[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