Skip to content

Commit

Permalink
Staging: hv: blkvsc_drv: Fix some locking issues
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
K. Y. Srinivasan authored and Greg Kroah-Hartman committed May 11, 2011
1 parent 6b73e4c commit 67de49c
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions drivers/staging/hv/blkvsc_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand All @@ -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);

Expand Down Expand Up @@ -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) {
Expand All @@ -605,30 +611,24 @@ 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)
{
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;
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 67de49c

Please sign in to comment.