// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2021-2024 Oracle. All Rights Reserved. * Author: Darrick J. Wong <[email protected]> */ #include "xfs.h" #include "xfs_fs.h" #include "xfs_shared.h" #include "xfs_format.h" #include "xfs_trans_resv.h" #include "xfs_mount.h" #include "xfs_log_format.h" #include "xfs_trans.h" #include "xfs_inode.h" #include "xfs_btree.h" #include "xfs_ialloc.h" #include "xfs_ialloc_btree.h" #include "xfs_ag.h" #include "xfs_error.h" #include "xfs_bit.h" #include "xfs_icache.h" #include "scrub/scrub.h" #include "scrub/iscan.h" #include "scrub/common.h" #include "scrub/trace.h" /* * Live File Scan * ============== * * Live file scans walk every inode in a live filesystem. This is more or * less like a regular iwalk, except that when we're advancing the scan cursor, * we must ensure that inodes cannot be added or deleted anywhere between the * old cursor value and the new cursor value. If we're advancing the cursor * by one inode, the caller must hold that inode; if we're finding the next * inode to scan, we must grab the AGI and hold it until we've updated the * scan cursor. * * Callers are expected to use this code to scan all files in the filesystem to * construct a new metadata index of some kind. The scan races against other * live updates, which means there must be a provision to update the new index * when updates are made to inodes that already been scanned. The iscan lock * can be used in live update hook code to stop the scan and protect this data * structure. * * To keep the new index up to date with other metadata updates being made to * the live filesystem, it is assumed that the caller will add hooks as needed * to be notified when a metadata update occurs. The inode scanner must tell * the hook code when an inode has been visited with xchk_iscan_mark_visit. * Hook functions can use xchk_iscan_want_live_update to decide if the * scanner's observations must be updated. */ /* * If the inobt record @rec covers @iscan->skip_ino, mark the inode free so * that the scan ignores that inode. */ STATIC void xchk_iscan_mask_skipino( struct xchk_iscan *iscan, struct xfs_perag *pag, struct xfs_inobt_rec_incore *rec, xfs_agino_t lastrecino) { … } /* * Set *cursor to the next allocated inode after whatever it's set to now. * If there are no more inodes in this AG, cursor is set to NULLAGINO. */ STATIC int xchk_iscan_find_next( struct xchk_iscan *iscan, struct xfs_buf *agi_bp, struct xfs_perag *pag, xfs_inofree_t *allocmaskp, xfs_agino_t *cursor, uint8_t *nr_inodesp) { … } /* * Advance both the scan and the visited cursors. * * The inumber address space for a given filesystem is sparse, which means that * the scan cursor can jump a long ways in a single iter() call. There are no * inodes in these sparse areas, so we must move the visited cursor forward at * the same time so that the scan user can receive live updates for inodes that * may get created once we release the AGI buffer. */ static inline void xchk_iscan_move_cursor( struct xchk_iscan *iscan, xfs_agnumber_t agno, xfs_agino_t agino) { … } /* * Prepare to return agno/agino to the iscan caller by moving the lastino * cursor to the previous inode. Do this while we still hold the AGI so that * no other threads can create or delete inodes in this AG. */ static inline void xchk_iscan_finish( struct xchk_iscan *iscan) { … } /* Mark an inode scan finished before we actually scan anything. */ void xchk_iscan_finish_early( struct xchk_iscan *iscan) { … } /* * Grab the AGI to advance the inode scan. Returns 0 if *agi_bpp is now set, * -ECANCELED if the live scan aborted, -EBUSY if the AGI could not be grabbed, * or the usual negative errno. */ STATIC int xchk_iscan_read_agi( struct xchk_iscan *iscan, struct xfs_perag *pag, struct xfs_buf **agi_bpp) { … } /* * Advance ino to the next inode that the inobt thinks is allocated, being * careful to jump to the next AG if we've reached the right end of this AG's * inode btree. Advancing ino effectively means that we've pushed the inode * scan forward, so set the iscan cursor to (ino - 1) so that our live update * predicates will track inode allocations in that part of the inode number * key space once we release the AGI buffer. * * Returns 1 if there's a new inode to examine, 0 if we've run out of inodes, * -ECANCELED if the live scan aborted, or the usual negative errno. */ STATIC int xchk_iscan_advance( struct xchk_iscan *iscan, struct xfs_perag **pagp, struct xfs_buf **agi_bpp, xfs_inofree_t *allocmaskp, uint8_t *nr_inodesp) { … } /* * Grabbing the inode failed, so we need to back up the scan and ask the caller * to try to _advance the scan again. Returns -EBUSY if we've run out of retry * opportunities, -ECANCELED if the process has a fatal signal pending, or * -EAGAIN if we should try again. */ STATIC int xchk_iscan_iget_retry( struct xchk_iscan *iscan, bool wait) { … } /* * For an inode scan, we hold the AGI and want to try to grab a batch of * inodes. Holding the AGI prevents inodegc from clearing freed inodes, * so we must use noretry here. For every inode after the first one in the * batch, we don't want to wait, so we use retry there too. Finally, use * dontcache to avoid polluting the cache. */ #define ISCAN_IGET_FLAGS … /* * Grab an inode as part of an inode scan. While scanning this inode, the * caller must ensure that no other threads can modify the inode until a call * to xchk_iscan_visit succeeds. * * Returns the number of incore inodes grabbed; -EAGAIN if the caller should * call again xchk_iscan_advance; -EBUSY if we couldn't grab an inode; * -ECANCELED if there's a fatal signal pending; or some other negative errno. */ STATIC int xchk_iscan_iget( struct xchk_iscan *iscan, struct xfs_perag *pag, struct xfs_buf *agi_bp, xfs_inofree_t allocmask, uint8_t nr_inodes) { … } /* * Advance the visit cursor to reflect skipped inodes beyond whatever we * scanned. */ STATIC void xchk_iscan_finish_batch( struct xchk_iscan *iscan) { … } /* * Advance the inode scan cursor to the next allocated inode and return up to * 64 consecutive allocated inodes starting with the cursor position. */ STATIC int xchk_iscan_iter_batch( struct xchk_iscan *iscan) { … } /* * Advance the inode scan cursor to the next allocated inode and return the * incore inode structure associated with it. * * Returns 1 if there's a new inode to examine, 0 if we've run out of inodes, * -ECANCELED if the live scan aborted, -EBUSY if the incore inode could not be * grabbed, or the usual negative errno. * * If the function returns -EBUSY and the caller can handle skipping an inode, * it may call this function again to continue the scan with the next allocated * inode. */ int xchk_iscan_iter( struct xchk_iscan *iscan, struct xfs_inode **ipp) { … } /* Clean up an xfs_iscan_iter call by dropping any inodes that we still hold. */ void xchk_iscan_iter_finish( struct xchk_iscan *iscan) { … } /* Mark this inode scan finished and release resources. */ void xchk_iscan_teardown( struct xchk_iscan *iscan) { … } /* Pick an AG from which to start a scan. */ static inline xfs_ino_t xchk_iscan_rotor( struct xfs_mount *mp) { … } /* * Set ourselves up to start an inode scan. If the @iget_timeout and * @iget_retry_delay parameters are set, the scan will try to iget each inode * for @iget_timeout milliseconds. If an iget call indicates that the inode is * waiting to be inactivated, the CPU will relax for @iget_retry_delay * milliseconds after pushing the inactivation workers. */ void xchk_iscan_start( struct xfs_scrub *sc, unsigned int iget_timeout, unsigned int iget_retry_delay, struct xchk_iscan *iscan) { … } /* * Mark this inode as having been visited. Callers must hold a sufficiently * exclusive lock on the inode to prevent concurrent modifications. */ void xchk_iscan_mark_visited( struct xchk_iscan *iscan, struct xfs_inode *ip) { … } /* * Did we skip this inode because it wasn't allocated when we loaded the batch? * If so, it is newly allocated and will not be scanned. All live updates to * this inode must be passed to the caller to maintain scan correctness. */ static inline bool xchk_iscan_skipped( const struct xchk_iscan *iscan, xfs_ino_t ino) { … } /* * Do we need a live update for this inode? This is true if the scanner thread * has visited this inode and the scan hasn't been aborted due to errors. * Callers must hold a sufficiently exclusive lock on the inode to prevent * scanners from reading any inode metadata. */ bool xchk_iscan_want_live_update( struct xchk_iscan *iscan, xfs_ino_t ino) { … }