Skip to content

Commit 12ef830

Browse files
Christoph Hellwigdjwong
authored andcommitted
xfs: don't rely on ->total in xfs_alloc_space_available
->total is a bit of an odd parameter passed down to the low-level allocator all the way from the high-level callers. It's supposed to contain the maximum number of blocks to be allocated for the whole transaction [1]. But in xfs_iomap_write_allocate we only convert existing delayed allocations and thus only have a minimal block reservation for the current transaction, so xfs_alloc_space_available can't use it for the allocation decisions. Use the maximum of args->total and the calculated block requirement to make a decision. We probably should get rid of args->total eventually and instead apply ->minleft more broadly, but that will require some extensive changes all over. [1] which creates lots of confusion as most callers don't decrement it once doing a first allocation. But that's for a separate series. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Brian Foster <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 54fee13 commit 12ef830

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,7 @@ xfs_alloc_space_available(
19951995
int flags)
19961996
{
19971997
struct xfs_perag *pag = args->pag;
1998-
xfs_extlen_t longest;
1998+
xfs_extlen_t alloc_len, longest;
19991999
xfs_extlen_t reservation; /* blocks that are still reserved */
20002000
int available;
20012001

@@ -2005,15 +2005,16 @@ xfs_alloc_space_available(
20052005
reservation = xfs_ag_resv_needed(pag, args->resv);
20062006

20072007
/* do we have enough contiguous free space for the allocation? */
2008+
alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
20082009
longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
20092010
reservation);
2010-
if ((args->minlen + args->alignment + args->minalignslop - 1) > longest)
2011+
if (longest < alloc_len)
20112012
return false;
20122013

20132014
/* do we have enough free space remaining for the allocation? */
20142015
available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
20152016
reservation - min_free - args->minleft);
2016-
if (available < (int)args->total)
2017+
if (available < (int)max(args->total, alloc_len))
20172018
return false;
20182019

20192020
/*

0 commit comments

Comments
 (0)