lkml.org 
[lkml]   [2010]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 14/16] blkfront: Lock blockfront_info during xbdev removal
    Date
    From: Daniel Stodden <daniel.stodden@citrix.com>

    Same approach as blkfront_closing:
    * Grab the bdev safely, holding the info mutex.
    * Zap xbdev safely, holding the info mutex.
    * Try bdev removal safely, holding bd_mutex.

    Signed-off-by: Daniel Stodden <daniel.stodden@citrix.com>
    Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
    ---
    drivers/block/xen-blkfront.c | 41 +++++++++++++++++++++++++++++++++++------
    1 files changed, 35 insertions(+), 6 deletions(-)

    diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
    index 214c92e..96ff225 100644
    --- a/drivers/block/xen-blkfront.c
    +++ b/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;
    }
    --
    1.7.1.1


    \
     
     \ /
      Last update: 2010-07-20 22:45    [W:2.664 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site