Skip to content

Commit 0f93425

Browse files
author
Darrick J. Wong
committed
xfs: check free AG space when making per-AG reservations
The new online shrink code exposed a gap in the per-AG reservation code, which is that we only return ENOSPC to callers if the entire fs doesn't have enough free blocks. Except for debugging mode, the reservation init code doesn't ever check that there's enough free space in that AG to cover the reservation. Not having enough space is not considered an immediate fatal error that requires filesystem offlining because (a) it's shouldn't be possible to wind up in that state through normal file operations and (b) even if one did, freeing data blocks would recover the situation. However, online shrink now needs to know if shrinking would not leave enough space so that it can abort the shrink operation. Hence we need to promote this assertion into an actual error return. Observed by running xfs/168 with a 1k block size, though in theory this could happen with any configuration. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Brian Foster <[email protected]> Reviewed-by: Carlos Maiolino <[email protected]> Reviewed-by: Gao Xiang <[email protected]>
1 parent e3c2b04 commit 0f93425

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

fs/xfs/libxfs/xfs_ag_resv.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,22 @@ xfs_ag_resv_init(
325325
error2 = xfs_alloc_pagf_init(mp, tp, pag->pag_agno, 0);
326326
if (error2)
327327
return error2;
328-
ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
329-
xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved <=
330-
pag->pagf_freeblks + pag->pagf_flcount);
328+
329+
/*
330+
* If there isn't enough space in the AG to satisfy the
331+
* reservation, let the caller know that there wasn't enough
332+
* space. Callers are responsible for deciding what to do
333+
* next, since (in theory) we can stumble along with
334+
* insufficient reservation if data blocks are being freed to
335+
* replenish the AG's free space.
336+
*/
337+
if (!error &&
338+
xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
339+
xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved >
340+
pag->pagf_freeblks + pag->pagf_flcount)
341+
error = -ENOSPC;
331342
}
343+
332344
return error;
333345
}
334346

0 commit comments

Comments
 (0)