From c1bd7bcce51350b80ef27c9f1e8dc434efcc4092 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 15 Dec 2022 20:20:17 -0800 Subject: [PATCH] Allow partial extent motion Refilling a client's data_avail is the only alloc_move call that doesn't try and limit the number of blocks that it dirties. If it doesn't find sufficiently large extents it can exhaust the server's alloc budget without hitting the target. It'll try to dirty blocks and return a hard error. This changes that behaviour to allow returning 0 if it moved any extents. Other callers can deal with partial progress as they already limit the blocks they dirty. This will also return ENOSPC if it hadn't moved anything just as the current code would. The result is that data fill can not necessarily hit the target. It might take multiple commits to fill the data_avail btree. Signed-off-by: Zach Brown --- kmod/src/alloc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index a36387b7..f0a94d97 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -976,6 +976,16 @@ int scoutfs_alloc_move(struct super_block *sb, struct scoutfs_alloc *alloc, break; } + /* return partial if the server alloc can't dirty any more */ + if (scoutfs_alloc_meta_low(sb, alloc, 50 + extent_mod_blocks(src->root.height) + + extent_mod_blocks(dst->root.height))) { + if (WARN_ON_ONCE(!moved)) + ret = -ENOSPC; + else + ret = 0; + break; + } + /* searching set start/len, finish initializing alloced extent */ ext.map = found.map ? ext.start - found.start + found.map : 0; ext.flags = found.flags;