1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2018-2024 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_trans_resv.h" 11 #include "xfs_mount.h" 12 #include "xfs_defer.h" 13 #include "xfs_btree.h" 14 #include "xfs_bit.h" 15 #include "xfs_log_format.h" 16 #include "xfs_trans.h" 17 #include "xfs_sb.h" 18 #include "xfs_inode.h" 19 #include "xfs_alloc.h" 20 #include "xfs_ialloc.h" 21 #include "xfs_rmap.h" 22 #include "xfs_health.h" 23 #include "scrub/xfs_scrub.h" 24 #include "scrub/scrub.h" 25 #include "scrub/common.h" 26 #include "scrub/trace.h" 27 #include "scrub/repair.h" 28 #include "scrub/fscounters.h" 29 30 /* 31 * FS Summary Counters 32 * =================== 33 * 34 * We correct errors in the filesystem summary counters by setting them to the 35 * values computed during the obligatory scrub phase. However, we must be 36 * careful not to allow any other thread to change the counters while we're 37 * computing and setting new values. To achieve this, we freeze the 38 * filesystem for the whole operation if the REPAIR flag is set. The checking 39 * function is stricter when we've frozen the fs. 40 */ 41 42 /* 43 * Reset the superblock counters. Caller is responsible for freezing the 44 * filesystem during the calculation and reset phases. 45 */ 46 int 47 xrep_fscounters( 48 struct xfs_scrub *sc) 49 { 50 struct xfs_mount *mp = sc->mp; 51 struct xchk_fscounters *fsc = sc->buf; 52 53 /* 54 * Reinitialize the in-core counters from what we computed. We froze 55 * the filesystem, so there shouldn't be anyone else trying to modify 56 * these counters. 57 */ 58 if (!fsc->frozen) { 59 ASSERT(fsc->frozen); 60 return -EFSCORRUPTED; 61 } 62 63 trace_xrep_reset_counters(mp, fsc); 64 65 percpu_counter_set(&mp->m_icount, fsc->icount); 66 percpu_counter_set(&mp->m_ifree, fsc->ifree); 67 percpu_counter_set(&mp->m_fdblocks, fsc->fdblocks); 68 69 /* 70 * Online repair is only supported on v5 file systems, which require 71 * lazy sb counters and thus no update of sb_fdblocks here. But as of 72 * now we don't support lazy counting sb_frextents yet, and thus need 73 * to also update it directly here. And for that we need to keep 74 * track of the delalloc reservations separately, as they are are 75 * subtracted from m_frextents, but not included in sb_frextents. 76 */ 77 percpu_counter_set(&mp->m_frextents, 78 fsc->frextents - fsc->frextents_delayed); 79 mp->m_sb.sb_frextents = fsc->frextents; 80 81 return 0; 82 } 83