From ddd5afebfb853a7a0a13c0c518c08da3aa47a167 Mon Sep 17 00:00:00 2001 From: Daniel Stodden Date: Fri, 30 Apr 2010 22:01:22 +0000 Subject: [PATCH] --- yaml --- r: 208287 b: refs/heads/master c: fa1bd3591a669b92b635dbdb11d1a32a5630821b h: refs/heads/master i: 208285: c2317977d0b8d78dbb5caed27b1c8d1049f3ea21 208283: ee70c9b7b83d09b9ded5edba8e06c69d9b27a485 208279: bd2a223a64a3bdcadcd3400c8cdf628a2cde2f1c 208271: 67be29011d7db2985d1c1f57474932d20705dab7 208255: 5a6b796dd32a947fbe521c109bb62ae7620884ba v: v3 --- [refs] | 2 +- trunk/drivers/block/xen-blkfront.c | 41 +++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index c49e7938e353..922dc5ab982b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7fd152f4b6ae4f3cf89e4b7a0383cc3c470772fc +refs/heads/master: fa1bd3591a669b92b635dbdb11d1a32a5630821b diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 49862993f31e..715de7d8ce01 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -1093,18 +1093,47 @@ static void blkback_changed(struct xenbus_device *dev, } } -static int blkfront_remove(struct xenbus_device *dev) +static int blkfront_remove(struct xenbus_device *xbdev) { - struct blkfront_info *info = dev_get_drvdata(&dev->dev); + struct blkfront_info *info = dev_get_drvdata(&xbdev->dev); + struct block_device *bdev = NULL; + struct gendisk *disk; - dev_dbg(&dev->dev, "blkfront_remove: %s removed\n", dev->nodename); + dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); blkif_free(info, 0); - if(info->users == 0) + mutex_lock(&info->mutex); + + disk = info->gd; + if (disk) + bdev = bdget_disk(disk, 0); + + info->xbdev = NULL; + mutex_unlock(&info->mutex); + + if (!bdev) { + kfree(info); + return 0; + } + + /* + * The xbdev was removed before we reached the Closed + * state. See if it's safe to remove the disk. If the bdev + * isn't closed yet, we let release take care of it. + */ + + mutex_lock(&bdev->bd_mutex); + info = disk->private_data; + + if (info && !info->users) { + xlvbd_release_gendisk(info); + disk->private_data = NULL; kfree(info); - else - info->xbdev = NULL; + } + + mutex_unlock(&bdev->bd_mutex); + bdput(bdev); return 0; }