diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2011-05-10 07:53:49 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-11 13:38:50 -0700 |
commit | 67de49c15480afd50b86f0cf18af82616974a5a9 (patch) | |
tree | 7346bc0b16bf74a68140b99228af2746f3dc6787 /drivers/staging/hv/blkvsc_drv.c | |
parent | 6b73e4c06d326571589eebcb78efde6182330042 (diff) | |
download | op-kernel-dev-67de49c15480afd50b86f0cf18af82616974a5a9.zip op-kernel-dev-67de49c15480afd50b86f0cf18af82616974a5a9.tar.gz |
Staging: hv: blkvsc_drv: Fix some locking issues
Additional lock related cleanup. Properly serialize access to
state even for command related operations.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Abhishek Kane <v-abkane@microsoft.com>
Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/blkvsc_drv.c')
-rw-r--r-- | drivers/staging/hv/blkvsc_drv.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 74d51bb..8a577bc 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -331,10 +331,14 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) (struct block_device_context *)blkvsc_req->dev; struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; + unsigned long flags; vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; + + spin_lock_irqsave(&blkdev->lock, flags); blkdev->num_outstanding_reqs--; + spin_unlock_irqrestore(&blkdev->lock, flags); if (vm_srb->scsi_status) if (scsi_normalize_sense(blkvsc_req->sense_buffer, @@ -354,6 +358,7 @@ static int blkvsc_do_operation(struct block_device_context *blkdev, unsigned char device_type; struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; + unsigned long flags; int ret = 0; @@ -407,7 +412,9 @@ static int blkvsc_do_operation(struct block_device_context *blkdev, goto cleanup; } + spin_lock_irqsave(&blkdev->lock, flags); blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); + spin_unlock_irqrestore(&blkdev->lock, flags); wait_for_completion_interruptible(&blkvsc_req->request.wait_event); @@ -555,6 +562,8 @@ static int blkvsc_remove(struct hv_device *dev) blk_stop_queue(blkdev->gd->queue); + blkvsc_cancel_pending_reqs(blkdev); + spin_unlock_irqrestore(&blkdev->lock, flags); while (blkdev->num_outstanding_reqs) { @@ -563,13 +572,8 @@ static int blkvsc_remove(struct hv_device *dev) udelay(100); } - blkvsc_do_operation(blkdev, DO_FLUSH); - - spin_lock_irqsave(&blkdev->lock, flags); - blkvsc_cancel_pending_reqs(blkdev); - - spin_unlock_irqrestore(&blkdev->lock, flags); + blkvsc_do_operation(blkdev, DO_FLUSH); blk_cleanup_queue(blkdev->gd->queue); @@ -597,6 +601,8 @@ static void blkvsc_shutdown(struct hv_device *dev) blk_stop_queue(blkdev->gd->queue); + blkvsc_cancel_pending_reqs(blkdev); + spin_unlock_irqrestore(&blkdev->lock, flags); while (blkdev->num_outstanding_reqs) { @@ -605,13 +611,9 @@ static void blkvsc_shutdown(struct hv_device *dev) udelay(100); } - blkvsc_do_operation(blkdev, DO_FLUSH); - spin_lock_irqsave(&blkdev->lock, flags); - - blkvsc_cancel_pending_reqs(blkdev); + blkvsc_do_operation(blkdev, DO_FLUSH); - spin_unlock_irqrestore(&blkdev->lock, flags); } static int blkvsc_release(struct gendisk *disk, fmode_t mode) @@ -619,16 +621,14 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) struct block_device_context *blkdev = disk->private_data; unsigned long flags; - spin_lock_irqsave(&blkdev->lock, flags); if (blkdev->users == 1) { - spin_unlock_irqrestore(&blkdev->lock, flags); blkvsc_do_operation(blkdev, DO_FLUSH); - spin_lock_irqsave(&blkdev->lock, flags); } + spin_lock_irqsave(&blkdev->lock, flags); blkdev->users--; - spin_unlock_irqrestore(&blkdev->lock, flags); + return 0; } @@ -943,7 +943,6 @@ static int blkvsc_probe(struct hv_device *dev) struct storvsc_major_info major_info; int ret = 0; - blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL); if (!blkdev) { ret = -ENOMEM; |