memstick: fix hangs on unexpected device removal in mspro_blk
Maxim Levitsky [Wed, 11 Aug 2010 21:17:52 +0000 (14:17 -0700)]
mspro_block_remove() is called from detect thread that first calls the
mspro_block_stop(), which stops the request queue.  If we call
del_gendisk() with the queue stopped we get a deadlock.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Cc: Alex Dubov <oakad@yahoo.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

drivers/memstick/core/mspro_block.c

index aa5ac6e..d3f1a08 100644 (file)
@@ -1339,13 +1339,14 @@ static void mspro_block_remove(struct memstick_dev *card)
        struct mspro_block_data *msb = memstick_get_drvdata(card);
        unsigned long flags;
 
-       del_gendisk(msb->disk);
-       dev_dbg(&card->dev, "mspro block remove\n");
        spin_lock_irqsave(&msb->q_lock, flags);
        msb->eject = 1;
        blk_start_queue(msb->queue);
        spin_unlock_irqrestore(&msb->q_lock, flags);
 
+       del_gendisk(msb->disk);
+       dev_dbg(&card->dev, "mspro block remove\n");
+
        blk_cleanup_queue(msb->queue);
        msb->queue = NULL;