Skip to content

Commit

Permalink
xfs: check free AG space when making per-AG reservations
Browse files Browse the repository at this point in the history
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 <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
  • Loading branch information
Darrick J. Wong committed May 25, 2021
1 parent e3c2b04 commit 0f93425
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions fs/xfs/libxfs/xfs_ag_resv.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,22 @@ xfs_ag_resv_init(
error2 = xfs_alloc_pagf_init(mp, tp, pag->pag_agno, 0);
if (error2)
return error2;
ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved <=
pag->pagf_freeblks + pag->pagf_flcount);

/*
* If there isn't enough space in the AG to satisfy the
* reservation, let the caller know that there wasn't enough
* space. Callers are responsible for deciding what to do
* next, since (in theory) we can stumble along with
* insufficient reservation if data blocks are being freed to
* replenish the AG's free space.
*/
if (!error &&
xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
xfs_perag_resv(pag, XFS_AG_RESV_RMAPBT)->ar_reserved >
pag->pagf_freeblks + pag->pagf_flcount)
error = -ENOSPC;
}

return error;
}

Expand Down

0 comments on commit 0f93425

Please sign in to comment.