From 3a03a6a20cc2691a0485c1b710c889f09d28492b Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 9 Dec 2020 14:09:52 -0800 Subject: [PATCH] Add SUBTREE btree walk flag to restrict join/merge Add a BTW_SUBTREE flag to btree_walk() to restrict splitting or joining of the root block. When clients are merging into the root built from a reference to the last parent in the fs tree we want to be careful that we maintain a single root block that can be spliced back into the fs tree. We specifically check that the root block remain within the split/join thresholds. If it falls out of compliance we return an error so that it can be spliced back into the fs tree and then split/joined with its siblings. Signed-off-by: Zach Brown --- kmod/src/btree.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kmod/src/btree.c b/kmod/src/btree.c index 1b83c498..603f4110 100644 --- a/kmod/src/btree.c +++ b/kmod/src/btree.c @@ -86,6 +86,7 @@ enum btree_walk_flags { BTW_PAR_RNG = (1 << 6), /* return range through final parent */ BTW_GET_PAR = (1 << 7), /* get reference to final parent */ BTW_SET_PAR = (1 << 8), /* override reference to final parent */ + BTW_SUBTREE = (1 << 9), /* root is parent subtree, return -ERANGE if split/join */ }; /* total length of the value payload */ @@ -1209,6 +1210,17 @@ restart: break; } + /* + * join/split won't check subtree parent root, let + * caller know when it needs to be split/join. + */ + if ((flags & BTW_SUBTREE) && level == 1 && + (!total_above_join_low_water(bt) || + !mid_free_item_room(bt, sizeof(struct scoutfs_block_ref)))) { + ret = -ERANGE; + break; + } + /* * Splitting and joining can add or remove parents or * change the parent item we use to reach the child