Hi all, Last week, I was running xfs/306 (which formats a single-AG 20MB filesystem) with an fstests configuration that specifies a 1k blocksize and a specially crafted log size that will consume 7/8 of the space (17920 blocks, specifically) in that AG. This resulted mount hanging on the infinite loop in xfs_reserve_blocks because we overestimate the number of blocks that xfs_mod_fdblocks will give us, and the code retries forever. v2: Initially, this was a single patch that fixed the calculation and transformed the loop into a finite loop. However, further discussion revealed several more issues: * People had a hard time grokking that the "alloc_set_aside" is actually the amount of space we hide so that a bmbt split will always succeed; * The author didn't understand what XFS_ALLOC_AGFL_RESERVE actually mean or whether it was correctly calculated; * The "alloc_set_aside" underestimated the blocks needed to handle any bmap btree split; * Both statfs and XFS_IOC_FSCOUNTS forgot to exclude the amount of space used by the free space btrees on behalf of per-AG reservations, leading to overreporting of available space; * The loop control change really should have been separate. Hence, this patchset has now grown to six patches to address each of these issues separately. v3: only add one helper for calculating the total fdblocks setaside and tighten some documentation If you're going to start using this mess, you probably ought to just pull from my git trees, which are linked below. This is an extraordinary way to destroy everything. Enjoy! Comments and questions are, as always, welcome. --D kernel git tree: https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=reserve-block-fixes-5.18 --- fs/xfs/libxfs/xfs_alloc.c | 30 +++++++++++++++++++++++------- fs/xfs/libxfs/xfs_alloc.h | 3 +-- fs/xfs/libxfs/xfs_sb.c | 2 -- fs/xfs/xfs_fsops.c | 18 +++++++++++++----- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_mount.c | 9 ++++++++- fs/xfs/xfs_mount.h | 18 +++++++++++++++++- fs/xfs/xfs_super.c | 3 ++- 8 files changed, 65 insertions(+), 20 deletions(-)