[PATCH] block: Move elevator exit from blk_cleanup_queue() to blk_release_queue()

From: Jarkko Lavinen
Date: Tue Nov 03 2009 - 02:48:00 EST


If block_cleanup_queue() should not remove elevator if it is still
in use. Better call the elevator exit in blk_release_queue() when
all the reference to queue are gone. Since drivers could use queue
locks which are freed after returning from blk_cleanup_queue(),
switch the queue lock to internal one.

Signed-off-by: Jarkko Lavinen <jarkko.lavinen@xxxxxxxxx>
---
block/blk-core.c | 8 ++++++--
block/blk-sysfs.c | 3 +++
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 9daf621..8d7d5aa 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -449,6 +449,8 @@ void blk_put_queue(struct request_queue *q)

void blk_cleanup_queue(struct request_queue *q)
{
+ spinlock_t *oldlock;
+
/*
* We know we have process context here, so we can be a little
* cautious and ensure that pending block actions on this device
@@ -461,8 +463,10 @@ void blk_cleanup_queue(struct request_queue *q)
queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q);
mutex_unlock(&q->sysfs_lock);

- if (q->elevator)
- elevator_exit(q->elevator);
+ oldlock = q->queue_lock;
+ spin_lock_irq(oldlock);
+ q->queue_lock = &q->__queue_lock;
+ spin_unlock_irq(oldlock);

blk_put_queue(q);
}
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 21e275d..8ac3e5b 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -304,6 +304,9 @@ static void blk_release_queue(struct kobject *kobj)
container_of(kobj, struct request_queue, kobj);
struct request_list *rl = &q->rq;

+ if (q->elevator)
+ elevator_exit(q->elevator);
+
blk_sync_queue(q);

if (rl->rq_pool)
--
1.6.5


--azLHFNyN32YCQGCU
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0002-block-Move-elevator-exit-from-blk_cleanup_queue-to-b.patch"