From 3a4505897ccaf387f4befa8c0d308d994bcdbc37 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 6 Jun 2011 15:49:43 -0700 Subject: [PATCH] Staging: hv: blkvsc: Fix bugs in the module unload path Fix bugs in the module unload path for the blkvsc driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 40 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index bcf562f5ffd3..a44fc7684727 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -518,22 +518,18 @@ static int blkvsc_remove(struct hv_device *dev) blkvsc_do_operation(blkdev, DO_FLUSH); - blk_cleanup_queue(blkdev->gd->queue); + if (blkdev->users == 0) { + del_gendisk(blkdev->gd); + put_disk(blkdev->gd); + blk_cleanup_queue(blkdev->gd->queue); - /* - * Call to the vsc driver to let it know that the device is being - * removed - */ - storvsc_dev_remove(dev); - - del_gendisk(blkdev->gd); + storvsc_dev_remove(blkdev->device_ctx); - kmem_cache_destroy(blkdev->request_pool); - - kfree(blkdev); + kmem_cache_destroy(blkdev->request_pool); + kfree(blkdev); + } return 0; - } static void blkvsc_shutdown(struct hv_device *dev) @@ -568,13 +564,23 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) struct block_device_context *blkdev = disk->private_data; unsigned long flags; - if (blkdev->users == 1) { + spin_lock_irqsave(&blkdev->lock, flags); + + if ((--blkdev->users == 0) && (blkdev->shutting_down)) { + blk_stop_queue(blkdev->gd->queue); + spin_unlock_irqrestore(&blkdev->lock, flags); + blkvsc_do_operation(blkdev, DO_FLUSH); - } + del_gendisk(blkdev->gd); + put_disk(blkdev->gd); + blk_cleanup_queue(blkdev->gd->queue); - spin_lock_irqsave(&blkdev->lock, flags); - blkdev->users--; - spin_unlock_irqrestore(&blkdev->lock, flags); + storvsc_dev_remove(blkdev->device_ctx); + + kmem_cache_destroy(blkdev->request_pool); + kfree(blkdev); + } else + spin_unlock_irqrestore(&blkdev->lock, flags); return 0; } -- 2.20.1