[Devel] [PATCH rh7 22/38] ploop: put top-delta back if merge failed
Andrey Smetanin
asmetanin at virtuozzo.com
Fri May 15 09:48:23 PDT 2015
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 <MPatlasov at parallels.com>
Acked-by: Pavel Emelyanov <xemul at 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
More information about the Devel
mailing list