Commit 4bdfd7d1 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: repair free space btrees



Rebuild the free space btrees from the gaps in the rmap btree.  Refer to
the case study in Documentation/filesystems/xfs-online-fsck-design.rst
for more details.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 8bd0bf57
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ xfs-$(CONFIG_XFS_QUOTA) += scrub/quota.o
ifeq ($(CONFIG_XFS_ONLINE_REPAIR),y)
xfs-y				+= $(addprefix scrub/, \
				   agheader_repair.o \
				   alloc_repair.o \
				   newbt.o \
				   reap.o \
				   repair.o \
+9 −0
Original line number Diff line number Diff line
@@ -80,6 +80,15 @@ struct xfs_perag {
	 */
	uint16_t	pag_checked;
	uint16_t	pag_sick;

#ifdef CONFIG_XFS_ONLINE_REPAIR
	/*
	 * Alternate btree heights so that online repair won't trip the write
	 * verifiers while rebuilding the AG btrees.
	 */
	uint8_t		pagf_repair_levels[XFS_BTNUM_AGF];
#endif

	spinlock_t	pag_state_lock;

	spinlock_t	pagb_lock;	/* lock for pagb_tree */
+2 −0
Original line number Diff line number Diff line
@@ -411,6 +411,8 @@ xfs_ag_resv_free_extent(
		fallthrough;
	case XFS_AG_RESV_NONE:
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (int64_t)len);
		fallthrough;
	case XFS_AG_RESV_IGNORE:
		return;
	}

+4 −6
Original line number Diff line number Diff line
@@ -246,11 +246,9 @@ xfs_alloc_btrec_to_irec(
/* Simple checks for free space records. */
xfs_failaddr_t
xfs_alloc_check_irec(
	struct xfs_btree_cur		*cur,
	struct xfs_perag			*pag,
	const struct xfs_alloc_rec_incore	*irec)
{
	struct xfs_perag		*pag = cur->bc_ag.pag;

	if (irec->ar_blockcount == 0)
		return __this_address;

@@ -299,7 +297,7 @@ xfs_alloc_get_rec(
		return error;

	xfs_alloc_btrec_to_irec(rec, &irec);
	fa = xfs_alloc_check_irec(cur, &irec);
	fa = xfs_alloc_check_irec(cur->bc_ag.pag, &irec);
	if (fa)
		return xfs_alloc_complain_bad_rec(cur, fa, &irec);

@@ -3944,7 +3942,7 @@ xfs_alloc_query_range_helper(
	xfs_failaddr_t				fa;

	xfs_alloc_btrec_to_irec(rec, &irec);
	fa = xfs_alloc_check_irec(cur, &irec);
	fa = xfs_alloc_check_irec(cur->bc_ag.pag, &irec);
	if (fa)
		return xfs_alloc_complain_bad_rec(cur, fa, &irec);

+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ xfs_alloc_get_rec(
union xfs_btree_rec;
void xfs_alloc_btrec_to_irec(const union xfs_btree_rec *rec,
		struct xfs_alloc_rec_incore *irec);
xfs_failaddr_t xfs_alloc_check_irec(struct xfs_btree_cur *cur,
xfs_failaddr_t xfs_alloc_check_irec(struct xfs_perag *pag,
		const struct xfs_alloc_rec_incore *irec);

int xfs_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags,
Loading