aboutsummaryrefslogtreecommitdiff
path: root/block/snapshot.c
diff options
context:
space:
mode:
authorMax Reitz <mreitz@redhat.com>2017-11-10 18:25:45 +0100
committerMax Reitz <mreitz@redhat.com>2017-11-17 18:21:31 +0100
commit5e003f17ec518cd96f5d2ac23ce9e14144426235 (patch)
treeffef6898ffde97ee3d7ab4fe80577b730ded0626 /block/snapshot.c
parent08546bcfb260c28141e27cf3367c443528602fc0 (diff)
block: Make bdrv_next() keep strong references
On one hand, it is a good idea for bdrv_next() to return a strong reference because ideally nearly every pointer should be refcounted. This fixes intermittent failure of iotest 194. On the other, it is absolutely necessary for bdrv_next() itself to keep a strong reference to both the BB (in its first phase) and the BDS (at least in the second phase) because when called the next time, it will dereference those objects to get a link to the next one. Therefore, it needs these objects to stay around until then. Just storing the pointer to the next in the iterator is not really viable because that pointer might become invalid as well. Both arguments taken together means we should probably just invoke bdrv_ref() and blk_ref() in bdrv_next(). This means we have to assert that bdrv_next() is always called from the main loop, but that was probably necessary already before this patch and judging from the callers, it also looks to actually be the case. Keeping these strong references means however that callers need to give them up if they decide to abort the iteration early. They can do so through the new bdrv_next_cleanup() function. Suggested-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com> Message-id: 20171110172545.32609-1-mreitz@redhat.com Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/snapshot.c')
-rw-r--r--block/snapshot.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/block/snapshot.c b/block/snapshot.c
index 1d5ab5f90f..be0743abac 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -417,6 +417,7 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
}
aio_context_release(ctx);
if (!ok) {
+ bdrv_next_cleanup(&it);
goto fail;
}
}
@@ -444,6 +445,7 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
}
aio_context_release(ctx);
if (ret < 0) {
+ bdrv_next_cleanup(&it);
goto fail;
}
}
@@ -469,6 +471,7 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
}
aio_context_release(ctx);
if (err < 0) {
+ bdrv_next_cleanup(&it);
goto fail;
}
}
@@ -494,6 +497,7 @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
}
aio_context_release(ctx);
if (err < 0) {
+ bdrv_next_cleanup(&it);
goto fail;
}
}
@@ -525,6 +529,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
}
aio_context_release(ctx);
if (err < 0) {
+ bdrv_next_cleanup(&it);
goto fail;
}
}
@@ -548,6 +553,7 @@ BlockDriverState *bdrv_all_find_vmstate_bs(void)
aio_context_release(ctx);
if (found) {
+ bdrv_next_cleanup(&it);
break;
}
}