xref: /linux/fs/xfs/scrub/fscounters_repair.c (revision c148bc7535650fbfa95a1f571b9ffa2ab478ea33)
14ed080cdSDarrick J. Wong // SPDX-License-Identifier: GPL-2.0-or-later
24ed080cdSDarrick J. Wong /*
34ed080cdSDarrick J. Wong  * Copyright (c) 2018-2024 Oracle.  All Rights Reserved.
44ed080cdSDarrick J. Wong  * Author: Darrick J. Wong <djwong@kernel.org>
54ed080cdSDarrick J. Wong  */
64ed080cdSDarrick J. Wong #include "xfs.h"
74ed080cdSDarrick J. Wong #include "xfs_fs.h"
84ed080cdSDarrick J. Wong #include "xfs_shared.h"
94ed080cdSDarrick J. Wong #include "xfs_format.h"
104ed080cdSDarrick J. Wong #include "xfs_trans_resv.h"
114ed080cdSDarrick J. Wong #include "xfs_mount.h"
124ed080cdSDarrick J. Wong #include "xfs_defer.h"
134ed080cdSDarrick J. Wong #include "xfs_btree.h"
144ed080cdSDarrick J. Wong #include "xfs_bit.h"
154ed080cdSDarrick J. Wong #include "xfs_log_format.h"
164ed080cdSDarrick J. Wong #include "xfs_trans.h"
174ed080cdSDarrick J. Wong #include "xfs_sb.h"
184ed080cdSDarrick J. Wong #include "xfs_inode.h"
194ed080cdSDarrick J. Wong #include "xfs_alloc.h"
204ed080cdSDarrick J. Wong #include "xfs_ialloc.h"
214ed080cdSDarrick J. Wong #include "xfs_rmap.h"
224ed080cdSDarrick J. Wong #include "xfs_health.h"
234ed080cdSDarrick J. Wong #include "scrub/xfs_scrub.h"
244ed080cdSDarrick J. Wong #include "scrub/scrub.h"
254ed080cdSDarrick J. Wong #include "scrub/common.h"
264ed080cdSDarrick J. Wong #include "scrub/trace.h"
274ed080cdSDarrick J. Wong #include "scrub/repair.h"
284ed080cdSDarrick J. Wong #include "scrub/fscounters.h"
294ed080cdSDarrick J. Wong 
304ed080cdSDarrick J. Wong /*
314ed080cdSDarrick J. Wong  * FS Summary Counters
324ed080cdSDarrick J. Wong  * ===================
334ed080cdSDarrick J. Wong  *
344ed080cdSDarrick J. Wong  * We correct errors in the filesystem summary counters by setting them to the
354ed080cdSDarrick J. Wong  * values computed during the obligatory scrub phase.  However, we must be
364ed080cdSDarrick J. Wong  * careful not to allow any other thread to change the counters while we're
374ed080cdSDarrick J. Wong  * computing and setting new values.  To achieve this, we freeze the
384ed080cdSDarrick J. Wong  * filesystem for the whole operation if the REPAIR flag is set.  The checking
394ed080cdSDarrick J. Wong  * function is stricter when we've frozen the fs.
404ed080cdSDarrick J. Wong  */
414ed080cdSDarrick J. Wong 
424ed080cdSDarrick J. Wong /*
434ed080cdSDarrick J. Wong  * Reset the superblock counters.  Caller is responsible for freezing the
444ed080cdSDarrick J. Wong  * filesystem during the calculation and reset phases.
454ed080cdSDarrick J. Wong  */
464ed080cdSDarrick J. Wong int
xrep_fscounters(struct xfs_scrub * sc)474ed080cdSDarrick J. Wong xrep_fscounters(
484ed080cdSDarrick J. Wong 	struct xfs_scrub	*sc)
494ed080cdSDarrick J. Wong {
504ed080cdSDarrick J. Wong 	struct xfs_mount	*mp = sc->mp;
514ed080cdSDarrick J. Wong 	struct xchk_fscounters	*fsc = sc->buf;
524ed080cdSDarrick J. Wong 
534ed080cdSDarrick J. Wong 	/*
544ed080cdSDarrick J. Wong 	 * Reinitialize the in-core counters from what we computed.  We froze
554ed080cdSDarrick J. Wong 	 * the filesystem, so there shouldn't be anyone else trying to modify
564ed080cdSDarrick J. Wong 	 * these counters.
574ed080cdSDarrick J. Wong 	 */
584ed080cdSDarrick J. Wong 	if (!fsc->frozen) {
594ed080cdSDarrick J. Wong 		ASSERT(fsc->frozen);
604ed080cdSDarrick J. Wong 		return -EFSCORRUPTED;
614ed080cdSDarrick J. Wong 	}
624ed080cdSDarrick J. Wong 
634ed080cdSDarrick J. Wong 	trace_xrep_reset_counters(mp, fsc);
644ed080cdSDarrick J. Wong 
654ed080cdSDarrick J. Wong 	percpu_counter_set(&mp->m_icount, fsc->icount);
664ed080cdSDarrick J. Wong 	percpu_counter_set(&mp->m_ifree, fsc->ifree);
67712bae96SChristoph Hellwig 	xfs_set_freecounter(mp, XC_FREE_BLOCKS, fsc->fdblocks);
687099bd0fSChristoph Hellwig 
697099bd0fSChristoph Hellwig 	/*
707099bd0fSChristoph Hellwig 	 * Online repair is only supported on v5 file systems, which require
7135537f25SDarrick J. Wong 	 * lazy sb counters and thus no update of sb_fdblocks here.  But
7235537f25SDarrick J. Wong 	 * sb_frextents only uses a lazy counter with rtgroups, and thus needs
7335537f25SDarrick J. Wong 	 * to be updated directly here otherwise.  And for that we need to keep
747099bd0fSChristoph Hellwig 	 * track of the delalloc reservations separately, as they are are
757099bd0fSChristoph Hellwig 	 * subtracted from m_frextents, but not included in sb_frextents.
767099bd0fSChristoph Hellwig 	 */
77*1d319ac6SChristoph Hellwig 	if (!xfs_has_zoned(mp)) {
78712bae96SChristoph Hellwig 		xfs_set_freecounter(mp, XC_FREE_RTEXTENTS,
797099bd0fSChristoph Hellwig 				fsc->frextents - fsc->frextents_delayed);
8035537f25SDarrick J. Wong 		if (!xfs_has_rtgroups(mp))
814ed080cdSDarrick J. Wong 			mp->m_sb.sb_frextents = fsc->frextents;
82*1d319ac6SChristoph Hellwig 	}
834ed080cdSDarrick J. Wong 
844ed080cdSDarrick J. Wong 	return 0;
854ed080cdSDarrick J. Wong }
86