The only allowed use-case for delta removal on running ploop is the merge operation. But merge never removes base delta. Hence, we can prohibit base delta removal if ploop is in RUNNING state. This resolves the following issue: buggy userspace removes all deltas from a running ploop, but leaves ploop in RUNNING state making any further ploop-mount impossible.
https://jira.sw.ru/browse/PSBM-25102 Signed-off-by: Maxim Patlasov <mpatla...@parallels.com> Acked-by: Pavel Emelyanov <xe...@parallels.com> --- drivers/block/ploop/dev.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 33f8442..d2a9eb4 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3173,6 +3173,12 @@ static int ploop_del_delta(struct ploop_device * plo, unsigned long arg) if (plo->maintenance_type != PLOOP_MNTN_OFF) return -EBUSY; + if (level == 0 && test_bit(PLOOP_S_RUNNING, &plo->state)) { + printk(KERN_INFO "Can't del base delta on running ploop%d\n", + plo->index); + return -EBUSY; + } + delta = find_delta(plo, level); if (delta == NULL) @@ -3197,6 +3203,8 @@ static int ploop_del_delta(struct ploop_device * plo, unsigned long arg) delta->ops->stop(delta); delta->ops->destroy(delta); kobject_put(&delta->kobj); + BUG_ON(test_bit(PLOOP_S_RUNNING, &plo->state) && + list_empty(&plo->map.delta_list)); return 0; } @@ -3573,6 +3581,7 @@ static int ploop_start(struct ploop_device * plo, struct block_device *bdev) wake_up_process(plo->thread); set_bit(PLOOP_S_RUNNING, &plo->state); + BUG_ON(list_empty(&plo->map.delta_list)); return 0; out_err: @@ -3605,8 +3614,11 @@ static int ploop_stop(struct ploop_device * plo, struct block_device *bdev) if (!test_bit(PLOOP_S_RUNNING, &plo->state)) return -EINVAL; - if (list_empty(&plo->map.delta_list)) + if (list_empty(&plo->map.delta_list)) { + printk(KERN_INFO "stop ploop%d failed (no deltas)\n", + plo->index); return -ENOENT; + } cnt = atomic_read(&plo->open_count); if (cnt > 1) { @@ -3755,6 +3767,7 @@ static int ploop_clear(struct ploop_device * plo, struct block_device * bdev) plo->maintenance_type = PLOOP_MNTN_OFF; plo->bd_size = 0; plo->state = (1 << PLOOP_S_CHANGED); + BUG_ON(test_bit(PLOOP_S_RUNNING, &plo->state)); return 0; } -- 1.9.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel