From: Daniel Stodden Date: Sat, 7 Aug 2010 16:36:53 +0000 (+0200) Subject: blkfront: Fix blkfront backend switch race (bdev open) X-Git-Tag: v2.6.36-rc1~288^2~70 X-Git-Url: https://bbs.cooldavid.org/git/?a=commitdiff_plain;h=139617437aff1f0d3b57c2d7cc60e60efc8fe6c3;p=net-next-2.6.git blkfront: Fix blkfront backend switch race (bdev open) We need not mind if users grab a late handle on a closing disk. We probably even should not. But we have to make sure it's not a dead one already Let the bdev deal with a gendisk deleted under its feet. Takes the info mutex to decide a race against backend closing. Signed-off-by: Daniel Stodden Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Jens Axboe --- diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 1e406f0331e..763a315712c 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1118,16 +1118,33 @@ static int blkfront_is_ready(struct xenbus_device *dev) static int blkif_open(struct block_device *bdev, fmode_t mode) { - struct blkfront_info *info = bdev->bd_disk->private_data; - - if (!info->xbdev) - return -ENODEV; + struct gendisk *disk = bdev->bd_disk; + struct blkfront_info *info; + int err = 0; lock_kernel(); - info->users++; - unlock_kernel(); - return 0; + info = disk->private_data; + if (!info) { + /* xbdev gone */ + err = -ERESTARTSYS; + goto out; + } + + mutex_lock(&info->mutex); + + if (!info->gd) + /* xbdev is closed */ + err = -ERESTARTSYS; + + mutex_unlock(&info->mutex); + + if (!err) + ++info->users; + + unlock_kernel(); +out: + return err; } static int blkif_release(struct gendisk *disk, fmode_t mode)