1b16817b6SDave Chinner /* SPDX-License-Identifier: GPL-2.0 */ 2b16817b6SDave Chinner /* 3b16817b6SDave Chinner * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4b16817b6SDave Chinner * Copyright (c) 2018 Red Hat, Inc. 5b16817b6SDave Chinner * All rights reserved. 6b16817b6SDave Chinner */ 7b16817b6SDave Chinner 8b16817b6SDave Chinner #include "xfs.h" 9b16817b6SDave Chinner #include "xfs_fs.h" 10b16817b6SDave Chinner #include "xfs_shared.h" 11b16817b6SDave Chinner #include "xfs_format.h" 12b16817b6SDave Chinner #include "xfs_trans_resv.h" 13b16817b6SDave Chinner #include "xfs_sb.h" 14b16817b6SDave Chinner #include "xfs_mount.h" 15b16817b6SDave Chinner #include "xfs_btree.h" 16b16817b6SDave Chinner #include "xfs_alloc_btree.h" 17b16817b6SDave Chinner #include "xfs_rmap_btree.h" 18b16817b6SDave Chinner #include "xfs_alloc.h" 19b16817b6SDave Chinner #include "xfs_rmap.h" 20b16817b6SDave Chinner #include "xfs_ag.h" 21b16817b6SDave Chinner 22b16817b6SDave Chinner static struct xfs_buf * 23b16817b6SDave Chinner xfs_get_aghdr_buf( 24b16817b6SDave Chinner struct xfs_mount *mp, 25b16817b6SDave Chinner xfs_daddr_t blkno, 26b16817b6SDave Chinner size_t numblks, 27b16817b6SDave Chinner int flags, 28b16817b6SDave Chinner const struct xfs_buf_ops *ops) 29b16817b6SDave Chinner { 30b16817b6SDave Chinner struct xfs_buf *bp; 31b16817b6SDave Chinner 32b16817b6SDave Chinner bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); 33b16817b6SDave Chinner if (!bp) 34b16817b6SDave Chinner return NULL; 35b16817b6SDave Chinner 36b16817b6SDave Chinner xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); 37b16817b6SDave Chinner bp->b_bn = blkno; 38b16817b6SDave Chinner bp->b_maps[0].bm_bn = blkno; 39b16817b6SDave Chinner bp->b_ops = ops; 40b16817b6SDave Chinner 41b16817b6SDave Chinner return bp; 42b16817b6SDave Chinner } 43b16817b6SDave Chinner 44b16817b6SDave Chinner /* 45b16817b6SDave Chinner * Generic btree root block init function 46b16817b6SDave Chinner */ 47b16817b6SDave Chinner static void 48b16817b6SDave Chinner xfs_btroot_init( 49b16817b6SDave Chinner struct xfs_mount *mp, 50b16817b6SDave Chinner struct xfs_buf *bp, 51b16817b6SDave Chinner struct aghdr_init_data *id) 52b16817b6SDave Chinner { 53b16817b6SDave Chinner xfs_btree_init_block(mp, bp, id->type, 0, 0, id->agno, 0); 54b16817b6SDave Chinner } 55b16817b6SDave Chinner 56b16817b6SDave Chinner /* 57b16817b6SDave Chinner * Alloc btree root block init functions 58b16817b6SDave Chinner */ 59b16817b6SDave Chinner static void 60b16817b6SDave Chinner xfs_bnoroot_init( 61b16817b6SDave Chinner struct xfs_mount *mp, 62b16817b6SDave Chinner struct xfs_buf *bp, 63b16817b6SDave Chinner struct aghdr_init_data *id) 64b16817b6SDave Chinner { 65b16817b6SDave Chinner struct xfs_alloc_rec *arec; 66b16817b6SDave Chinner 67b16817b6SDave Chinner xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno, 0); 68b16817b6SDave Chinner arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); 69b16817b6SDave Chinner arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks); 70b16817b6SDave Chinner arec->ar_blockcount = cpu_to_be32(id->agsize - 71b16817b6SDave Chinner be32_to_cpu(arec->ar_startblock)); 72b16817b6SDave Chinner } 73b16817b6SDave Chinner 74b16817b6SDave Chinner static void 75b16817b6SDave Chinner xfs_cntroot_init( 76b16817b6SDave Chinner struct xfs_mount *mp, 77b16817b6SDave Chinner struct xfs_buf *bp, 78b16817b6SDave Chinner struct aghdr_init_data *id) 79b16817b6SDave Chinner { 80b16817b6SDave Chinner struct xfs_alloc_rec *arec; 81b16817b6SDave Chinner 82b16817b6SDave Chinner xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno, 0); 83b16817b6SDave Chinner arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); 84b16817b6SDave Chinner arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks); 85b16817b6SDave Chinner arec->ar_blockcount = cpu_to_be32(id->agsize - 86b16817b6SDave Chinner be32_to_cpu(arec->ar_startblock)); 87b16817b6SDave Chinner } 88b16817b6SDave Chinner 89b16817b6SDave Chinner /* 90b16817b6SDave Chinner * Reverse map root block init 91b16817b6SDave Chinner */ 92b16817b6SDave Chinner static void 93b16817b6SDave Chinner xfs_rmaproot_init( 94b16817b6SDave Chinner struct xfs_mount *mp, 95b16817b6SDave Chinner struct xfs_buf *bp, 96b16817b6SDave Chinner struct aghdr_init_data *id) 97b16817b6SDave Chinner { 98b16817b6SDave Chinner struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 99b16817b6SDave Chinner struct xfs_rmap_rec *rrec; 100b16817b6SDave Chinner 101b16817b6SDave Chinner xfs_btree_init_block(mp, bp, XFS_BTNUM_RMAP, 0, 4, id->agno, 0); 102b16817b6SDave Chinner 103b16817b6SDave Chinner /* 104b16817b6SDave Chinner * mark the AG header regions as static metadata The BNO 105b16817b6SDave Chinner * btree block is the first block after the headers, so 106b16817b6SDave Chinner * it's location defines the size of region the static 107b16817b6SDave Chinner * metadata consumes. 108b16817b6SDave Chinner * 109b16817b6SDave Chinner * Note: unlike mkfs, we never have to account for log 110b16817b6SDave Chinner * space when growing the data regions 111b16817b6SDave Chinner */ 112b16817b6SDave Chinner rrec = XFS_RMAP_REC_ADDR(block, 1); 113b16817b6SDave Chinner rrec->rm_startblock = 0; 114b16817b6SDave Chinner rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp)); 115b16817b6SDave Chinner rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS); 116b16817b6SDave Chinner rrec->rm_offset = 0; 117b16817b6SDave Chinner 118b16817b6SDave Chinner /* account freespace btree root blocks */ 119b16817b6SDave Chinner rrec = XFS_RMAP_REC_ADDR(block, 2); 120b16817b6SDave Chinner rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp)); 121b16817b6SDave Chinner rrec->rm_blockcount = cpu_to_be32(2); 122b16817b6SDave Chinner rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); 123b16817b6SDave Chinner rrec->rm_offset = 0; 124b16817b6SDave Chinner 125b16817b6SDave Chinner /* account inode btree root blocks */ 126b16817b6SDave Chinner rrec = XFS_RMAP_REC_ADDR(block, 3); 127b16817b6SDave Chinner rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp)); 128b16817b6SDave Chinner rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) - 129b16817b6SDave Chinner XFS_IBT_BLOCK(mp)); 130b16817b6SDave Chinner rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT); 131b16817b6SDave Chinner rrec->rm_offset = 0; 132b16817b6SDave Chinner 133b16817b6SDave Chinner /* account for rmap btree root */ 134b16817b6SDave Chinner rrec = XFS_RMAP_REC_ADDR(block, 4); 135b16817b6SDave Chinner rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp)); 136b16817b6SDave Chinner rrec->rm_blockcount = cpu_to_be32(1); 137b16817b6SDave Chinner rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); 138b16817b6SDave Chinner rrec->rm_offset = 0; 139b16817b6SDave Chinner 140b16817b6SDave Chinner /* account for refc btree root */ 141b16817b6SDave Chinner if (xfs_sb_version_hasreflink(&mp->m_sb)) { 142b16817b6SDave Chinner rrec = XFS_RMAP_REC_ADDR(block, 5); 143b16817b6SDave Chinner rrec->rm_startblock = cpu_to_be32(xfs_refc_block(mp)); 144b16817b6SDave Chinner rrec->rm_blockcount = cpu_to_be32(1); 145b16817b6SDave Chinner rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC); 146b16817b6SDave Chinner rrec->rm_offset = 0; 147b16817b6SDave Chinner be16_add_cpu(&block->bb_numrecs, 1); 148b16817b6SDave Chinner } 149b16817b6SDave Chinner } 150b16817b6SDave Chinner 151b16817b6SDave Chinner /* 152b16817b6SDave Chinner * Initialise new secondary superblocks with the pre-grow geometry, but mark 153b16817b6SDave Chinner * them as "in progress" so we know they haven't yet been activated. This will 154b16817b6SDave Chinner * get cleared when the update with the new geometry information is done after 155b16817b6SDave Chinner * changes to the primary are committed. This isn't strictly necessary, but we 156b16817b6SDave Chinner * get it for free with the delayed buffer write lists and it means we can tell 157b16817b6SDave Chinner * if a grow operation didn't complete properly after the fact. 158b16817b6SDave Chinner */ 159b16817b6SDave Chinner static void 160b16817b6SDave Chinner xfs_sbblock_init( 161b16817b6SDave Chinner struct xfs_mount *mp, 162b16817b6SDave Chinner struct xfs_buf *bp, 163b16817b6SDave Chinner struct aghdr_init_data *id) 164b16817b6SDave Chinner { 165b16817b6SDave Chinner struct xfs_dsb *dsb = XFS_BUF_TO_SBP(bp); 166b16817b6SDave Chinner 167b16817b6SDave Chinner xfs_sb_to_disk(dsb, &mp->m_sb); 168b16817b6SDave Chinner dsb->sb_inprogress = 1; 169b16817b6SDave Chinner } 170b16817b6SDave Chinner 171b16817b6SDave Chinner static void 172b16817b6SDave Chinner xfs_agfblock_init( 173b16817b6SDave Chinner struct xfs_mount *mp, 174b16817b6SDave Chinner struct xfs_buf *bp, 175b16817b6SDave Chinner struct aghdr_init_data *id) 176b16817b6SDave Chinner { 177b16817b6SDave Chinner struct xfs_agf *agf = XFS_BUF_TO_AGF(bp); 178b16817b6SDave Chinner xfs_extlen_t tmpsize; 179b16817b6SDave Chinner 180b16817b6SDave Chinner agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); 181b16817b6SDave Chinner agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION); 182b16817b6SDave Chinner agf->agf_seqno = cpu_to_be32(id->agno); 183b16817b6SDave Chinner agf->agf_length = cpu_to_be32(id->agsize); 184b16817b6SDave Chinner agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp)); 185b16817b6SDave Chinner agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp)); 186b16817b6SDave Chinner agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1); 187b16817b6SDave Chinner agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1); 188b16817b6SDave Chinner if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { 189b16817b6SDave Chinner agf->agf_roots[XFS_BTNUM_RMAPi] = 190b16817b6SDave Chinner cpu_to_be32(XFS_RMAP_BLOCK(mp)); 191b16817b6SDave Chinner agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); 192b16817b6SDave Chinner agf->agf_rmap_blocks = cpu_to_be32(1); 193b16817b6SDave Chinner } 194b16817b6SDave Chinner 195b16817b6SDave Chinner agf->agf_flfirst = cpu_to_be32(1); 196b16817b6SDave Chinner agf->agf_fllast = 0; 197b16817b6SDave Chinner agf->agf_flcount = 0; 198b16817b6SDave Chinner tmpsize = id->agsize - mp->m_ag_prealloc_blocks; 199b16817b6SDave Chinner agf->agf_freeblks = cpu_to_be32(tmpsize); 200b16817b6SDave Chinner agf->agf_longest = cpu_to_be32(tmpsize); 201b16817b6SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb)) 202b16817b6SDave Chinner uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); 203b16817b6SDave Chinner if (xfs_sb_version_hasreflink(&mp->m_sb)) { 204b16817b6SDave Chinner agf->agf_refcount_root = cpu_to_be32( 205b16817b6SDave Chinner xfs_refc_block(mp)); 206b16817b6SDave Chinner agf->agf_refcount_level = cpu_to_be32(1); 207b16817b6SDave Chinner agf->agf_refcount_blocks = cpu_to_be32(1); 208b16817b6SDave Chinner } 209b16817b6SDave Chinner } 210b16817b6SDave Chinner 211b16817b6SDave Chinner static void 212b16817b6SDave Chinner xfs_agflblock_init( 213b16817b6SDave Chinner struct xfs_mount *mp, 214b16817b6SDave Chinner struct xfs_buf *bp, 215b16817b6SDave Chinner struct aghdr_init_data *id) 216b16817b6SDave Chinner { 217b16817b6SDave Chinner struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp); 218b16817b6SDave Chinner __be32 *agfl_bno; 219b16817b6SDave Chinner int bucket; 220b16817b6SDave Chinner 221b16817b6SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb)) { 222b16817b6SDave Chinner agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC); 223b16817b6SDave Chinner agfl->agfl_seqno = cpu_to_be32(id->agno); 224b16817b6SDave Chinner uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid); 225b16817b6SDave Chinner } 226b16817b6SDave Chinner 227b16817b6SDave Chinner agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp); 228b16817b6SDave Chinner for (bucket = 0; bucket < xfs_agfl_size(mp); bucket++) 229b16817b6SDave Chinner agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); 230b16817b6SDave Chinner } 231b16817b6SDave Chinner 232b16817b6SDave Chinner static void 233b16817b6SDave Chinner xfs_agiblock_init( 234b16817b6SDave Chinner struct xfs_mount *mp, 235b16817b6SDave Chinner struct xfs_buf *bp, 236b16817b6SDave Chinner struct aghdr_init_data *id) 237b16817b6SDave Chinner { 238b16817b6SDave Chinner struct xfs_agi *agi = XFS_BUF_TO_AGI(bp); 239b16817b6SDave Chinner int bucket; 240b16817b6SDave Chinner 241b16817b6SDave Chinner agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); 242b16817b6SDave Chinner agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION); 243b16817b6SDave Chinner agi->agi_seqno = cpu_to_be32(id->agno); 244b16817b6SDave Chinner agi->agi_length = cpu_to_be32(id->agsize); 245b16817b6SDave Chinner agi->agi_count = 0; 246b16817b6SDave Chinner agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp)); 247b16817b6SDave Chinner agi->agi_level = cpu_to_be32(1); 248b16817b6SDave Chinner agi->agi_freecount = 0; 249b16817b6SDave Chinner agi->agi_newino = cpu_to_be32(NULLAGINO); 250b16817b6SDave Chinner agi->agi_dirino = cpu_to_be32(NULLAGINO); 251b16817b6SDave Chinner if (xfs_sb_version_hascrc(&mp->m_sb)) 252b16817b6SDave Chinner uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid); 253b16817b6SDave Chinner if (xfs_sb_version_hasfinobt(&mp->m_sb)) { 254b16817b6SDave Chinner agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp)); 255b16817b6SDave Chinner agi->agi_free_level = cpu_to_be32(1); 256b16817b6SDave Chinner } 257b16817b6SDave Chinner for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) 258b16817b6SDave Chinner agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); 259b16817b6SDave Chinner } 260b16817b6SDave Chinner 261b16817b6SDave Chinner typedef void (*aghdr_init_work_f)(struct xfs_mount *mp, struct xfs_buf *bp, 262b16817b6SDave Chinner struct aghdr_init_data *id); 263b16817b6SDave Chinner static int 264b16817b6SDave Chinner xfs_ag_init_hdr( 265b16817b6SDave Chinner struct xfs_mount *mp, 266b16817b6SDave Chinner struct aghdr_init_data *id, 267b16817b6SDave Chinner aghdr_init_work_f work, 268b16817b6SDave Chinner const struct xfs_buf_ops *ops) 269b16817b6SDave Chinner 270b16817b6SDave Chinner { 271b16817b6SDave Chinner struct xfs_buf *bp; 272b16817b6SDave Chinner 273b16817b6SDave Chinner bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, 0, ops); 274b16817b6SDave Chinner if (!bp) 275b16817b6SDave Chinner return -ENOMEM; 276b16817b6SDave Chinner 277b16817b6SDave Chinner (*work)(mp, bp, id); 278b16817b6SDave Chinner 279b16817b6SDave Chinner xfs_buf_delwri_queue(bp, &id->buffer_list); 280b16817b6SDave Chinner xfs_buf_relse(bp); 281b16817b6SDave Chinner return 0; 282b16817b6SDave Chinner } 283b16817b6SDave Chinner 284b16817b6SDave Chinner struct xfs_aghdr_grow_data { 285b16817b6SDave Chinner xfs_daddr_t daddr; 286b16817b6SDave Chinner size_t numblks; 287b16817b6SDave Chinner const struct xfs_buf_ops *ops; 288b16817b6SDave Chinner aghdr_init_work_f work; 289b16817b6SDave Chinner xfs_btnum_t type; 290b16817b6SDave Chinner bool need_init; 291b16817b6SDave Chinner }; 292b16817b6SDave Chinner 293b16817b6SDave Chinner /* 294b16817b6SDave Chinner * Prepare new AG headers to be written to disk. We use uncached buffers here, 295b16817b6SDave Chinner * as it is assumed these new AG headers are currently beyond the currently 296b16817b6SDave Chinner * valid filesystem address space. Using cached buffers would trip over EOFS 297b16817b6SDave Chinner * corruption detection alogrithms in the buffer cache lookup routines. 298b16817b6SDave Chinner * 299b16817b6SDave Chinner * This is a non-transactional function, but the prepared buffers are added to a 300b16817b6SDave Chinner * delayed write buffer list supplied by the caller so they can submit them to 301b16817b6SDave Chinner * disk and wait on them as required. 302b16817b6SDave Chinner */ 303b16817b6SDave Chinner int 304b16817b6SDave Chinner xfs_ag_init_headers( 305b16817b6SDave Chinner struct xfs_mount *mp, 306b16817b6SDave Chinner struct aghdr_init_data *id) 307b16817b6SDave Chinner 308b16817b6SDave Chinner { 309b16817b6SDave Chinner struct xfs_aghdr_grow_data aghdr_data[] = { 310b16817b6SDave Chinner { /* SB */ 311b16817b6SDave Chinner .daddr = XFS_AG_DADDR(mp, id->agno, XFS_SB_DADDR), 312b16817b6SDave Chinner .numblks = XFS_FSS_TO_BB(mp, 1), 313b16817b6SDave Chinner .ops = &xfs_sb_buf_ops, 314b16817b6SDave Chinner .work = &xfs_sbblock_init, 315b16817b6SDave Chinner .need_init = true 316b16817b6SDave Chinner }, 317b16817b6SDave Chinner { /* AGF */ 318b16817b6SDave Chinner .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGF_DADDR(mp)), 319b16817b6SDave Chinner .numblks = XFS_FSS_TO_BB(mp, 1), 320b16817b6SDave Chinner .ops = &xfs_agf_buf_ops, 321b16817b6SDave Chinner .work = &xfs_agfblock_init, 322b16817b6SDave Chinner .need_init = true 323b16817b6SDave Chinner }, 324b16817b6SDave Chinner { /* AGFL */ 325b16817b6SDave Chinner .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGFL_DADDR(mp)), 326b16817b6SDave Chinner .numblks = XFS_FSS_TO_BB(mp, 1), 327b16817b6SDave Chinner .ops = &xfs_agfl_buf_ops, 328b16817b6SDave Chinner .work = &xfs_agflblock_init, 329b16817b6SDave Chinner .need_init = true 330b16817b6SDave Chinner }, 331b16817b6SDave Chinner { /* AGI */ 332b16817b6SDave Chinner .daddr = XFS_AG_DADDR(mp, id->agno, XFS_AGI_DADDR(mp)), 333b16817b6SDave Chinner .numblks = XFS_FSS_TO_BB(mp, 1), 334b16817b6SDave Chinner .ops = &xfs_agi_buf_ops, 335b16817b6SDave Chinner .work = &xfs_agiblock_init, 336b16817b6SDave Chinner .need_init = true 337b16817b6SDave Chinner }, 338b16817b6SDave Chinner { /* BNO root block */ 339b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_BNO_BLOCK(mp)), 340b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 341b16817b6SDave Chinner .ops = &xfs_allocbt_buf_ops, 342b16817b6SDave Chinner .work = &xfs_bnoroot_init, 343b16817b6SDave Chinner .need_init = true 344b16817b6SDave Chinner }, 345b16817b6SDave Chinner { /* CNT root block */ 346b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_CNT_BLOCK(mp)), 347b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 348b16817b6SDave Chinner .ops = &xfs_allocbt_buf_ops, 349b16817b6SDave Chinner .work = &xfs_cntroot_init, 350b16817b6SDave Chinner .need_init = true 351b16817b6SDave Chinner }, 352b16817b6SDave Chinner { /* INO root block */ 353b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_IBT_BLOCK(mp)), 354b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 355b16817b6SDave Chinner .ops = &xfs_inobt_buf_ops, 356b16817b6SDave Chinner .work = &xfs_btroot_init, 357b16817b6SDave Chinner .type = XFS_BTNUM_INO, 358b16817b6SDave Chinner .need_init = true 359b16817b6SDave Chinner }, 360b16817b6SDave Chinner { /* FINO root block */ 361b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_FIBT_BLOCK(mp)), 362b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 363b16817b6SDave Chinner .ops = &xfs_inobt_buf_ops, 364b16817b6SDave Chinner .work = &xfs_btroot_init, 365b16817b6SDave Chinner .type = XFS_BTNUM_FINO, 366b16817b6SDave Chinner .need_init = xfs_sb_version_hasfinobt(&mp->m_sb) 367b16817b6SDave Chinner }, 368b16817b6SDave Chinner { /* RMAP root block */ 369b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, XFS_RMAP_BLOCK(mp)), 370b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 371b16817b6SDave Chinner .ops = &xfs_rmapbt_buf_ops, 372b16817b6SDave Chinner .work = &xfs_rmaproot_init, 373b16817b6SDave Chinner .need_init = xfs_sb_version_hasrmapbt(&mp->m_sb) 374b16817b6SDave Chinner }, 375b16817b6SDave Chinner { /* REFC root block */ 376b16817b6SDave Chinner .daddr = XFS_AGB_TO_DADDR(mp, id->agno, xfs_refc_block(mp)), 377b16817b6SDave Chinner .numblks = BTOBB(mp->m_sb.sb_blocksize), 378b16817b6SDave Chinner .ops = &xfs_refcountbt_buf_ops, 379b16817b6SDave Chinner .work = &xfs_btroot_init, 380b16817b6SDave Chinner .type = XFS_BTNUM_REFC, 381b16817b6SDave Chinner .need_init = xfs_sb_version_hasreflink(&mp->m_sb) 382b16817b6SDave Chinner }, 383b16817b6SDave Chinner { /* NULL terminating block */ 384b16817b6SDave Chinner .daddr = XFS_BUF_DADDR_NULL, 385b16817b6SDave Chinner } 386b16817b6SDave Chinner }; 387b16817b6SDave Chinner struct xfs_aghdr_grow_data *dp; 388b16817b6SDave Chinner int error = 0; 389b16817b6SDave Chinner 390b16817b6SDave Chinner /* Account for AG free space in new AG */ 391b16817b6SDave Chinner id->nfree += id->agsize - mp->m_ag_prealloc_blocks; 392b16817b6SDave Chinner for (dp = &aghdr_data[0]; dp->daddr != XFS_BUF_DADDR_NULL; dp++) { 393b16817b6SDave Chinner if (!dp->need_init) 394b16817b6SDave Chinner continue; 395b16817b6SDave Chinner 396b16817b6SDave Chinner id->daddr = dp->daddr; 397b16817b6SDave Chinner id->numblks = dp->numblks; 398b16817b6SDave Chinner id->type = dp->type; 399b16817b6SDave Chinner error = xfs_ag_init_hdr(mp, id, dp->work, dp->ops); 400b16817b6SDave Chinner if (error) 401b16817b6SDave Chinner break; 402b16817b6SDave Chinner } 403b16817b6SDave Chinner return error; 404b16817b6SDave Chinner } 405