diff mbox series

[RFC,3/4] xfs: let allocations tap the AGFL reserve

Message ID ea3afc58fdf51c5edd86455bfea8d6a6fc448d1f.1718232004.git.kjlx@templeofstupid.com (mailing list archive)
State New
Headers show
Series bringing back the AGFL reserve | expand

Commit Message

Krister Johansen June 13, 2024, 8:27 p.m. UTC
In the case where a transaction is making an allocation after its
initial allocation, allow that transaction to tap the AGFL reserve.
This is done in case a prior allocation depleted the freelists below
their minimum fill and reserve space is needed to finish the
transaction.  This is predicated on the earlier phases of the allocation
enforcing that the AGFL reserve has sufficient space for the transaction
to refill the AGFL.  That enforcement is in a separate commit.

Signed-off-by: Krister Johansen <kjlx@templeofstupid.com>
---
 fs/xfs/libxfs/xfs_alloc.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 0b15414468cf..3fc8448e02d9 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2389,6 +2389,7 @@  xfs_alloc_space_available(
 	int			flags)
 {
 	struct xfs_perag	*pag = args->pag;
+	enum xfs_ag_resv_type	resv_type = args->resv;
 	xfs_extlen_t		alloc_len, longest;
 	xfs_extlen_t		reservation; /* blocks that are still reserved */
 	int			available;
@@ -2397,7 +2398,19 @@  xfs_alloc_space_available(
 	if (flags & XFS_ALLOC_FLAG_FREEING)
 		return true;
 
-	reservation = xfs_ag_resv_needed(pag, args->resv);
+	/*
+	 * If this allocation is a subsequent allocation in a transaction with
+	 * multiple allocations, allow it to tap the AGFL reserve in order to
+	 * ensure that it can refill its freelist if a prior transaction has
+	 * depleted it.  This is done to ensure that the available space checks
+	 * below don't stop an allocation that's up against the reservation
+	 * space limits when there is AGFL space still reserved and available.
+	 */
+	if (args->tp->t_highest_agno != NULLAGNUMBER &&
+	    args->resv == XFS_AG_RESV_NONE) {
+		resv_type = XFS_AG_RESV_AGFL;
+	}
+	reservation = xfs_ag_resv_needed(pag, resv_type);
 
 	/* do we have enough contiguous free space for the allocation? */
 	alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;