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 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2018 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "xfs_bit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "xfs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "xfs_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "xfs_alloc_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "xfs_rmap_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "xfs_alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "xfs_ialloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "xfs_rmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "xfs_ag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "xfs_ag_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "xfs_health.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) xfs_get_aghdr_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	xfs_daddr_t		blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	size_t			numblks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct xfs_buf		**bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	const struct xfs_buf_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	error = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	bp->b_bn = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	bp->b_maps[0].bm_bn = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	bp->b_ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	*bpp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static inline bool is_log_ag(struct xfs_mount *mp, struct aghdr_init_data *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return mp->m_sb.sb_logstart > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	       id->agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * Generic btree root block init function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) xfs_btroot_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	xfs_btree_init_block(mp, bp, id->type, 0, 0, id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) /* Finish initializing a free space btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) xfs_freesp_init_recs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct xfs_alloc_rec	*arec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (is_log_ag(mp, id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		struct xfs_alloc_rec	*nrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		xfs_agblock_t		start = XFS_FSB_TO_AGBNO(mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 							mp->m_sb.sb_logstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		ASSERT(start >= mp->m_ag_prealloc_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		if (start != mp->m_ag_prealloc_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			 * Modify first record to pad stripe align of log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			arec->ar_blockcount = cpu_to_be32(start -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 						mp->m_ag_prealloc_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			nrec = arec + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			 * Insert second record at start of internal log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			 * which then gets trimmed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			nrec->ar_startblock = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 					be32_to_cpu(arec->ar_startblock) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 					be32_to_cpu(arec->ar_blockcount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			arec = nrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			be16_add_cpu(&block->bb_numrecs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		 * Change record start to after the internal log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		be32_add_cpu(&arec->ar_startblock, mp->m_sb.sb_logblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * Calculate the record block count and check for the case where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 * the log might have consumed all available space in the AG. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 * so, reset the record count to 0 to avoid exposure of an invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	 * record start block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	arec->ar_blockcount = cpu_to_be32(id->agsize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 					  be32_to_cpu(arec->ar_startblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (!arec->ar_blockcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		block->bb_numrecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Alloc btree root block init functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) xfs_bnoroot_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	xfs_freesp_init_recs(mp, bp, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) xfs_cntroot_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	xfs_freesp_init_recs(mp, bp, id);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * Reverse map root block init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) xfs_rmaproot_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct xfs_rmap_rec	*rrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	xfs_btree_init_block(mp, bp, XFS_BTNUM_RMAP, 0, 4, id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	 * mark the AG header regions as static metadata The BNO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	 * btree block is the first block after the headers, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	 * it's location defines the size of region the static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	 * metadata consumes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	 * Note: unlike mkfs, we never have to account for log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 * space when growing the data regions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	rrec = XFS_RMAP_REC_ADDR(block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	rrec->rm_startblock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	/* account freespace btree root blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	rrec = XFS_RMAP_REC_ADDR(block, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	rrec->rm_blockcount = cpu_to_be32(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/* account inode btree root blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	rrec = XFS_RMAP_REC_ADDR(block, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 					  XFS_IBT_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	/* account for rmap btree root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	rrec = XFS_RMAP_REC_ADDR(block, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	rrec->rm_blockcount = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/* account for refc btree root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		rrec = XFS_RMAP_REC_ADDR(block, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		rrec->rm_startblock = cpu_to_be32(xfs_refc_block(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		rrec->rm_blockcount = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		be16_add_cpu(&block->bb_numrecs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	/* account for the log space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (is_log_ag(mp, id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		rrec = XFS_RMAP_REC_ADDR(block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				be16_to_cpu(block->bb_numrecs) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		rrec->rm_startblock = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		rrec->rm_blockcount = cpu_to_be32(mp->m_sb.sb_logblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		rrec->rm_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		be16_add_cpu(&block->bb_numrecs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	}
^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)  * Initialise new secondary superblocks with the pre-grow geometry, but mark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * them as "in progress" so we know they haven't yet been activated. This will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * get cleared when the update with the new geometry information is done after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * changes to the primary are committed. This isn't strictly necessary, but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * get it for free with the delayed buffer write lists and it means we can tell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * if a grow operation didn't complete properly after the fact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) xfs_sbblock_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct xfs_dsb		*dsb = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	xfs_sb_to_disk(dsb, &mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	dsb->sb_inprogress = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) xfs_agfblock_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	struct xfs_agf		*agf = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	xfs_extlen_t		tmpsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	agf->agf_seqno = cpu_to_be32(id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	agf->agf_length = cpu_to_be32(id->agsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		agf->agf_roots[XFS_BTNUM_RMAPi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					cpu_to_be32(XFS_RMAP_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		agf->agf_rmap_blocks = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	agf->agf_flfirst = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	agf->agf_fllast = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	agf->agf_flcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	tmpsize = id->agsize - mp->m_ag_prealloc_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	agf->agf_freeblks = cpu_to_be32(tmpsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	agf->agf_longest = cpu_to_be32(tmpsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		agf->agf_refcount_root = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				xfs_refc_block(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		agf->agf_refcount_level = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		agf->agf_refcount_blocks = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (is_log_ag(mp, id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		int64_t	logblocks = mp->m_sb.sb_logblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		be32_add_cpu(&agf->agf_freeblks, -logblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		agf->agf_longest = cpu_to_be32(id->agsize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart) - logblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) xfs_agflblock_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	struct xfs_agfl		*agfl = XFS_BUF_TO_AGFL(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	__be32			*agfl_bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int			bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		agfl->agfl_seqno = cpu_to_be32(id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	agfl_bno = xfs_buf_to_agfl_bno(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	for (bucket = 0; bucket < xfs_agfl_size(mp); bucket++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) xfs_agiblock_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	struct xfs_agi		*agi = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	int			bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	agi->agi_seqno = cpu_to_be32(id->agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	agi->agi_length = cpu_to_be32(id->agsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	agi->agi_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	agi->agi_level = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	agi->agi_freecount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	agi->agi_newino = cpu_to_be32(NULLAGINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	agi->agi_dirino = cpu_to_be32(NULLAGINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		agi->agi_free_level = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		agi->agi_iblocks = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		if (xfs_sb_version_hasfinobt(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			agi->agi_fblocks = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) typedef void (*aghdr_init_work_f)(struct xfs_mount *mp, struct xfs_buf *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				  struct aghdr_init_data *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) xfs_ag_init_hdr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct aghdr_init_data	*id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	aghdr_init_work_f	work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	const struct xfs_buf_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	error = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, &bp, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	(*work)(mp, bp, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	xfs_buf_delwri_queue(bp, &id->buffer_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	xfs_buf_relse(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct xfs_aghdr_grow_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	xfs_daddr_t		daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	size_t			numblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	const struct xfs_buf_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	aghdr_init_work_f	work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	xfs_btnum_t		type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	bool			need_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  * Prepare new AG headers to be written to disk. We use uncached buffers here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  * as it is assumed these new AG headers are currently beyond the currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  * valid filesystem address space. Using cached buffers would trip over EOFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  * corruption detection alogrithms in the buffer cache lookup routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * This is a non-transactional function, but the prepared buffers are added to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * delayed write buffer list supplied by the caller so they can submit them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  * disk and wait on them as required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) xfs_ag_init_headers(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	struct aghdr_init_data	*id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	struct xfs_aghdr_grow_data aghdr_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	{ /* SB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		.daddr = XFS_AG_DADDR(mp, id->agno, XFS_SB_DADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		.numblks = XFS_FSS_TO_BB(mp, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		.ops = &xfs_sb_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		.work = &xfs_sbblock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	{ /* AGF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		.daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGF_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		.numblks = XFS_FSS_TO_BB(mp, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		.ops = &xfs_agf_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		.work = &xfs_agfblock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	{ /* AGFL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		.daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGFL_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		.numblks = XFS_FSS_TO_BB(mp, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		.ops = &xfs_agfl_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		.work = &xfs_agflblock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	{ /* AGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		.daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGI_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		.numblks = XFS_FSS_TO_BB(mp, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		.ops = &xfs_agi_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		.work = &xfs_agiblock_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	{ /* BNO root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_BNO_BLOCK(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		.ops = &xfs_bnobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		.work = &xfs_bnoroot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	{ /* CNT root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_CNT_BLOCK(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		.ops = &xfs_cntbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		.work = &xfs_cntroot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	{ /* INO root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_IBT_BLOCK(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		.ops = &xfs_inobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		.work = &xfs_btroot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		.type = XFS_BTNUM_INO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		.need_init = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	{ /* FINO root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_FIBT_BLOCK(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		.ops = &xfs_finobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		.work = &xfs_btroot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		.type = XFS_BTNUM_FINO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		.need_init =  xfs_sb_version_hasfinobt(&mp->m_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	{ /* RMAP root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_RMAP_BLOCK(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		.ops = &xfs_rmapbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		.work = &xfs_rmaproot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		.need_init = xfs_sb_version_hasrmapbt(&mp->m_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	{ /* REFC root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		.daddr = XFS_AGB_TO_DADDR(mp, id->agno, xfs_refc_block(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		.numblks = BTOBB(mp->m_sb.sb_blocksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		.ops = &xfs_refcountbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		.work = &xfs_btroot_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		.type = XFS_BTNUM_REFC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		.need_init = xfs_sb_version_hasreflink(&mp->m_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	{ /* NULL terminating block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		.daddr = XFS_BUF_DADDR_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	struct  xfs_aghdr_grow_data *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	int			error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	/* Account for AG free space in new AG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	id->nfree += id->agsize - mp->m_ag_prealloc_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	for (dp = &aghdr_data[0]; dp->daddr != XFS_BUF_DADDR_NULL; dp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		if (!dp->need_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		id->daddr = dp->daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		id->numblks = dp->numblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		id->type = dp->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		error = xfs_ag_init_hdr(mp, id, dp->work, dp->ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)  * Extent the AG indicated by the @id by the length passed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) xfs_ag_extend_space(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	struct xfs_trans	*tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	struct aghdr_init_data	*id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	xfs_extlen_t		len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	struct xfs_agi		*agi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct xfs_agf		*agf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	 * Change the agi length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	error = xfs_ialloc_read_agi(mp, tp, id->agno, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	agi = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	be32_add_cpu(&agi->agi_length, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	ASSERT(id->agno == mp->m_sb.sb_agcount - 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	       be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	 * Change agf length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	error = xfs_alloc_read_agf(mp, tp, id->agno, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	agf = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	be32_add_cpu(&agf->agf_length, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	ASSERT(agf->agf_length == agi->agi_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	 * Free the new space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	 * XFS_RMAP_OINFO_SKIP_UPDATE is used here to tell the rmap btree that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	 * this doesn't actually exist in the rmap btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	error = xfs_rmap_free(tp, bp, id->agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 				be32_to_cpu(agf->agf_length) - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 				len, &XFS_RMAP_OINFO_SKIP_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	return  xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 					be32_to_cpu(agf->agf_length) - len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				len, &XFS_RMAP_OINFO_SKIP_UPDATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 				XFS_AG_RESV_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* Retrieve AG geometry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) xfs_ag_get_geometry(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	xfs_agnumber_t		agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	struct xfs_ag_geometry	*ageo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct xfs_buf		*agi_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	struct xfs_buf		*agf_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	struct xfs_agi		*agi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	struct xfs_agf		*agf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	struct xfs_perag	*pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	unsigned int		freeblks;
^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) 	if (agno >= mp->m_sb.sb_agcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	/* Lock the AG headers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	error = xfs_ialloc_read_agi(mp, NULL, agno, &agi_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		goto out_agi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	pag = agi_bp->b_pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	/* Fill out form. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	memset(ageo, 0, sizeof(*ageo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	ageo->ag_number = agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	agi = agi_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	ageo->ag_icount = be32_to_cpu(agi->agi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	ageo->ag_ifree = be32_to_cpu(agi->agi_freecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	ageo->ag_length = be32_to_cpu(agf->agf_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	freeblks = pag->pagf_freeblks +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		   pag->pagf_flcount +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		   pag->pagf_btreeblks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		   xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	ageo->ag_freeblks = freeblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	xfs_ag_geom_health(pag, ageo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	/* Release resources. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	xfs_buf_relse(agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) out_agi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	xfs_buf_relse(agi_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }