diff options
| -rw-r--r-- | drivers/block/rbd.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 842caf4aab47..c7bf9613ad40 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -235,6 +235,7 @@ struct rbd_device { | |||
| 235 | 235 | ||
| 236 | /* sysfs related */ | 236 | /* sysfs related */ |
| 237 | struct device dev; | 237 | struct device dev; |
| 238 | unsigned long open_count; | ||
| 238 | }; | 239 | }; |
| 239 | 240 | ||
| 240 | static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ | 241 | static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ |
| @@ -309,8 +310,11 @@ static int rbd_open(struct block_device *bdev, fmode_t mode) | |||
| 309 | if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only) | 310 | if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only) |
| 310 | return -EROFS; | 311 | return -EROFS; |
| 311 | 312 | ||
| 313 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
| 312 | rbd_get_dev(rbd_dev); | 314 | rbd_get_dev(rbd_dev); |
| 313 | set_device_ro(bdev, rbd_dev->mapping.read_only); | 315 | set_device_ro(bdev, rbd_dev->mapping.read_only); |
| 316 | rbd_dev->open_count++; | ||
| 317 | mutex_unlock(&ctl_mutex); | ||
| 314 | 318 | ||
| 315 | return 0; | 319 | return 0; |
| 316 | } | 320 | } |
| @@ -319,7 +323,11 @@ static int rbd_release(struct gendisk *disk, fmode_t mode) | |||
| 319 | { | 323 | { |
| 320 | struct rbd_device *rbd_dev = disk->private_data; | 324 | struct rbd_device *rbd_dev = disk->private_data; |
| 321 | 325 | ||
| 326 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
| 327 | rbd_assert(rbd_dev->open_count > 0); | ||
| 328 | rbd_dev->open_count--; | ||
| 322 | rbd_put_dev(rbd_dev); | 329 | rbd_put_dev(rbd_dev); |
| 330 | mutex_unlock(&ctl_mutex); | ||
| 323 | 331 | ||
| 324 | return 0; | 332 | return 0; |
| 325 | } | 333 | } |
| @@ -3745,6 +3753,11 @@ static ssize_t rbd_remove(struct bus_type *bus, | |||
| 3745 | goto done; | 3753 | goto done; |
| 3746 | } | 3754 | } |
| 3747 | 3755 | ||
| 3756 | if (rbd_dev->open_count) { | ||
| 3757 | ret = -EBUSY; | ||
| 3758 | goto done; | ||
| 3759 | } | ||
| 3760 | |||
| 3748 | rbd_remove_all_snaps(rbd_dev); | 3761 | rbd_remove_all_snaps(rbd_dev); |
| 3749 | rbd_bus_del_dev(rbd_dev); | 3762 | rbd_bus_del_dev(rbd_dev); |
| 3750 | 3763 | ||
