Commit 67de49c1 authored by K. Y. Srinivasan's avatar K. Y. Srinivasan Committed by Greg Kroah-Hartman

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: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: default avatarAbhishek Kane <v-abkane@microsoft.com>
Signed-off-by: default avatarHank Janssen <hjanssen@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 6b73e4c0
...@@ -331,10 +331,14 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) ...@@ -331,10 +331,14 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
(struct block_device_context *)blkvsc_req->dev; (struct block_device_context *)blkvsc_req->dev;
struct scsi_sense_hdr sense_hdr; struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb; struct vmscsi_request *vm_srb;
unsigned long flags;
vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
spin_lock_irqsave(&blkdev->lock, flags);
blkdev->num_outstanding_reqs--; blkdev->num_outstanding_reqs--;
spin_unlock_irqrestore(&blkdev->lock, flags);
if (vm_srb->scsi_status) if (vm_srb->scsi_status)
if (scsi_normalize_sense(blkvsc_req->sense_buffer, if (scsi_normalize_sense(blkvsc_req->sense_buffer,
...@@ -354,6 +358,7 @@ static int blkvsc_do_operation(struct block_device_context *blkdev, ...@@ -354,6 +358,7 @@ static int blkvsc_do_operation(struct block_device_context *blkdev,
unsigned char device_type; unsigned char device_type;
struct scsi_sense_hdr sense_hdr; struct scsi_sense_hdr sense_hdr;
struct vmscsi_request *vm_srb; struct vmscsi_request *vm_srb;
unsigned long flags;
int ret = 0; int ret = 0;
...@@ -407,7 +412,9 @@ static int blkvsc_do_operation(struct block_device_context *blkdev, ...@@ -407,7 +412,9 @@ static int blkvsc_do_operation(struct block_device_context *blkdev,
goto cleanup; goto cleanup;
} }
spin_lock_irqsave(&blkdev->lock, flags);
blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
spin_unlock_irqrestore(&blkdev->lock, flags);
wait_for_completion_interruptible(&blkvsc_req->request.wait_event); wait_for_completion_interruptible(&blkvsc_req->request.wait_event);
...@@ -555,6 +562,8 @@ static int blkvsc_remove(struct hv_device *dev) ...@@ -555,6 +562,8 @@ static int blkvsc_remove(struct hv_device *dev)
blk_stop_queue(blkdev->gd->queue); blk_stop_queue(blkdev->gd->queue);
blkvsc_cancel_pending_reqs(blkdev);
spin_unlock_irqrestore(&blkdev->lock, flags); spin_unlock_irqrestore(&blkdev->lock, flags);
while (blkdev->num_outstanding_reqs) { while (blkdev->num_outstanding_reqs) {
...@@ -563,13 +572,8 @@ static int blkvsc_remove(struct hv_device *dev) ...@@ -563,13 +572,8 @@ static int blkvsc_remove(struct hv_device *dev)
udelay(100); 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);
blk_cleanup_queue(blkdev->gd->queue); blk_cleanup_queue(blkdev->gd->queue);
...@@ -597,6 +601,8 @@ static void blkvsc_shutdown(struct hv_device *dev) ...@@ -597,6 +601,8 @@ static void blkvsc_shutdown(struct hv_device *dev)
blk_stop_queue(blkdev->gd->queue); blk_stop_queue(blkdev->gd->queue);
blkvsc_cancel_pending_reqs(blkdev);
spin_unlock_irqrestore(&blkdev->lock, flags); spin_unlock_irqrestore(&blkdev->lock, flags);
while (blkdev->num_outstanding_reqs) { while (blkdev->num_outstanding_reqs) {
...@@ -605,13 +611,9 @@ static void blkvsc_shutdown(struct hv_device *dev) ...@@ -605,13 +611,9 @@ static void blkvsc_shutdown(struct hv_device *dev)
udelay(100); udelay(100);
} }
blkvsc_do_operation(blkdev, DO_FLUSH);
spin_lock_irqsave(&blkdev->lock, flags); blkvsc_do_operation(blkdev, DO_FLUSH);
blkvsc_cancel_pending_reqs(blkdev);
spin_unlock_irqrestore(&blkdev->lock, flags);
} }
static int blkvsc_release(struct gendisk *disk, fmode_t mode) static int blkvsc_release(struct gendisk *disk, fmode_t mode)
...@@ -619,16 +621,14 @@ 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; struct block_device_context *blkdev = disk->private_data;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&blkdev->lock, flags);
if (blkdev->users == 1) { if (blkdev->users == 1) {
spin_unlock_irqrestore(&blkdev->lock, flags);
blkvsc_do_operation(blkdev, DO_FLUSH); blkvsc_do_operation(blkdev, DO_FLUSH);
spin_lock_irqsave(&blkdev->lock, flags);
} }
spin_lock_irqsave(&blkdev->lock, flags);
blkdev->users--; blkdev->users--;
spin_unlock_irqrestore(&blkdev->lock, flags); spin_unlock_irqrestore(&blkdev->lock, flags);
return 0; return 0;
} }
...@@ -943,7 +943,6 @@ static int blkvsc_probe(struct hv_device *dev) ...@@ -943,7 +943,6 @@ static int blkvsc_probe(struct hv_device *dev)
struct storvsc_major_info major_info; struct storvsc_major_info major_info;
int ret = 0; int ret = 0;
blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL); blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
if (!blkdev) { if (!blkdev) {
ret = -ENOMEM; ret = -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment