From d8478ed6f131b6cfa93a22aa3bb3ace3f1dd3ae7 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 18 Dec 2020 09:24:27 -0800 Subject: [PATCH] Add scoutfs_btree_rebalance() Add a btree call to just dirty to a leaf block, joining and splitting along the way so that the blocks in the path satisfy the balance constraints. Signed-off-by: Zach Brown --- kmod/src/btree.c | 24 ++++++++++++++++++++++++ kmod/src/btree.h | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/kmod/src/btree.c b/kmod/src/btree.c index 03ad5b96..f2e16924 100644 --- a/kmod/src/btree.c +++ b/kmod/src/btree.c @@ -1868,6 +1868,30 @@ int scoutfs_btree_set_parent(struct super_block *sb, key, 0, NULL, NULL, par_root); } +/* + * Descend to the leaf, making sure that all the blocks conform to the + * balance constraints. Blocks below the low threshold will be joined. + * This is called to split blocks that were too large for insertions, + * but those insertions were in a distant context and we don't bother + * communicating the val_len back here. We just try to insert a max + * value. + * + * This always dirties all the way to the leaf. It could be made more + * efficient with more btree walk flags to walk and check for blocks + * that need balancing, and then walks that don't dirty unless they need + * to join/split. + */ +int scoutfs_btree_rebalance(struct super_block *sb, + struct scoutfs_alloc *alloc, + struct scoutfs_block_writer *wri, + struct scoutfs_btree_root *root, + struct scoutfs_key *key) +{ + return btree_walk(sb, alloc, wri, root, + BTW_DIRTY | BTW_INSERT | BTW_DELETE, + key, SCOUTFS_BTREE_MAX_VAL_LEN, NULL, NULL, NULL); +} + struct merge_pos { struct rb_node node; struct scoutfs_btree_root *root; diff --git a/kmod/src/btree.h b/kmod/src/btree.h index 02228290..63447669 100644 --- a/kmod/src/btree.h +++ b/kmod/src/btree.h @@ -97,6 +97,11 @@ int scoutfs_btree_set_parent(struct super_block *sb, struct scoutfs_btree_root *root, struct scoutfs_key *key, struct scoutfs_btree_root *par_root); +int scoutfs_btree_rebalance(struct super_block *sb, + struct scoutfs_alloc *alloc, + struct scoutfs_block_writer *wri, + struct scoutfs_btree_root *root, + struct scoutfs_key *key); /* merge input is a list of roots */ struct scoutfs_btree_root_head {