mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
rbd: do not allow remove of mounted-on image
There is no check in rbd_remove() to see if anybody holds open the
image being removed. That's not cool.
Add a simple open count that goes up and down with opens and closes
(releases) of the device, and don't allow an rbd image to be removed
if the count is non-zero.
Protect the updates of the open count value with ctl_mutex to ensure
the underlying rbd device doesn't get removed while concurrently
being opened.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
(based on commit 42382b709b
)
This commit is contained in:
parent
1e411c6673
commit
3317122449
1 changed files with 13 additions and 0 deletions
|
@ -189,6 +189,7 @@ struct rbd_device {
|
|||
|
||||
/* sysfs related */
|
||||
struct device dev;
|
||||
unsigned long open_count;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */
|
||||
|
@ -249,8 +250,11 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
|
|||
if ((mode & FMODE_WRITE) && rbd_dev->read_only)
|
||||
return -EROFS;
|
||||
|
||||
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
|
||||
rbd_get_dev(rbd_dev);
|
||||
set_device_ro(bdev, rbd_dev->read_only);
|
||||
rbd_dev->open_count++;
|
||||
mutex_unlock(&ctl_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -259,7 +263,11 @@ static int rbd_release(struct gendisk *disk, fmode_t mode)
|
|||
{
|
||||
struct rbd_device *rbd_dev = disk->private_data;
|
||||
|
||||
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
|
||||
BUG_ON(!rbd_dev->open_count);
|
||||
rbd_dev->open_count--;
|
||||
rbd_put_dev(rbd_dev);
|
||||
mutex_unlock(&ctl_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2448,6 +2456,11 @@ static ssize_t rbd_remove(struct bus_type *bus,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (rbd_dev->open_count) {
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
__rbd_remove_all_snaps(rbd_dev);
|
||||
rbd_bus_del_dev(rbd_dev);
|
||||
|
||||
|
|
Loading…
Reference in a new issue