[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 10/21] quorum: Implement .bdrv_recurse_can_replace()
From: |
Max Reitz |
Subject: |
[PATCH v3 10/21] quorum: Implement .bdrv_recurse_can_replace() |
Date: |
Thu, 30 Jan 2020 22:44:20 +0100 |
Signed-off-by: Max Reitz <address@hidden>
---
block/quorum.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/block/quorum.c b/block/quorum.c
index 6a7224c9e4..22c1060b42 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -825,6 +825,62 @@ static bool
quorum_recurse_is_first_non_filter(BlockDriverState *bs,
return false;
}
+static bool quorum_recurse_can_replace(BlockDriverState *bs,
+ BlockDriverState *to_replace)
+{
+ BDRVQuorumState *s = bs->opaque;
+ int i;
+
+ for (i = 0; i < s->num_children; i++) {
+ /*
+ * We have no idea whether our children show the same data as
+ * this node (@bs). It is actually highly likely that
+ * @to_replace does not, because replacing a broken child is
+ * one of the main use cases here.
+ *
+ * We do know that the new BDS will match @bs, so replacing
+ * any of our children by it will be safe. It cannot change
+ * the data this quorum node presents to its parents.
+ *
+ * However, replacing @to_replace by @bs in any of our
+ * children's chains may change visible data somewhere in
+ * there. We therefore cannot recurse down those chains with
+ * bdrv_recurse_can_replace().
+ * (More formally, bdrv_recurse_can_replace() requires that
+ * @to_replace will be replaced by something matching the @bs
+ * passed to it. We cannot guarantee that.)
+ *
+ * Thus, we can only check whether any of our immediate
+ * children matches @to_replace.
+ *
+ * (In the future, we might add a function to recurse down a
+ * chain that checks that nothing there cares about a change
+ * in data from the respective child in question. For
+ * example, most filters do not care when their child's data
+ * suddenly changes, as long as their parents do not care.)
+ */
+ if (s->children[i].child->bs == to_replace) {
+ int ret;
+
+ /*
+ * We now have to ensure that there is no other parent
+ * that cares about replacing this child by a node with
+ * potentially different data.
+ */
+ s->children[i].to_be_replaced = true;
+ ret = bdrv_child_refresh_perms(bs, s->children[i].child, NULL);
+
+ /* Revert permissions */
+ s->children[i].to_be_replaced = false;
+ bdrv_child_refresh_perms(bs, s->children[i].child, &error_abort);
+
+ return ret == 0;
+ }
+ }
+
+ return false;
+}
+
static int quorum_valid_threshold(int threshold, int num_children, Error
**errp)
{
@@ -1197,6 +1253,7 @@ static BlockDriver bdrv_quorum = {
.is_filter = true,
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
+ .bdrv_recurse_can_replace = quorum_recurse_can_replace,
.strong_runtime_opts = quorum_strong_runtime_opts,
};
--
2.24.1
- [PATCH v3 00/21] block: Fix check_to_replace_node(), Max Reitz, 2020/01/30
- [PATCH v3 01/21] blockdev: Allow external snapshots everywhere, Max Reitz, 2020/01/30
- [PATCH v3 02/21] blockdev: Allow resizing everywhere, Max Reitz, 2020/01/30
- [PATCH v3 04/21] iotests: Let 041 use -blockdev for quorum children, Max Reitz, 2020/01/30
- [PATCH v3 03/21] block: Drop bdrv_is_first_non_filter(), Max Reitz, 2020/01/30
- [PATCH v3 05/21] quorum: Fix child permissions, Max Reitz, 2020/01/30
- [PATCH v3 06/21] block: Add bdrv_recurse_can_replace(), Max Reitz, 2020/01/30
- [PATCH v3 07/21] blkverify: Implement .bdrv_recurse_can_replace(), Max Reitz, 2020/01/30
- [PATCH v3 09/21] quorum: Add QuorumChild.to_be_replaced, Max Reitz, 2020/01/30
- [PATCH v3 08/21] quorum: Store children in own structure, Max Reitz, 2020/01/30
- [PATCH v3 10/21] quorum: Implement .bdrv_recurse_can_replace(),
Max Reitz <=
- [PATCH v3 11/21] block: Use bdrv_recurse_can_replace(), Max Reitz, 2020/01/30
- [PATCH v3 12/21] block: Remove bdrv_recurse_is_first_non_filter(), Max Reitz, 2020/01/30
- [PATCH v3 13/21] mirror: Double-check immediately before replacing, Max Reitz, 2020/01/30
- [PATCH v3 14/21] quorum: Stop marking it as a filter, Max Reitz, 2020/01/30
- [PATCH v3 16/21] iotests: Add VM.assert_block_path(), Max Reitz, 2020/01/30
- [PATCH v3 18/21] iotests: Resolve TODOs in 041, Max Reitz, 2020/01/30
- [PATCH v3 15/21] iotests: Use complete_and_wait() in 155, Max Reitz, 2020/01/30
- [PATCH v3 17/21] iotests/041: Drop superfluous shutdowns, Max Reitz, 2020/01/30
- [PATCH v3 19/21] iotests: Use self.image_len in TestRepairQuorum, Max Reitz, 2020/01/30
- [PATCH v3 20/21] iotests: Add tests for invalid Quorum @replaces, Max Reitz, 2020/01/30