diff options
author | Daniel Stodden <daniel.stodden@citrix.com> | 2010-08-07 12:36:53 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 12:38:43 -0400 |
commit | 139617437aff1f0d3b57c2d7cc60e60efc8fe6c3 (patch) | |
tree | 2c903b3f6456ab4a7d70c16c864ceb63bc366a5e /drivers/block/xen-blkfront.c | |
parent | b70f5fa043b318659c936d8c3c696250e6528944 (diff) |
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 <daniel.stodden@citrix.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r-- | drivers/block/xen-blkfront.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 1e406f0331e7..763a315712cc 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) | |||
1118 | 1118 | ||
1119 | static int blkif_open(struct block_device *bdev, fmode_t mode) | 1119 | static int blkif_open(struct block_device *bdev, fmode_t mode) |
1120 | { | 1120 | { |
1121 | struct blkfront_info *info = bdev->bd_disk->private_data; | 1121 | struct gendisk *disk = bdev->bd_disk; |
1122 | 1122 | struct blkfront_info *info; | |
1123 | if (!info->xbdev) | 1123 | int err = 0; |
1124 | return -ENODEV; | ||
1125 | 1124 | ||
1126 | lock_kernel(); | 1125 | lock_kernel(); |
1127 | info->users++; | ||
1128 | unlock_kernel(); | ||
1129 | 1126 | ||
1130 | return 0; | 1127 | info = disk->private_data; |
1128 | if (!info) { | ||
1129 | /* xbdev gone */ | ||
1130 | err = -ERESTARTSYS; | ||
1131 | goto out; | ||
1132 | } | ||
1133 | |||
1134 | mutex_lock(&info->mutex); | ||
1135 | |||
1136 | if (!info->gd) | ||
1137 | /* xbdev is closed */ | ||
1138 | err = -ERESTARTSYS; | ||
1139 | |||
1140 | mutex_unlock(&info->mutex); | ||
1141 | |||
1142 | if (!err) | ||
1143 | ++info->users; | ||
1144 | |||
1145 | unlock_kernel(); | ||
1146 | out: | ||
1147 | return err; | ||
1131 | } | 1148 | } |
1132 | 1149 | ||
1133 | static int blkif_release(struct gendisk *disk, fmode_t mode) | 1150 | static int blkif_release(struct gendisk *disk, fmode_t mode) |