mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
rbd: add force close option
This adds a force close option, so we can force the unmapping of a rbd device that is open. If a path/device is blacklisted, apps like multipathd can map a new device and then unmap the old one. The unmapping cleanup would then be handled by the generic hotunplug code paths in multipahd like is done for iSCSI, FC/FCOE, SAS, etc. Signed-off-by: Mike Christie <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
This commit is contained in:
parent
0d6d1e9c2e
commit
0276dca6c1
2 changed files with 33 additions and 12 deletions
|
|
@ -6347,18 +6347,26 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
|
|||
struct rbd_device *rbd_dev = NULL;
|
||||
struct list_head *tmp;
|
||||
int dev_id;
|
||||
unsigned long ul;
|
||||
char opt_buf[6];
|
||||
bool already = false;
|
||||
bool force = false;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul(buf, 10, &ul);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* convert to int; abort if we lost anything in the conversion */
|
||||
dev_id = (int)ul;
|
||||
if (dev_id != ul)
|
||||
dev_id = -1;
|
||||
opt_buf[0] = '\0';
|
||||
sscanf(buf, "%d %5s", &dev_id, opt_buf);
|
||||
if (dev_id < 0) {
|
||||
pr_err("dev_id out of range\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (opt_buf[0] != '\0') {
|
||||
if (!strcmp(opt_buf, "force")) {
|
||||
force = true;
|
||||
} else {
|
||||
pr_err("bad remove option at '%s'\n", opt_buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = -ENOENT;
|
||||
spin_lock(&rbd_dev_list_lock);
|
||||
|
|
@ -6371,7 +6379,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
|
|||
}
|
||||
if (!ret) {
|
||||
spin_lock_irq(&rbd_dev->lock);
|
||||
if (rbd_dev->open_count)
|
||||
if (rbd_dev->open_count && !force)
|
||||
ret = -EBUSY;
|
||||
else
|
||||
already = test_and_set_bit(RBD_DEV_FLAG_REMOVING,
|
||||
|
|
@ -6382,6 +6390,15 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
|
|||
if (ret < 0 || already)
|
||||
return ret;
|
||||
|
||||
if (force) {
|
||||
/*
|
||||
* Prevent new IO from being queued and wait for existing
|
||||
* IO to complete/fail.
|
||||
*/
|
||||
blk_mq_freeze_queue(rbd_dev->disk->queue);
|
||||
blk_set_queue_dying(rbd_dev->disk->queue);
|
||||
}
|
||||
|
||||
down_write(&rbd_dev->lock_rwsem);
|
||||
if (__rbd_is_lock_owner(rbd_dev))
|
||||
rbd_unlock(rbd_dev);
|
||||
|
|
|
|||
Loading…
Reference in a new issue