An open request for a mapped rbd image can arrive while removal of that mapping is underway. The control mutex and an open count is protect a mapped device that's in use from being removed. But it is possible for the removal of the mapping to reach the point of no return *after* a racing open has concluded it is OK to proceed. The result of this is not good. Define and use a flag to indicate a mapping is getting removed to avoid this problem. This addresses http://tracker.newdream.net/issues/3427 Signed-off-by: Alex Elder <elder@xxxxxxxxxxx> --- drivers/block/rbd.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 9eb1631..760f7f7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -264,6 +264,7 @@ struct rbd_device { enum rbd_dev_flags { rbd_dev_flag_exists, /* mapped snapshot has not been deleted */ + rbd_dev_flag_removing, /* this mapping is being removed */ }; static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ @@ -351,17 +352,22 @@ static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev, u64 *hver); static int rbd_open(struct block_device *bdev, fmode_t mode) { struct rbd_device *rbd_dev = bdev->bd_disk->private_data; + int ret = 0; if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only) return -EROFS; mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); - (void) get_device(&rbd_dev->dev); - set_device_ro(bdev, rbd_dev->mapping.read_only); - rbd_dev->open_count++; + if (!test_bit(rbd_dev_flag_removing, &rbd_dev->flags)) { + (void) get_device(&rbd_dev->dev); + set_device_ro(bdev, rbd_dev->mapping.read_only); + rbd_dev->open_count++; + } else { + ret = -ENOENT; + } mutex_unlock(&ctl_mutex); - return 0; + return ret; } static int rbd_release(struct gendisk *disk, fmode_t mode) @@ -3796,6 +3802,7 @@ static ssize_t rbd_remove(struct bus_type *bus, ret = -EBUSY; goto done; } + set_bit(rbd_dev_flag_removing, &rbd_dev->flags); rbd_remove_all_snaps(rbd_dev); rbd_bus_del_dev(rbd_dev); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html