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

xfs: online repair of realtime summaries



Repair the realtime summary data by constructing a new rtsummary file in
the scrub temporary file, then atomically swapping the contents.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 56596d8b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ xfs-y += $(addprefix scrub/, \

xfs-$(CONFIG_XFS_RT)		+= $(addprefix scrub/, \
				   rtbitmap_repair.o \
				   rtsummary_repair.o \
				   )

xfs-$(CONFIG_XFS_QUOTA)		+= $(addprefix scrub/, \
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "xfs_ag.h"
#include "xfs_error.h"
#include "xfs_quota.h"
#include "xfs_exchmaps.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
+3 −0
Original line number Diff line number Diff line
@@ -126,8 +126,10 @@ int xrep_fscounters(struct xfs_scrub *sc);

#ifdef CONFIG_XFS_RT
int xrep_rtbitmap(struct xfs_scrub *sc);
int xrep_rtsummary(struct xfs_scrub *sc);
#else
# define xrep_rtbitmap			xrep_notsupported
# define xrep_rtsummary			xrep_notsupported
#endif /* CONFIG_XFS_RT */

#ifdef CONFIG_XFS_QUOTA
@@ -212,6 +214,7 @@ xrep_setup_nothing(
#define xrep_quotacheck			xrep_notsupported
#define xrep_nlinks			xrep_notsupported
#define xrep_fscounters			xrep_notsupported
#define xrep_rtsummary			xrep_notsupported

#endif /* CONFIG_XFS_ONLINE_REPAIR */

+18 −15
Original line number Diff line number Diff line
@@ -17,10 +17,14 @@
#include "xfs_bit.h"
#include "xfs_bmap.h"
#include "xfs_sb.h"
#include "xfs_exchmaps.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
#include "scrub/xfile.h"
#include "scrub/repair.h"
#include "scrub/tempexch.h"
#include "scrub/rtsummary.h"

/*
 * Realtime Summary
@@ -32,18 +36,6 @@
 * (potentially large) amount of data in pageable memory.
 */

struct xchk_rtsummary {
	struct xfs_rtalloc_args	args;

	uint64_t		rextents;
	uint64_t		rbmblocks;
	uint64_t		rsumsize;
	unsigned int		rsumlevels;

	/* Memory buffer for the summary comparison. */
	union xfs_suminfo_raw	words[];
};

/* Set us up to check the rtsummary file. */
int
xchk_setup_rtsummary(
@@ -60,6 +52,12 @@ xchk_setup_rtsummary(
		return -ENOMEM;
	sc->buf = rts;

	if (xchk_could_repair(sc)) {
		error = xrep_setup_rtsummary(sc, rts);
		if (error)
			return error;
	}

	/*
	 * Create an xfile to construct a new rtsummary file.  The xfile allows
	 * us to avoid pinning kernel memory for this purpose.
@@ -70,7 +68,7 @@ xchk_setup_rtsummary(
	if (error)
		return error;

	error = xchk_trans_alloc(sc, 0);
	error = xchk_trans_alloc(sc, rts->resblks);
	if (error)
		return error;

@@ -135,7 +133,7 @@ xfsum_store(
			sumoff << XFS_WORDLOG);
}

static inline int
inline int
xfsum_copyout(
	struct xfs_scrub	*sc,
	xfs_rtsumoff_t		sumoff,
@@ -362,7 +360,12 @@ xchk_rtsummary(
	error = xchk_rtsum_compare(sc);

out_rbm:
	/* Unlock the rtbitmap since we're done with it. */
	/*
	 * Unlock the rtbitmap since we're done with it.  All other writers of
	 * the rt free space metadata grab the bitmap and summary ILOCKs in
	 * that order, so we're still protected against allocation activities
	 * even if we continue on to the repair function.
	 */
	xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
	return error;
}
+37 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2020-2024 Oracle.  All Rights Reserved.
 * Author: Darrick J. Wong <djwong@kernel.org>
 */
#ifndef __XFS_SCRUB_RTSUMMARY_H__
#define __XFS_SCRUB_RTSUMMARY_H__

struct xchk_rtsummary {
#ifdef CONFIG_XFS_ONLINE_REPAIR
	struct xrep_tempexch	tempexch;
#endif
	struct xfs_rtalloc_args	args;

	uint64_t		rextents;
	uint64_t		rbmblocks;
	uint64_t		rsumsize;
	unsigned int		rsumlevels;
	unsigned int		resblks;

	/* suminfo position of xfile as we write buffers to disk. */
	xfs_rtsumoff_t		prep_wordoff;

	/* Memory buffer for the summary comparison. */
	union xfs_suminfo_raw	words[];
};

int xfsum_copyout(struct xfs_scrub *sc, xfs_rtsumoff_t sumoff,
		union xfs_suminfo_raw *rawinfo, unsigned int nr_words);

#ifdef CONFIG_XFS_ONLINE_REPAIR
int xrep_setup_rtsummary(struct xfs_scrub *sc, struct xchk_rtsummary *rts);
#else
# define xrep_setup_rtsummary(sc, rts)	(0)
#endif /* CONFIG_XFS_ONLINE_REPAIR */

#endif /* __XFS_SCRUB_RTSUMMARY_H__ */
Loading