diff mbox series

[19/21] block: add bdrv_remove_backing transaction action

Message ID 20201123201233.9534-22-vsementsov@virtuozzo.com
State New
Headers show
Series block: update graph permissions update | expand

Commit Message

Vladimir Sementsov-Ogievskiy Nov. 23, 2020, 8:12 p.m. UTC
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 block.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/block.c b/block.c
index cf7b859a81..6ea926e2c1 100644
--- a/block.c
+++ b/block.c
@@ -2974,12 +2974,19 @@  BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
     return child;
 }
 
+static void bdrv_child_free(void *opaque)
+{
+    BdrvChild *c = opaque;
+
+    g_free(c->name);
+    g_free(c);
+}
+
 static void bdrv_remove_empty_child(BdrvChild *child)
 {
     assert(!child->bs);
     QLIST_SAFE_REMOVE(child, next);
-    g_free(child->name);
-    g_free(child);
+    bdrv_child_free(child);
 }
 
 typedef struct BdrvAttachChildNopermState {
@@ -4852,6 +4859,37 @@  static bool should_update_child(BdrvChild *c, BlockDriverState *to)
     return ret;
 }
 
+/* this doesn't restore original child bs, only the child itself */
+static void bdrv_remove_backing_abort(void *opaque)
+{
+    BdrvChild *c = opaque;
+    BlockDriverState *parent_bs = c->opaque;
+
+    QLIST_INSERT_HEAD(&parent_bs->children, c, next);
+    parent_bs->backing = c;
+}
+
+static BdrvActionDrv bdrv_remove_backing_drv = {
+    .abort = bdrv_remove_backing_abort,
+    .commit = bdrv_child_free,
+};
+
+__attribute__((unused))
+static void bdrv_remove_backing(BlockDriverState *bs, GSList **tran)
+{
+    if (!bs->backing) {
+        return;
+    }
+
+    if (bs->backing->bs) {
+        bdrv_replace_child_safe(bs->backing, NULL, tran);
+    }
+
+    tran_prepend(tran, &bdrv_remove_backing_drv, bs->backing);
+    QLIST_SAFE_REMOVE(bs->backing, next);
+    bs->backing = NULL;
+}
+
 static int bdrv_replace_node_noperm(BlockDriverState *from,
                                     BlockDriverState *to,
                                     bool auto_skip, GSList **tran, Error **errp)