Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2019 Oracle.  All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Author: Darrick J. Wong <darrick.wong@oracle.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "xfs_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "xfs_ialloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "xfs_ialloc_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "xfs_iwalk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "xfs_icache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "xfs_health.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "xfs_pwork.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * Walking Inodes in the Filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * ================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * This iterator function walks a subset of filesystem inodes in increasing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * order from @startino until there are no more inodes.  For each allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * inode it finds, it calls a walk function with the relevant inode number and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * a pointer to caller-provided data.  The walk function can return the usual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * negative error code to stop the iteration; 0 to continue the iteration; or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * -ECANCELED to stop the iteration.  This return value is returned to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * Internally, we allow the walk function to do anything, which means that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * cannot maintain the inobt cursor or our lock on the AGI buffer.  We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * therefore cache the inobt records in kernel memory and only call the walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * function when our memory buffer is full.  @nr_recs is the number of records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * that we've cached, and @sz_recs is the size of our cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * It is the responsibility of the walk function to ensure it accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * allocated inodes, as the inobt records may be stale by the time they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * acted upon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) struct xfs_iwalk_ag {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	/* parallel work control data; will be null if single threaded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	struct xfs_pwork		pwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct xfs_mount		*mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct xfs_trans		*tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	/* Where do we start the traversal? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	xfs_ino_t			startino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	/* What was the last inode number we saw when iterating the inobt? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	xfs_ino_t			lastino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	/* Array of inobt records we cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct xfs_inobt_rec_incore	*recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	/* Number of entries allocated for the @recs array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	unsigned int			sz_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/* Number of entries in the @recs array that are in use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	unsigned int			nr_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	/* Inode walk function and data pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	xfs_iwalk_fn			iwalk_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	xfs_inobt_walk_fn		inobt_walk_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	void				*data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 * Make it look like the inodes up to startino are free so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 * bulkstat can start its inode iteration at the correct place without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * needing to special case everywhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned int			trim_start:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	/* Skip empty inobt records? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	unsigned int			skip_empty:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * Loop over all clusters in a chunk for a given incore inode allocation btree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * record.  Do a readahead if there are any allocated inodes in that cluster.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) xfs_iwalk_ichunk_ra(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct xfs_mount		*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	xfs_agnumber_t			agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct xfs_inobt_rec_incore	*irec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct xfs_ino_geometry		*igeo = M_IGEO(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	xfs_agblock_t			agbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct blk_plug			plug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int				i;	/* inode chunk index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	agbno = XFS_AGINO_TO_AGBNO(mp, irec->ir_startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	blk_start_plug(&plug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	for (i = 0; i < XFS_INODES_PER_CHUNK; i += igeo->inodes_per_cluster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		xfs_inofree_t	imask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		imask = xfs_inobt_maskn(i, igeo->inodes_per_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		if (imask & ~irec->ir_free) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			xfs_btree_reada_bufs(mp, agno, agbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 					igeo->blocks_per_cluster,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 					&xfs_inode_buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		agbno += igeo->blocks_per_cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	blk_finish_plug(&plug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * Set the bits in @irec's free mask that correspond to the inodes before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * @agino so that we skip them.  This is how we restart an inode walk that was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * interrupted in the middle of an inode record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) xfs_iwalk_adjust_start(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	xfs_agino_t			agino,	/* starting inode of chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct xfs_inobt_rec_incore	*irec)	/* btree record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	int				idx;	/* index into inode chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	int				i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	idx = agino - irec->ir_startino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 * We got a right chunk with some left inodes allocated at it.  Grab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	 * the chunk record.  Mark all the uninteresting inodes free because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	 * they're before our start point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	for (i = 0; i < idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		if (XFS_INOBT_MASK(i) & ~irec->ir_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			irec->ir_freecount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	irec->ir_free |= xfs_inobt_maskn(0, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Allocate memory for a walk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) xfs_iwalk_alloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct xfs_iwalk_ag	*iwag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	size_t			size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ASSERT(iwag->recs == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	iwag->nr_recs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	/* Allocate a prefetch buffer for inobt records. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	size = iwag->sz_recs * sizeof(struct xfs_inobt_rec_incore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	iwag->recs = kmem_alloc(size, KM_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (iwag->recs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Free memory we allocated for a walk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) xfs_iwalk_free(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct xfs_iwalk_ag	*iwag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	kmem_free(iwag->recs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	iwag->recs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* For each inuse inode in each cached inobt record, call our function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xfs_iwalk_ag_recs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	struct xfs_iwalk_ag		*iwag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct xfs_mount		*mp = iwag->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct xfs_trans		*tp = iwag->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	xfs_ino_t			ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	unsigned int			i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	xfs_agnumber_t			agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	agno = XFS_INO_TO_AGNO(mp, iwag->startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	for (i = 0; i < iwag->nr_recs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		struct xfs_inobt_rec_incore	*irec = &iwag->recs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		trace_xfs_iwalk_ag_rec(mp, agno, irec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		if (xfs_pwork_want_abort(&iwag->pwork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		if (iwag->inobt_walk_fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			error = iwag->inobt_walk_fn(mp, tp, agno, irec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 					iwag->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		if (!iwag->iwalk_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		for (j = 0; j < XFS_INODES_PER_CHUNK; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if (xfs_pwork_want_abort(&iwag->pwork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			/* Skip if this inode is free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			if (XFS_INOBT_MASK(j) & irec->ir_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			/* Otherwise call our function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			ino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino + j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			error = iwag->iwalk_fn(mp, tp, ino, iwag->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Delete cursor and let go of AGI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) xfs_iwalk_del_inobt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct xfs_btree_cur	**curpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	struct xfs_buf		**agi_bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int			error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (*curpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		xfs_btree_del_cursor(*curpp, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		*curpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (*agi_bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		xfs_trans_brelse(tp, *agi_bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		*agi_bpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * Set ourselves up for walking inobt records starting from a given point in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  * If caller passed in a nonzero start inode number, load the record from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * inobt and make the record look like all the inodes before agino are free so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * that we skip them, and then move the cursor to the next inobt record.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * is how we support starting an iwalk in the middle of an inode chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * If the caller passed in a start number of zero, move the cursor to the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * inobt record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * The caller is responsible for cleaning up the cursor and buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * regardless of the error status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) xfs_iwalk_ag_start(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	struct xfs_iwalk_ag	*iwag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	xfs_agnumber_t		agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	xfs_agino_t		agino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct xfs_btree_cur	**curpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	struct xfs_buf		**agi_bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	int			*has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	struct xfs_mount	*mp = iwag->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct xfs_trans	*tp = iwag->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct xfs_inobt_rec_incore *irec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/* Set up a fresh cursor and empty the inobt cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	iwag->nr_recs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	error = xfs_inobt_cur(mp, tp, agno, XFS_BTNUM_INO, curpp, agi_bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	/* Starting at the beginning of the AG?  That's easy! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (agino == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		return xfs_inobt_lookup(*curpp, 0, XFS_LOOKUP_GE, has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	 * Otherwise, we have to grab the inobt record where we left off, stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	 * the record into our cache, and then see if there are more records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 * We require a lookup cache of at least two elements so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 * caller doesn't have to deal with tearing down the cursor to walk the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	 * records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	error = xfs_inobt_lookup(*curpp, agino, XFS_LOOKUP_LE, has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	 * If the LE lookup at @agino yields no records, jump ahead to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	 * inobt cursor increment to see if there are more records to process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (!*has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		goto out_advance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Get the record, should always work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	irec = &iwag->recs[iwag->nr_recs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	error = xfs_inobt_get_rec(*curpp, irec, has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (XFS_IS_CORRUPT(mp, *has_more != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	iwag->lastino = XFS_AGINO_TO_INO(mp, agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				irec->ir_startino + XFS_INODES_PER_CHUNK - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * If the LE lookup yielded an inobt record before the cursor position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 * skip it and see if there's another one after it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (irec->ir_startino + XFS_INODES_PER_CHUNK <= agino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		goto out_advance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	 * If agino fell in the middle of the inode record, make it look like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	 * the inodes up to agino are free so that we don't return them again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (iwag->trim_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		xfs_iwalk_adjust_start(agino, irec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	 * The prefetch calculation is supposed to give us a large enough inobt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	 * record cache that grab_ichunk can stage a partial first record and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	 * the loop body can cache a record without having to check for cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	 * space until after it reads an inobt record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	iwag->nr_recs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	ASSERT(iwag->nr_recs < iwag->sz_recs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) out_advance:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	return xfs_btree_increment(*curpp, 0, has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * The inobt record cache is full, so preserve the inobt cursor state and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * run callbacks on the cached inobt records.  When we're done, restore the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  * cursor state to wherever the cursor would have been had the cache not been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * full (and therefore we could've just incremented the cursor) if *@has_more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * is true.  On exit, *@has_more will indicate whether or not the caller should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  * try for more inode records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) xfs_iwalk_run_callbacks(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	struct xfs_iwalk_ag		*iwag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	xfs_agnumber_t			agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	struct xfs_btree_cur		**curpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	struct xfs_buf			**agi_bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	int				*has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct xfs_mount		*mp = iwag->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	struct xfs_trans		*tp = iwag->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	struct xfs_inobt_rec_incore	*irec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	xfs_agino_t			next_agino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	next_agino = XFS_INO_TO_AGINO(mp, iwag->lastino) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	ASSERT(iwag->nr_recs > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	/* Delete cursor but remember the last record we cached... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	xfs_iwalk_del_inobt(tp, curpp, agi_bpp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	irec = &iwag->recs[iwag->nr_recs - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	ASSERT(next_agino == irec->ir_startino + XFS_INODES_PER_CHUNK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	error = xfs_iwalk_ag_recs(iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* ...empty the cache... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	iwag->nr_recs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (!has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	/* ...and recreate the cursor just past where we left off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	error = xfs_inobt_cur(mp, tp, agno, XFS_BTNUM_INO, curpp, agi_bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return xfs_inobt_lookup(*curpp, next_agino, XFS_LOOKUP_GE, has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Walk all inodes in a single AG, from @iwag->startino to the end of the AG. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) xfs_iwalk_ag(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	struct xfs_iwalk_ag		*iwag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	struct xfs_mount		*mp = iwag->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	struct xfs_trans		*tp = iwag->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	struct xfs_buf			*agi_bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	struct xfs_btree_cur		*cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	xfs_agnumber_t			agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	xfs_agino_t			agino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	int				has_more;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	int				error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	/* Set up our cursor at the right place in the inode btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	agno = XFS_INO_TO_AGNO(mp, iwag->startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	agino = XFS_INO_TO_AGINO(mp, iwag->startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	error = xfs_iwalk_ag_start(iwag, agno, agino, &cur, &agi_bp, &has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	while (!error && has_more) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		struct xfs_inobt_rec_incore	*irec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		xfs_ino_t			rec_fsino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (xfs_pwork_want_abort(&iwag->pwork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		/* Fetch the inobt record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		irec = &iwag->recs[iwag->nr_recs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		error = xfs_inobt_get_rec(cur, irec, &has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		if (error || !has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		/* Make sure that we always move forward. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		rec_fsino = XFS_AGINO_TO_INO(mp, agno, irec->ir_startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		if (iwag->lastino != NULLFSINO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		    XFS_IS_CORRUPT(mp, iwag->lastino >= rec_fsino)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		iwag->lastino = rec_fsino + XFS_INODES_PER_CHUNK - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		/* No allocated inodes in this chunk; skip it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		if (iwag->skip_empty && irec->ir_freecount == irec->ir_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			error = xfs_btree_increment(cur, 0, &has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		 * Start readahead for this inode chunk in anticipation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		 * walking the inodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		if (iwag->iwalk_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			xfs_iwalk_ichunk_ra(mp, agno, irec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		 * If there's space in the buffer for more records, increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		 * the btree cursor and grab more.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		if (++iwag->nr_recs < iwag->sz_recs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			error = xfs_btree_increment(cur, 0, &has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			if (error || !has_more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		 * Otherwise, we need to save cursor state and run the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		 * function on the cached records.  The run_callbacks function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		 * is supposed to return a cursor pointing to the record where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		 * we would be if we had been able to increment like above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		ASSERT(has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		error = xfs_iwalk_run_callbacks(iwag, agno, &cur, &agi_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				&has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	if (iwag->nr_recs == 0 || error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	/* Walk the unprocessed records in the cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	error = xfs_iwalk_run_callbacks(iwag, agno, &cur, &agi_bp, &has_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	xfs_iwalk_del_inobt(tp, &cur, &agi_bp, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  * We experimentally determined that the reduction in ioctl call overhead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  * diminishes when userspace asks for more than 2048 inodes, so we'll cap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  * prefetch at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) #define IWALK_MAX_INODE_PREFETCH	(2048U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  * Given the number of inodes to prefetch, set the number of inobt records that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  * we cache in memory, which controls the number of inodes we try to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)  * ahead.  Set the maximum if @inodes == 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) xfs_iwalk_prefetch(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	unsigned int		inodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	unsigned int		inobt_records;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	 * If the caller didn't tell us the number of inodes they wanted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	 * assume the maximum prefetch possible for best performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	 * Otherwise, cap prefetch at that maximum so that we don't start an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	 * absurd amount of prefetch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	if (inodes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		inodes = IWALK_MAX_INODE_PREFETCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	inodes = min(inodes, IWALK_MAX_INODE_PREFETCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	/* Round the inode count up to a full chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	inodes = round_up(inodes, XFS_INODES_PER_CHUNK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * In order to convert the number of inodes to prefetch into an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 * estimate of the number of inobt records to cache, we require a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	 * conversion factor that reflects our expectations of the average
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	 * loading factor of an inode chunk.  Based on data gathered, most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	 * (but not all) filesystems manage to keep the inode chunks totally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	 * full, so we'll underestimate slightly so that our readahead will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	 * still deliver the performance we want on aging filesystems:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	 * inobt = inodes / (INODES_PER_CHUNK * (4 / 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	 * The funny math is to avoid integer division.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	inobt_records = (inodes * 5) / (4 * XFS_INODES_PER_CHUNK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	 * Allocate enough space to prefetch at least two inobt records so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	 * we can cache both the record where the iwalk started and the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	 * record.  This simplifies the AG inode walk loop setup code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	return max(inobt_records, 2U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)  * Walk all inodes in the filesystem starting from @startino.  The @iwalk_fn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  * will be called for each allocated inode, being passed the inode's number and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * @data.  @max_prefetch controls how many inobt records' worth of inodes we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  * try to readahead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) xfs_iwalk(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	xfs_ino_t		startino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	unsigned int		flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	xfs_iwalk_fn		iwalk_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	unsigned int		inode_records,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	void			*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	struct xfs_iwalk_ag	iwag = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		.mp		= mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		.tp		= tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		.iwalk_fn	= iwalk_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		.data		= data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		.startino	= startino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		.sz_recs	= xfs_iwalk_prefetch(inode_records),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		.trim_start	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		.skip_empty	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		.pwork		= XFS_PWORK_SINGLE_THREADED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		.lastino	= NULLFSINO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	ASSERT(agno < mp->m_sb.sb_agcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	error = xfs_iwalk_alloc(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	for (; agno < mp->m_sb.sb_agcount; agno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		error = xfs_iwalk_ag(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		iwag.startino = XFS_AGINO_TO_INO(mp, agno + 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		if (flags & XFS_INOBT_WALK_SAME_AG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	xfs_iwalk_free(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /* Run per-thread iwalk work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) xfs_iwalk_ag_work(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	struct xfs_pwork	*pwork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	struct xfs_iwalk_ag	*iwag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	int			error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	iwag = container_of(pwork, struct xfs_iwalk_ag, pwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	if (xfs_pwork_want_abort(pwork))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	error = xfs_iwalk_alloc(iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	error = xfs_iwalk_ag(iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	xfs_iwalk_free(iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	kmem_free(iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  * Walk all the inodes in the filesystem using multiple threads to process each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)  * AG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) xfs_iwalk_threaded(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	xfs_ino_t		startino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	unsigned int		flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	xfs_iwalk_fn		iwalk_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	unsigned int		inode_records,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	bool			polled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	void			*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	struct xfs_pwork_ctl	pctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	unsigned int		nr_threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	ASSERT(agno < mp->m_sb.sb_agcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	ASSERT(!(flags & ~XFS_IWALK_FLAGS_ALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	nr_threads = xfs_pwork_guess_datadev_parallelism(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	error = xfs_pwork_init(mp, &pctl, xfs_iwalk_ag_work, "xfs_iwalk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			nr_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	for (; agno < mp->m_sb.sb_agcount; agno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		struct xfs_iwalk_ag	*iwag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		if (xfs_pwork_ctl_want_abort(&pctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		iwag = kmem_zalloc(sizeof(struct xfs_iwalk_ag), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		iwag->mp = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		iwag->iwalk_fn = iwalk_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		iwag->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		iwag->startino = startino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		iwag->sz_recs = xfs_iwalk_prefetch(inode_records);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		iwag->lastino = NULLFSINO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		xfs_pwork_queue(&pctl, &iwag->pwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		startino = XFS_AGINO_TO_INO(mp, agno + 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		if (flags & XFS_INOBT_WALK_SAME_AG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	if (polled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		xfs_pwork_poll(&pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	return xfs_pwork_destroy(&pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  * Allow callers to cache up to a page's worth of inobt records.  This reflects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  * the existing inumbers prefetching behavior.  Since the inobt walk does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)  * itself do anything with the inobt records, we can set a fairly high limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) #define MAX_INOBT_WALK_PREFETCH	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	(PAGE_SIZE / sizeof(struct xfs_inobt_rec_incore))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)  * Given the number of records that the user wanted, set the number of inobt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  * records that we buffer in memory.  Set the maximum if @inobt_records == 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) xfs_inobt_walk_prefetch(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	unsigned int		inobt_records)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	 * If the caller didn't tell us the number of inobt records they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	 * wanted, assume the maximum prefetch possible for best performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (inobt_records == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		inobt_records = MAX_INOBT_WALK_PREFETCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	 * Allocate enough space to prefetch at least two inobt records so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	 * we can cache both the record where the iwalk started and the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	 * record.  This simplifies the AG inode walk loop setup code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	inobt_records = max(inobt_records, 2U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	 * Cap prefetch at that maximum so that we don't use an absurd amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	 * of memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	return min_t(unsigned int, inobt_records, MAX_INOBT_WALK_PREFETCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)  * Walk all inode btree records in the filesystem starting from @startino.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * @inobt_walk_fn will be called for each btree record, being passed the incore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  * record and @data.  @max_prefetch controls how many inobt records we try to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  * cache ahead of time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) xfs_inobt_walk(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	xfs_ino_t		startino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	unsigned int		flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	xfs_inobt_walk_fn	inobt_walk_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	unsigned int		inobt_records,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	void			*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	struct xfs_iwalk_ag	iwag = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		.mp		= mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		.tp		= tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		.inobt_walk_fn	= inobt_walk_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		.data		= data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		.startino	= startino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		.sz_recs	= xfs_inobt_walk_prefetch(inobt_records),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		.pwork		= XFS_PWORK_SINGLE_THREADED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		.lastino	= NULLFSINO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	xfs_agnumber_t		agno = XFS_INO_TO_AGNO(mp, startino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	ASSERT(agno < mp->m_sb.sb_agcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	ASSERT(!(flags & ~XFS_INOBT_WALK_FLAGS_ALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	error = xfs_iwalk_alloc(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	for (; agno < mp->m_sb.sb_agcount; agno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		error = xfs_iwalk_ag(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		iwag.startino = XFS_AGINO_TO_INO(mp, agno + 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		if (flags & XFS_INOBT_WALK_SAME_AG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	xfs_iwalk_free(&iwag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }