Before merge, we move top-delta to a temporary plo->trans_map list. Since then, it's not present in the main plo->map list anymore. If merge failed, we must put it back to plo->map. Otherwise the delta will be lost forever (visible in /sys/block/ploop*/pdelta/*, but not accessible from ploop).
https://jira.sw.ru/browse/PSBM-25252 Signed-off-by: Maxim Patlasov <mpatla...@parallels.com> Acked-by: Pavel Emelyanov <xe...@parallels.com> --- drivers/block/ploop/dev.c | 49 +++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index d2a9eb4..2e6302f 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -3280,6 +3280,26 @@ static void ploop_update_fmt_version(struct ploop_device * plo) } } +static void ploop_merge_cleanup(struct ploop_device * plo, + struct ploop_map * map, + struct ploop_delta * delta, int err) +{ + ploop_quiesce(plo); + mutex_lock(&plo->sysfs_mutex); + list_del(&delta->list); + + if (err) + list_add(&delta->list, &plo->map.delta_list); + else + ploop_update_fmt_version(plo); + + plo->trans_map = NULL; + plo->maintenance_type = PLOOP_MNTN_OFF; + mutex_unlock(&plo->sysfs_mutex); + ploop_map_destroy(map); + ploop_relax(plo); +} + static int ploop_merge(struct ploop_device * plo) { int err; @@ -3368,32 +3388,19 @@ already: if (test_bit(PLOOP_S_ABORT, &plo->state)) { printk(KERN_WARNING "merge for ploop%d failed (state ABORT)\n", plo->index); - plo->trans_map = NULL; - plo->maintenance_type = PLOOP_MNTN_OFF; err = -EIO; - goto out; } - ploop_quiesce(plo); - mutex_lock(&plo->sysfs_mutex); - plo->trans_map = NULL; - plo->maintenance_type = PLOOP_MNTN_OFF; - list_del(&delta->list); - ploop_update_fmt_version(plo); - mutex_unlock(&plo->sysfs_mutex); - ploop_map_destroy(map); - ploop_relax(plo); + ploop_merge_cleanup(plo, map, delta, err); - kfree(map); - - kobject_del(&delta->kobj); - kobject_put(&plo->kobj); - - delta->ops->stop(delta); - delta->ops->destroy(delta); - kobject_put(&delta->kobj); - return 0; + if (!err) { + kobject_del(&delta->kobj); + kobject_put(&plo->kobj); + delta->ops->stop(delta); + delta->ops->destroy(delta); + kobject_put(&delta->kobj); + } out: kfree(map); return err; -- 1.9.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel