rbd: protect against concurrent unmaps
Make sure two concurrent unmap operations on the same rbd device won't collide, by only proceeding with the removal and cleanup of a device if is not already underway. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
parent
751cc0e3cf
commit
82a442d239
1 changed files with 4 additions and 2 deletions
|
@ -5137,6 +5137,7 @@ static ssize_t rbd_remove(struct bus_type *bus,
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
int dev_id;
|
int dev_id;
|
||||||
unsigned long ul;
|
unsigned long ul;
|
||||||
|
bool already = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &ul);
|
ret = strict_strtoul(buf, 10, &ul);
|
||||||
|
@ -5164,11 +5165,12 @@ static ssize_t rbd_remove(struct bus_type *bus,
|
||||||
if (rbd_dev->open_count)
|
if (rbd_dev->open_count)
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
else
|
else
|
||||||
set_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags);
|
already = test_and_set_bit(RBD_DEV_FLAG_REMOVING,
|
||||||
|
&rbd_dev->flags);
|
||||||
spin_unlock_irq(&rbd_dev->lock);
|
spin_unlock_irq(&rbd_dev->lock);
|
||||||
}
|
}
|
||||||
spin_unlock(&rbd_dev_list_lock);
|
spin_unlock(&rbd_dev_list_lock);
|
||||||
if (ret < 0)
|
if (ret < 0 || already)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
rbd_bus_del_dev(rbd_dev);
|
rbd_bus_del_dev(rbd_dev);
|
||||||
|
|
Loading…
Add table
Reference in a new issue