From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085387 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA13AC4332F for ; Sat, 31 Dec 2022 01:16:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236035AbiLaBQj (ORCPT ); Fri, 30 Dec 2022 20:16:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236041AbiLaBQj (ORCPT ); Fri, 30 Dec 2022 20:16:39 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FCACB865 for ; Fri, 30 Dec 2022 17:16:37 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B195AB81DF6 for ; Sat, 31 Dec 2022 01:16:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73FF8C433D2; Sat, 31 Dec 2022 01:16:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449394; bh=tIGJUn03JwAO5WbqTtgKIVxQiBGPBnw8O+ySltmThZg=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=VcuV/6B/DgUDD/Kfo3Ahq8ftockQozcx5AGDjo8WE3/M/22/lPkWWS3xot785kPDi HyFOu8BfYNDumVMOIA5UTRht7J+hbTVDChRpn1+7+HDcTeFLgdjGIkEyG0wRS8KRIg NraMPsKl662Z9/XO67Nz9edf1cXMVEwvEJ60jqN3bVY/d96UjtupLp5i7gatHFEXBY QSWbt/owOFzPY554Xs+d27+g4ZAYt0F7NiqxbZ4+tdeV2nzNplrnTtmm9S5KdzwSXB ayCfzKYsV5zGmsmSizvyB97iFRA01zuHtlAUek5K4+hA/YqrxiNLD4E5zt35H0xilj vPpwfdMP1pFiQ== Subject: [PATCH 01/14] xfs: replace shouty XFS_BM{BT,DR} macros From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865121.708933.3065643199388250003.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Replace all the shouty bmap btree and bmap disk root macros with actual functions, and fix a type handling error in the xattr code that the macros previously didn't care about. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr_leaf.c | 8 +- fs/xfs/libxfs/xfs_bmap.c | 40 ++++---- fs/xfs/libxfs/xfs_bmap_btree.c | 18 ++-- fs/xfs/libxfs/xfs_bmap_btree.h | 204 +++++++++++++++++++++++++++------------- fs/xfs/libxfs/xfs_inode_fork.c | 30 +++--- fs/xfs/libxfs/xfs_trans_resv.c | 2 fs/xfs/scrub/bmap_repair.c | 2 fs/xfs/scrub/inode_repair.c | 8 +- fs/xfs/xfs_xchgrange.c | 4 - 9 files changed, 196 insertions(+), 120 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 1f3febeccbe0..055290d37016 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -649,7 +649,7 @@ xfs_attr_shortform_bytesfit( */ if (!dp->i_forkoff && dp->i_df.if_bytes > xfs_default_attroffset(dp)) - dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); + dsize = xfs_bmdr_space_calc(MINDBTPTRS); break; case XFS_DINODE_FMT_BTREE: /* @@ -663,7 +663,7 @@ xfs_attr_shortform_bytesfit( return 0; return dp->i_forkoff; } - dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot); + dsize = xfs_bmap_bmdr_space(dp->i_df.if_broot); break; } @@ -671,11 +671,11 @@ xfs_attr_shortform_bytesfit( * A data fork btree root must have space for at least * MINDBTPTRS key/ptr pairs if the data fork is small or empty. */ - minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); + minforkoff = max_t(int64_t, dsize, xfs_bmdr_space_calc(MINDBTPTRS)); minforkoff = roundup(minforkoff, 8) >> 3; /* attr fork btree root can have at least this many key/ptr pairs */ - maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); + maxforkoff = XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS); maxforkoff = maxforkoff >> 3; /* rounded down */ if (offset >= maxforkoff) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 55fe8cda3d98..cbcb24df1a1e 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -78,9 +78,9 @@ xfs_bmap_compute_maxlevels( maxleafents = xfs_iext_max_nextents(xfs_has_large_extent_counts(mp), whichfork); if (whichfork == XFS_DATA_FORK) - sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); + sz = xfs_bmdr_space_calc(MINDBTPTRS); else - sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); + sz = xfs_bmdr_space_calc(MINABTPTRS); maxrootrecs = xfs_bmdr_maxrecs(sz, 0); minleafrecs = mp->m_bmap_dmnr[0]; @@ -101,8 +101,8 @@ xfs_bmap_compute_attr_offset( struct xfs_mount *mp) { if (mp->m_sb.sb_inodesize == 256) - return XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); - return XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); + return XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS); + return xfs_bmdr_space_calc(6 * MINABTPTRS); } STATIC int /* error */ @@ -275,7 +275,7 @@ xfs_check_block( prevp = NULL; for( i = 1; i <= xfs_btree_get_numrecs(block); i++) { dmxr = mp->m_bmap_dmxr[0]; - keyp = XFS_BMBT_KEY_ADDR(mp, block, i); + keyp = xfs_bmbt_key_addr(mp, block, i); if (prevp) { ASSERT(be64_to_cpu(prevp->br_startoff) < @@ -287,15 +287,15 @@ xfs_check_block( * Compare the block numbers to see if there are dups. */ if (root) - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz); + pp = xfs_bmap_broot_ptr_addr(mp, block, i, sz); else - pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr); + pp = xfs_bmbt_ptr_addr(mp, block, i, dmxr); for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) { if (root) - thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz); + thispa = xfs_bmap_broot_ptr_addr(mp, block, j, sz); else - thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); + thispa = xfs_bmbt_ptr_addr(mp, block, j, dmxr); if (*thispa == *pp) { xfs_warn(mp, "%s: thispa(%d) == pp(%d) %lld", __func__, j, i, @@ -350,7 +350,7 @@ xfs_bmap_check_leaf_extents( level = be16_to_cpu(block->bb_level); ASSERT(level > 0); xfs_check_block(block, mp, 1, ifp->if_broot_bytes); - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); + pp = xfs_bmap_broot_ptr_addr(mp, block, 1, ifp->if_broot_bytes); bno = be64_to_cpu(*pp); ASSERT(bno != NULLFSBLOCK); @@ -385,7 +385,7 @@ xfs_bmap_check_leaf_extents( */ xfs_check_block(block, mp, 0, 0); - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); + pp = xfs_bmbt_ptr_addr(mp, block, 1, mp->m_bmap_dmxr[1]); bno = be64_to_cpu(*pp); if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) { xfs_btree_mark_sick(cur); @@ -425,14 +425,14 @@ xfs_bmap_check_leaf_extents( * conform with the first entry in this one. */ - ep = XFS_BMBT_REC_ADDR(mp, block, 1); + ep = xfs_bmbt_rec_addr(mp, block, 1); if (i) { ASSERT(xfs_bmbt_disk_get_startoff(&last) + xfs_bmbt_disk_get_blockcount(&last) <= xfs_bmbt_disk_get_startoff(ep)); } for (j = 1; j < num_recs; j++) { - nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1); + nextp = xfs_bmbt_rec_addr(mp, block, j + 1); ASSERT(xfs_bmbt_disk_get_startoff(ep) + xfs_bmbt_disk_get_blockcount(ep) <= xfs_bmbt_disk_get_startoff(nextp)); @@ -567,7 +567,7 @@ xfs_bmap_btree_to_extents( ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); + pp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, ifp->if_broot_bytes); cbno = be64_to_cpu(*pp); #ifdef DEBUG if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) { @@ -701,7 +701,7 @@ xfs_bmap_extents_to_btree( for_each_xfs_iext(ifp, &icur, &rec) { if (isnullstartblock(rec.br_startblock)) continue; - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1 + cnt); + arp = xfs_bmbt_rec_addr(mp, ablock, 1 + cnt); xfs_bmbt_disk_set_all(arp, &rec); cnt++; } @@ -711,10 +711,10 @@ xfs_bmap_extents_to_btree( /* * Fill in the root key and pointer. */ - kp = XFS_BMBT_KEY_ADDR(mp, block, 1); - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); + kp = xfs_bmbt_key_addr(mp, block, 1); + arp = xfs_bmbt_rec_addr(mp, ablock, 1); kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, + pp = xfs_bmbt_ptr_addr(mp, block, 1, xfs_bmbt_get_maxrecs(cur, be16_to_cpu(block->bb_level))); *pp = cpu_to_be64(args.fsbno); @@ -888,7 +888,7 @@ xfs_bmap_add_attrfork_btree( mp = ip->i_mount; - if (XFS_BMAP_BMDR_SPACE(block) <= xfs_inode_data_fork_size(ip)) + if (xfs_bmap_bmdr_space(block) <= xfs_inode_data_fork_size(ip)) *flags |= XFS_ILOG_DBROOT; else { cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); @@ -1170,7 +1170,7 @@ xfs_iread_bmbt_block( } /* Copy records into the incore cache. */ - frp = XFS_BMBT_REC_ADDR(mp, block, 1); + frp = xfs_bmbt_rec_addr(mp, block, 1); for (j = 0; j < num_recs; j++, frp++, ir->loaded++) { struct xfs_bmbt_irec new; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 2f9202ed41dd..82f46837f79f 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -48,10 +48,10 @@ xfs_bmdr_to_bmbt( ASSERT(be16_to_cpu(rblock->bb_level) > 0); rblock->bb_numrecs = dblock->bb_numrecs; dmxr = xfs_bmdr_maxrecs(dblocklen, 0); - fkp = XFS_BMDR_KEY_ADDR(dblock, 1); - tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); - fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); - tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); + fkp = xfs_bmdr_key_addr(dblock, 1); + tkp = xfs_bmbt_key_addr(mp, rblock, 1); + fpp = xfs_bmdr_ptr_addr(dblock, 1, dmxr); + tpp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, rblocklen); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); memcpy(tpp, fpp, sizeof(*fpp) * dmxr); @@ -151,10 +151,10 @@ xfs_bmbt_to_bmdr( dblock->bb_level = rblock->bb_level; dblock->bb_numrecs = rblock->bb_numrecs; dmxr = xfs_bmdr_maxrecs(dblocklen, 0); - fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); - tkp = XFS_BMDR_KEY_ADDR(dblock, 1); - fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); - tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); + fkp = xfs_bmbt_key_addr(mp, rblock, 1); + tkp = xfs_bmdr_key_addr(dblock, 1); + fpp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, rblocklen); + tpp = xfs_bmdr_ptr_addr(dblock, 1, dmxr); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); memcpy(tpp, fpp, sizeof(*fpp) * dmxr); @@ -688,7 +688,7 @@ xfs_bmbt_maxrecs( int blocklen, int leaf) { - blocklen -= XFS_BMBT_BLOCK_LEN(mp); + blocklen -= xfs_bmbt_block_len(mp); return xfs_bmbt_block_maxrecs(blocklen, leaf); } diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index 151b8491f60e..62fbc4f7c2c4 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -13,70 +13,6 @@ struct xfs_inode; struct xfs_trans; struct xbtree_ifakeroot; -/* - * Btree block header size depends on a superblock flag. - */ -#define XFS_BMBT_BLOCK_LEN(mp) \ - (xfs_has_crc(((mp))) ? \ - XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN) - -#define XFS_BMBT_REC_ADDR(mp, block, index) \ - ((xfs_bmbt_rec_t *) \ - ((char *)(block) + \ - XFS_BMBT_BLOCK_LEN(mp) + \ - ((index) - 1) * sizeof(xfs_bmbt_rec_t))) - -#define XFS_BMBT_KEY_ADDR(mp, block, index) \ - ((xfs_bmbt_key_t *) \ - ((char *)(block) + \ - XFS_BMBT_BLOCK_LEN(mp) + \ - ((index) - 1) * sizeof(xfs_bmbt_key_t))) - -#define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \ - ((xfs_bmbt_ptr_t *) \ - ((char *)(block) + \ - XFS_BMBT_BLOCK_LEN(mp) + \ - (maxrecs) * sizeof(xfs_bmbt_key_t) + \ - ((index) - 1) * sizeof(xfs_bmbt_ptr_t))) - -#define XFS_BMDR_REC_ADDR(block, index) \ - ((xfs_bmdr_rec_t *) \ - ((char *)(block) + \ - sizeof(struct xfs_bmdr_block) + \ - ((index) - 1) * sizeof(xfs_bmdr_rec_t))) - -#define XFS_BMDR_KEY_ADDR(block, index) \ - ((xfs_bmdr_key_t *) \ - ((char *)(block) + \ - sizeof(struct xfs_bmdr_block) + \ - ((index) - 1) * sizeof(xfs_bmdr_key_t))) - -#define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \ - ((xfs_bmdr_ptr_t *) \ - ((char *)(block) + \ - sizeof(struct xfs_bmdr_block) + \ - (maxrecs) * sizeof(xfs_bmdr_key_t) + \ - ((index) - 1) * sizeof(xfs_bmdr_ptr_t))) - -/* - * These are to be used when we know the size of the block and - * we don't have a cursor. - */ -#define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \ - XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)) - -#define XFS_BMAP_BROOT_SPACE_CALC(mp, nrecs) \ - (int)(XFS_BMBT_BLOCK_LEN(mp) + \ - ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) - -#define XFS_BMAP_BROOT_SPACE(mp, bb) \ - (XFS_BMAP_BROOT_SPACE_CALC(mp, be16_to_cpu((bb)->bb_numrecs))) -#define XFS_BMDR_SPACE_CALC(nrecs) \ - (int)(sizeof(xfs_bmdr_block_t) + \ - ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) -#define XFS_BMAP_BMDR_SPACE(bb) \ - (XFS_BMDR_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) - /* * Maximum number of bmap btree levels. */ @@ -120,4 +56,144 @@ unsigned int xfs_bmbt_maxlevels_ondisk(void); int __init xfs_bmbt_init_cur_cache(void); void xfs_bmbt_destroy_cur_cache(void); +/* + * Btree block header size depends on a superblock flag. + */ +static inline size_t +xfs_bmbt_block_len(struct xfs_mount *mp) +{ + return xfs_has_crc(mp) ? + XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN; +} + +/* Addresses of key, pointers, and records within an incore bmbt block. */ + +static inline struct xfs_bmbt_rec * +xfs_bmbt_rec_addr( + struct xfs_mount *mp, + struct xfs_btree_block *block, + unsigned int index) +{ + return (struct xfs_bmbt_rec *) + ((char *)block + xfs_bmbt_block_len(mp) + + (index - 1) * sizeof(struct xfs_bmbt_rec)); +} + +static inline struct xfs_bmbt_key * +xfs_bmbt_key_addr( + struct xfs_mount *mp, + struct xfs_btree_block *block, + unsigned int index) +{ + return (struct xfs_bmbt_key *) + ((char *)block + xfs_bmbt_block_len(mp) + + (index - 1) * sizeof(struct xfs_bmbt_key *)); +} + +static inline xfs_bmbt_ptr_t * +xfs_bmbt_ptr_addr( + struct xfs_mount *mp, + struct xfs_btree_block *block, + unsigned int index, + unsigned int maxrecs) +{ + return (xfs_bmbt_ptr_t *) + ((char *)block + xfs_bmbt_block_len(mp) + + maxrecs * sizeof(struct xfs_bmbt_key) + + (index - 1) * sizeof(xfs_bmbt_ptr_t)); +} + +/* Addresses of key, pointers, and records within an ondisk bmbt block. */ + +static inline struct xfs_bmbt_rec * +xfs_bmdr_rec_addr( + struct xfs_bmdr_block *block, + unsigned int index) +{ + return (struct xfs_bmbt_rec *) + ((char *)(block + 1) + + (index - 1) * sizeof(struct xfs_bmbt_rec)); +} + +static inline struct xfs_bmbt_key * +xfs_bmdr_key_addr( + struct xfs_bmdr_block *block, + unsigned int index) +{ + return (struct xfs_bmbt_key *) + ((char *)(block + 1) + + (index - 1) * sizeof(struct xfs_bmbt_key)); +} + +static inline xfs_bmbt_ptr_t * +xfs_bmdr_ptr_addr( + struct xfs_bmdr_block *block, + unsigned int index, + unsigned int maxrecs) +{ + return (xfs_bmbt_ptr_t *) + ((char *)(block + 1) + + maxrecs * sizeof(struct xfs_bmbt_key) + + (index - 1) * sizeof(xfs_bmbt_ptr_t)); +} + +/* + * Address of pointers within the incore btree root. + * + * These are to be used when we know the size of the block and + * we don't have a cursor. + */ +static inline xfs_bmbt_ptr_t * +xfs_bmap_broot_ptr_addr( + struct xfs_mount *mp, + struct xfs_btree_block *bb, + unsigned int i, + unsigned int sz) +{ + return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)); +} + +/* + * Compute the space required for the incore btree root containing the given + * number of records. + */ +static inline size_t +xfs_bmap_broot_space_calc( + struct xfs_mount *mp, + unsigned int nrecs) +{ + return xfs_bmbt_block_len(mp) + \ + (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t))); +} + +/* + * Compute the space required for the incore btree root given the ondisk + * btree root block. + */ +static inline size_t +xfs_bmap_broot_space( + struct xfs_mount *mp, + struct xfs_bmdr_block *bb) +{ + return xfs_bmap_broot_space_calc(mp, be16_to_cpu(bb->bb_numrecs)); +} + +/* Compute the space required for the ondisk root block. */ +static inline size_t +xfs_bmdr_space_calc(unsigned int nrecs) +{ + return sizeof(struct xfs_bmdr_block) + + (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t))); +} + +/* + * Compute the space required for the ondisk root block given an incore root + * block. + */ +static inline size_t +xfs_bmap_bmdr_space(struct xfs_btree_block *bb) +{ + return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs)); +} + #endif /* __XFS_BMAP_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index ab1bc0e3a595..9d53df7ce49d 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -181,7 +181,7 @@ xfs_iformat_btree( ifp = xfs_ifork_ptr(ip, whichfork); dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); - size = XFS_BMAP_BROOT_SPACE(mp, dfp); + size = xfs_bmap_broot_space(mp, dfp); nrecs = be16_to_cpu(dfp->bb_numrecs); level = be16_to_cpu(dfp->bb_level); @@ -194,7 +194,7 @@ xfs_iformat_btree( */ if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || nrecs == 0 || - XFS_BMDR_SPACE_CALC(nrecs) > + xfs_bmdr_space_calc(nrecs) > XFS_DFORK_SIZE(dip, mp, whichfork) || ifp->if_nextents > ip->i_nblocks) || level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) { @@ -391,7 +391,7 @@ xfs_iroot_realloc( * allocate it now and get out. */ if (ifp->if_broot_bytes == 0) { - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff); + new_size = xfs_bmap_broot_space_calc(mp, rec_diff); ifp->if_broot = kmem_alloc(new_size, KM_NOFS); ifp->if_broot_bytes = (int)new_size; return; @@ -405,15 +405,15 @@ xfs_iroot_realloc( */ cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); new_max = cur_max + rec_diff; - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); + new_size = xfs_bmap_broot_space_calc(mp, new_max); ifp->if_broot = krealloc(ifp->if_broot, new_size, GFP_NOFS | __GFP_NOFAIL); - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, ifp->if_broot_bytes); - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, (int)new_size); ifp->if_broot_bytes = (int)new_size; - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= xfs_inode_fork_size(ip, whichfork)); memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t)); return; @@ -429,7 +429,7 @@ xfs_iroot_realloc( new_max = cur_max + rec_diff; ASSERT(new_max >= 0); if (new_max > 0) - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); + new_size = xfs_bmap_broot_space_calc(mp, new_max); else new_size = 0; if (new_size > 0) { @@ -438,7 +438,7 @@ xfs_iroot_realloc( * First copy over the btree block header. */ memcpy(new_broot, ifp->if_broot, - XFS_BMBT_BLOCK_LEN(ip->i_mount)); + xfs_bmbt_block_len(ip->i_mount)); } else { new_broot = NULL; } @@ -450,16 +450,16 @@ xfs_iroot_realloc( /* * First copy the records. */ - op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); - np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); + op = (char *)xfs_bmbt_rec_addr(mp, ifp->if_broot, 1); + np = (char *)xfs_bmbt_rec_addr(mp, new_broot, 1); memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); /* * Then copy the pointers. */ - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, + op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, ifp->if_broot_bytes); - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, + np = (char *)xfs_bmap_broot_ptr_addr(mp, new_broot, 1, (int)new_size); memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t)); } @@ -467,7 +467,7 @@ xfs_iroot_realloc( ifp->if_broot = new_broot; ifp->if_broot_bytes = (int)new_size; if (ifp->if_broot) - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= xfs_inode_fork_size(ip, whichfork)); return; } @@ -640,7 +640,7 @@ xfs_iflush_fork( if ((iip->ili_fields & brootflag[whichfork]) && (ifp->if_broot_bytes > 0)) { ASSERT(ifp->if_broot != NULL); - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= xfs_inode_fork_size(ip, whichfork)); xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, (xfs_bmdr_block_t *)cp, diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 67accd613038..3435492b1658 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -128,7 +128,7 @@ xfs_calc_inode_res( (4 * sizeof(struct xlog_op_header) + sizeof(struct xfs_inode_log_format) + mp->m_sb.sb_inodesize + - 2 * XFS_BMBT_BLOCK_LEN(mp)); + 2 * xfs_bmbt_block_len(mp)); } /* diff --git a/fs/xfs/scrub/bmap_repair.c b/fs/xfs/scrub/bmap_repair.c index 4638f3652b54..73ba5c514cde 100644 --- a/fs/xfs/scrub/bmap_repair.c +++ b/fs/xfs/scrub/bmap_repair.c @@ -437,7 +437,7 @@ xrep_bmap_iroot_size( { ASSERT(level > 0); - return XFS_BMAP_BROOT_SPACE_CALC(cur->bc_mp, nr_this_level); + return xfs_bmap_broot_space_calc(cur->bc_mp, nr_this_level); } /* Update the inode counters. */ diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c index ef10f031146e..1efd606bf92c 100644 --- a/fs/xfs/scrub/inode_repair.c +++ b/fs/xfs/scrub/inode_repair.c @@ -701,7 +701,7 @@ xrep_dinode_bad_btree_fork( nrecs = be16_to_cpu(dfp->bb_numrecs); level = be16_to_cpu(dfp->bb_level); - if (nrecs == 0 || XFS_BMDR_SPACE_CALC(nrecs) > dfork_size) + if (nrecs == 0 || xfs_bmdr_space_calc(nrecs) > dfork_size) return true; if (level == 0 || level >= XFS_BM_MAXLEVELS(sc->mp, whichfork)) return true; @@ -919,7 +919,7 @@ xrep_dinode_ensure_forkoff( struct xfs_bmdr_block *bmdr; struct xfs_scrub *sc = ri->sc; xfs_extnum_t attr_extents, data_extents; - size_t bmdr_minsz = XFS_BMDR_SPACE_CALC(1); + size_t bmdr_minsz = xfs_bmdr_space_calc(1); unsigned int lit_sz = XFS_LITINO(sc->mp); unsigned int afork_min, dfork_min; @@ -971,7 +971,7 @@ xrep_dinode_ensure_forkoff( case XFS_DINODE_FMT_BTREE: /* Must have space for btree header and key/pointers. */ bmdr = XFS_DFORK_PTR(dip, XFS_ATTR_FORK); - afork_min = XFS_BMAP_BROOT_SPACE(sc->mp, bmdr); + afork_min = xfs_bmap_broot_space(sc->mp, bmdr); break; default: /* We should never see any other formats. */ @@ -1021,7 +1021,7 @@ xrep_dinode_ensure_forkoff( case XFS_DINODE_FMT_BTREE: /* Must have space for btree header and key/pointers. */ bmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK); - dfork_min = XFS_BMAP_BROOT_SPACE(sc->mp, bmdr); + dfork_min = xfs_bmap_broot_space(sc->mp, bmdr); break; default: dfork_min = 0; diff --git a/fs/xfs/xfs_xchgrange.c b/fs/xfs/xfs_xchgrange.c index 829a17ac7406..1951fcfdb1d9 100644 --- a/fs/xfs/xfs_xchgrange.c +++ b/fs/xfs/xfs_xchgrange.c @@ -163,7 +163,7 @@ xfs_swap_extents_check_format( */ if (tifp->if_format == XFS_DINODE_FMT_BTREE) { if (xfs_inode_has_attr_fork(ip) && - XFS_BMAP_BMDR_SPACE(tifp->if_broot) > xfs_inode_fork_boff(ip)) + xfs_bmap_bmdr_space(tifp->if_broot) > xfs_inode_fork_boff(ip)) return -EINVAL; if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) return -EINVAL; @@ -172,7 +172,7 @@ xfs_swap_extents_check_format( /* Reciprocal target->temp btree format checks */ if (ifp->if_format == XFS_DINODE_FMT_BTREE) { if (xfs_inode_has_attr_fork(tip) && - XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > xfs_inode_fork_boff(tip)) + xfs_bmap_bmdr_space(ip->i_df.if_broot) > xfs_inode_fork_boff(tip)) return -EINVAL; if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) return -EINVAL; From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085388 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E39EC4332F for ; Sat, 31 Dec 2022 01:16:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236041AbiLaBQ6 (ORCPT ); Fri, 30 Dec 2022 20:16:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236048AbiLaBQv (ORCPT ); Fri, 30 Dec 2022 20:16:51 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F4D71AD9A for ; Fri, 30 Dec 2022 17:16:51 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A18E261D77 for ; Sat, 31 Dec 2022 01:16:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 13AC7C433EF; Sat, 31 Dec 2022 01:16:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449410; bh=iZpoeAyr09sNC8/LhzPvMHNNf3TtviNobi5y096JWh8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=R3clVJfUNNUEBZs2C6cPmujsH84Y76gXvT3s7U9MI2nCDuTX4jGmsWL7na5TM9Lhv 08VPqd8kJwqdn7kdkc2MnSOWBXrLbSchdKpDQo9dYk4ZDvtHcCQZvNWBH2/yYYUgUg 2OMB5jPOo8+9LqoT7uWjEQkQPeUYz8OBvnQjBxiR246i51GRIBQtLqtT4smvmhoos3 lA6TcO1pXHrI6+Jhy98mZZR4AmFH1v4kU2C79SnJ2eN0kVtn7tG4QvscujvCjHvXVQ 9syp1uskMA8mBD15ry3F6T88g8Mcy0Oaf7IS7NKW8QOsItn9OuMVC50VgRJNQCtshh mEGOS/O/dw43w== Subject: [PATCH 02/14] xfs: refactor the allocation and freeing of incore inode fork btree roots From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865136.708933.3250808354146954240.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Refactor the code that allocates and freese the incore inode fork btree roots. This will help us disentangle some of the weird logic when we're creating and tearing down inode-based btrees. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 53 ++++++++++++++++++++++++++++------------ fs/xfs/libxfs/xfs_inode_fork.h | 3 ++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 9d53df7ce49d..0f220f100069 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -207,8 +207,7 @@ xfs_iformat_btree( return -EFSCORRUPTED; } - ifp->if_broot_bytes = size; - ifp->if_broot = kmem_alloc(size, KM_NOFS); + xfs_iroot_alloc(ip, whichfork, size); ASSERT(ifp->if_broot != NULL); /* * Copy and convert from the on-disk structure @@ -344,6 +343,32 @@ xfs_iformat_attr_fork( return error; } +/* Allocate a new incore ifork btree root. */ +void +xfs_iroot_alloc( + struct xfs_inode *ip, + int whichfork, + size_t bytes) +{ + struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); + + ifp->if_broot = kmem_alloc(bytes, KM_NOFS); + ifp->if_broot_bytes = bytes; +} + +/* Free all the memory and state associated with an incore ifork btree root. */ +void +xfs_iroot_free( + struct xfs_inode *ip, + int whichfork) +{ + struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); + + ifp->if_broot_bytes = 0; + kmem_free(ifp->if_broot); + ifp->if_broot = NULL; +} + /* * Reallocate the space for if_broot based on the number of records * being added or deleted as indicated in rec_diff. Move the records @@ -392,8 +417,7 @@ xfs_iroot_realloc( */ if (ifp->if_broot_bytes == 0) { new_size = xfs_bmap_broot_space_calc(mp, rec_diff); - ifp->if_broot = kmem_alloc(new_size, KM_NOFS); - ifp->if_broot_bytes = (int)new_size; + xfs_iroot_alloc(ip, whichfork, new_size); return; } @@ -432,17 +456,15 @@ xfs_iroot_realloc( new_size = xfs_bmap_broot_space_calc(mp, new_max); else new_size = 0; - if (new_size > 0) { - new_broot = kmem_alloc(new_size, KM_NOFS); - /* - * First copy over the btree block header. - */ - memcpy(new_broot, ifp->if_broot, - xfs_bmbt_block_len(ip->i_mount)); - } else { - new_broot = NULL; + if (new_size == 0) { + xfs_iroot_free(ip, whichfork); + return; } + /* First copy over the btree block header. */ + new_broot = kmem_alloc(new_size, KM_NOFS); + memcpy(new_broot, ifp->if_broot, xfs_bmbt_block_len(ip->i_mount)); + /* * Only copy the records and pointers if there are any. */ @@ -466,9 +488,8 @@ xfs_iroot_realloc( kmem_free(ifp->if_broot); ifp->if_broot = new_broot; ifp->if_broot_bytes = (int)new_size; - if (ifp->if_broot) - ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= - xfs_inode_fork_size(ip, whichfork)); + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= + xfs_inode_fork_size(ip, whichfork)); return; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index c201d8ad5957..f4379e2df616 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -171,6 +171,9 @@ void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, void xfs_idestroy_fork(struct xfs_ifork *ifp); void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, int whichfork); +void xfs_iroot_alloc(struct xfs_inode *ip, int whichfork, + size_t bytes); +void xfs_iroot_free(struct xfs_inode *ip, int whichfork); void xfs_iroot_realloc(struct xfs_inode *, int, int); int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085389 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B9BBC3DA7C for ; Sat, 31 Dec 2022 01:17:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235936AbiLaBRK (ORCPT ); Fri, 30 Dec 2022 20:17:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236047AbiLaBRH (ORCPT ); Fri, 30 Dec 2022 20:17:07 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E62B1AD9A for ; Fri, 30 Dec 2022 17:17:06 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3C19761D79 for ; Sat, 31 Dec 2022 01:17:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 999AAC433D2; Sat, 31 Dec 2022 01:17:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449425; bh=HzwpWgwfQ9Mfz1R9AkHcvK2nPsJlDP2WhxCRh45i+ZI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=MZpNCkfUfzaBxga5cRHYQrvILFosRQ/3staDVQ4Lon/ybi2q8hFldUM2qUY7cRJpy h0XBOzb0vg9Z7zSryd5ZmNmrfHJncDpqlcpt/gR4fbPfa7m4lg5cccVz2cbyELgMBd AOctx6t7qtALzwrFcfB6CsxK7h+ehjPuVSNfbbPcCcCV+IcJCCiBnh7YWmlBbc5YOL yW4pkkFJXX+kvDgGVhj7yZDDwJ42w7KF2WB9au98Bxw7b/QXxpKIT2jtEN9OiSuCg0 gCjBH0qE1VdYz/8SK5UGdMdOS8P9YGhZpxbJEFjJzyNEia+lCO7YnwueyTztg3qq4f roOQuWvgeXL3g== Subject: [PATCH 03/14] xfs: refactor creation of bmap btree roots From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865150.708933.20488103124286076.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Now that we've created inode fork helpers to allocate and free btree roots, create a new bmap btree helper to create a new bmbt root, and refactor the extents <-> btree conversion functions to use our new helpers. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 17 ++++------------- fs/xfs/libxfs/xfs_bmap_btree.c | 16 ++++++++++++++++ fs/xfs/libxfs/xfs_bmap_btree.h | 2 ++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index cbcb24df1a1e..98bd32da142d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -591,7 +591,7 @@ xfs_bmap_btree_to_extents( xfs_trans_binval(tp, cbp); if (cur->bc_levels[0].bp == cbp) cur->bc_levels[0].bp = NULL; - xfs_iroot_realloc(ip, -1, whichfork); + xfs_iroot_free(ip, whichfork); ASSERT(ifp->if_broot == NULL); ifp->if_format = XFS_DINODE_FMT_EXTENTS; *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork); @@ -631,20 +631,10 @@ xfs_bmap_extents_to_btree( ifp = xfs_ifork_ptr(ip, whichfork); ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); - /* - * Make space in the inode incore. This needs to be undone if we fail - * to expand the root. - */ - xfs_iroot_realloc(ip, 1, whichfork); - - /* - * Fill in the root. - */ - block = ifp->if_broot; - xfs_btree_init_block(mp, block, &xfs_bmbt_ops, 1, 1, ip->i_ino); /* * Need a cursor. Can't allocate until bb_level is filled in. */ + xfs_bmbt_iroot_alloc(ip, whichfork); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_ino.flags = wasdel ? XFS_BTCUR_BMBT_WASDEL : 0; /* @@ -711,6 +701,7 @@ xfs_bmap_extents_to_btree( /* * Fill in the root key and pointer. */ + block = ifp->if_broot; kp = xfs_bmbt_key_addr(mp, block, 1); arp = xfs_bmbt_rec_addr(mp, ablock, 1); kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); @@ -732,7 +723,7 @@ xfs_bmap_extents_to_btree( out_unreserve_dquot: xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); out_root_realloc: - xfs_iroot_realloc(ip, -1, whichfork); + xfs_iroot_free(ip, whichfork); ifp->if_format = XFS_DINODE_FMT_EXTENTS; ASSERT(ifp->if_broot == NULL); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 82f46837f79f..973fa6cc7aa6 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -796,3 +796,19 @@ xfs_bmbt_destroy_cur_cache(void) kmem_cache_destroy(xfs_bmbt_cur_cache); xfs_bmbt_cur_cache = NULL; } + +/* Create an incore bmbt btree root block. */ +void +xfs_bmbt_iroot_alloc( + struct xfs_inode *ip, + int whichfork) +{ + struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); + + xfs_iroot_alloc(ip, whichfork, + xfs_bmap_broot_space_calc(ip->i_mount, 1)); + + /* Fill in the root. */ + xfs_btree_init_block(ip->i_mount, ifp->if_broot, &xfs_bmbt_ops, 1, 1, + ip->i_ino); +} diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index 62fbc4f7c2c4..3fe9c4f7f1a0 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -196,4 +196,6 @@ xfs_bmap_bmdr_space(struct xfs_btree_block *bb) return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs)); } +void xfs_bmbt_iroot_alloc(struct xfs_inode *ip, int whichfork); + #endif /* __XFS_BMAP_BTREE_H__ */ From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085390 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FE80C3DA7C for ; Sat, 31 Dec 2022 01:17:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236049AbiLaBRY (ORCPT ); Fri, 30 Dec 2022 20:17:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236047AbiLaBRW (ORCPT ); Fri, 30 Dec 2022 20:17:22 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 330D11DDF3 for ; Fri, 30 Dec 2022 17:17:22 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C4F8161D78 for ; Sat, 31 Dec 2022 01:17:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 31930C433EF; Sat, 31 Dec 2022 01:17:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449441; bh=NpcS68SNppusa38Iu9fJ4vk7KNtkJ4f/M3I+j9a2MKk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=bfRRZArxf37ncoLS/7E/w/lvgaHBD2YOtbNhZNDeexKxEubyCAX1MB29bUVQQAxUu fwm7Xrp7QBxTtauhPKu+XycMxHkhKRGkMPhYNDWvxR7UC3yacthklDUXAImEPU7FTW 7z3fizdFW8JFuJmkiJObeWZ0yJGE8Dz4hA4xBVFuTB0cyxZ67sDplSz3ZRmuu6voWo K5KqNQsqQZlRecQD0A8FBzjzBcJRSVlk59mjioUHxWPlE0L34hSPZyJrl8zotdvNAg OVnkY8P31eJPjttyIU3FqgDNoZJiW1otQg90QPPoP7m+xEMRGkNNz++oKfQTSvIFox z+DOowuAu7gIw== Subject: [PATCH 04/14] xfs: fix a sloppy memory handling bug in xfs_iroot_realloc From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865165.708933.12401569768700467243.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong While refactoring code, I noticed that when xfs_iroot_realloc tries to shrink a bmbt root block, it allocates a smaller new block and then copies "records" and pointers to the new block. However, bmbt root blocks cannot ever be leaves, which means that it's not technically correct to copy records. We /should/ be copying keys. Note that this has never resulted in actual memory corruption because sizeof(bmbt_rec) == (sizeof(bmbt_key) + sizeof(bmbt_ptr)). However, this will no longer be true when we start adding realtime rmap stuff, so fix this now. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0f220f100069..b73b971b83cd 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -466,15 +466,15 @@ xfs_iroot_realloc( memcpy(new_broot, ifp->if_broot, xfs_bmbt_block_len(ip->i_mount)); /* - * Only copy the records and pointers if there are any. + * Only copy the keys and pointers if there are any. */ if (new_max > 0) { /* - * First copy the records. + * First copy the keys. */ - op = (char *)xfs_bmbt_rec_addr(mp, ifp->if_broot, 1); - np = (char *)xfs_bmbt_rec_addr(mp, new_broot, 1); - memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); + op = (char *)xfs_bmbt_key_addr(mp, ifp->if_broot, 1); + np = (char *)xfs_bmbt_key_addr(mp, new_broot, 1); + memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t)); /* * Then copy the pointers. From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085391 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC34AC4332F for ; Sat, 31 Dec 2022 01:17:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236048AbiLaBRj (ORCPT ); Fri, 30 Dec 2022 20:17:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236047AbiLaBRi (ORCPT ); Fri, 30 Dec 2022 20:17:38 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C15C91CB3B for ; Fri, 30 Dec 2022 17:17:37 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5C79261D79 for ; Sat, 31 Dec 2022 01:17:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BBABCC433EF; Sat, 31 Dec 2022 01:17:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449456; bh=oRy5N9oi3E1wtIqPTLjNbIeHuE6yWcI6pc/WITKayYI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=XUUJlzMtzYoZbZenijN3Lx/JOJ4Rz00hO+HNk9Ag7h7EbLoo9lKn+6yPsaVnDHycA vUJExxDMrTzuRc7J7kWlZz9z47Isf6jJ00vv+oRENyRLu96tUm6T0vSX4rsz3PL22o uFWiCKye8d0mE8RkIJekHZhTWXk4liBLaapcYMgl5v2cZastH+0x8qsI7MOUZYE2i9 nA9eZtUThUwHlIl5K9M4YaY8WG/yy2yQhYS/bxmXCdhuUrX3USFJ+I8WI+CfajNGlL yzj38K6emewRc8yWsXpq9h2jnkR/E6zlrwPSzspE99215nTZ9C8pD/h2rdV2aQBjYI 9AQkyTaZX4axg== Subject: [PATCH 05/14] xfs: hoist the code that moves the incore inode fork broot memory From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865180.708933.1395874514497911625.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Whenever we change the size of the memory buffer holding an inode fork btree root block, we have to copy the contents over. Refactor all this into a single function that handles both, in preparation for making xfs_iroot_realloc more generic. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 99 +++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index b73b971b83cd..16782d3630d2 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -369,6 +369,50 @@ xfs_iroot_free( ifp->if_broot = NULL; } +/* Move the bmap btree root from one incore buffer to another. */ +static void +xfs_ifork_move_broot( + struct xfs_inode *ip, + int whichfork, + struct xfs_btree_block *dst_broot, + size_t dst_bytes, + struct xfs_btree_block *src_broot, + size_t src_bytes, + unsigned int numrecs) +{ + struct xfs_mount *mp = ip->i_mount; + void *dptr; + void *sptr; + + ASSERT(xfs_bmap_bmdr_space(src_broot) <= xfs_inode_fork_size(ip, whichfork)); + + /* + * We always have to move the pointers because they are not butted + * against the btree block header. + */ + if (numrecs) { + sptr = xfs_bmap_broot_ptr_addr(mp, src_broot, 1, src_bytes); + dptr = xfs_bmap_broot_ptr_addr(mp, dst_broot, 1, dst_bytes); + memmove(dptr, sptr, numrecs * sizeof(xfs_fsblock_t)); + } + + if (src_broot == dst_broot) + return; + + /* + * If the root is being totally relocated, we have to migrate the block + * header and the keys that come after it. + */ + memcpy(dst_broot, src_broot, xfs_bmbt_block_len(mp)); + + /* Now copy the keys, which come right after the header. */ + if (numrecs) { + sptr = xfs_bmbt_key_addr(mp, src_broot, 1); + dptr = xfs_bmbt_key_addr(mp, dst_broot, 1); + memcpy(dptr, sptr, numrecs * sizeof(struct xfs_bmbt_key)); + } +} + /* * Reallocate the space for if_broot based on the number of records * being added or deleted as indicated in rec_diff. Move the records @@ -395,12 +439,11 @@ xfs_iroot_realloc( { struct xfs_mount *mp = ip->i_mount; int cur_max; - struct xfs_ifork *ifp; + struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); struct xfs_btree_block *new_broot; int new_max; size_t new_size; - char *np; - char *op; + size_t old_size = ifp->if_broot_bytes; /* * Handle the degenerate case quietly. @@ -409,13 +452,12 @@ xfs_iroot_realloc( return; } - ifp = xfs_ifork_ptr(ip, whichfork); if (rec_diff > 0) { /* * If there wasn't any memory allocated before, just * allocate it now and get out. */ - if (ifp->if_broot_bytes == 0) { + if (old_size == 0) { new_size = xfs_bmap_broot_space_calc(mp, rec_diff); xfs_iroot_alloc(ip, whichfork, new_size); return; @@ -424,22 +466,16 @@ xfs_iroot_realloc( /* * If there is already an existing if_broot, then we need * to realloc() it and shift the pointers to their new - * location. The records don't change location because - * they are kept butted up against the btree block header. + * location. */ - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); + cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); new_max = cur_max + rec_diff; new_size = xfs_bmap_broot_space_calc(mp, new_max); ifp->if_broot = krealloc(ifp->if_broot, new_size, GFP_NOFS | __GFP_NOFAIL); - op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, - ifp->if_broot_bytes); - np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, - (int)new_size); - ifp->if_broot_bytes = (int)new_size; - ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= - xfs_inode_fork_size(ip, whichfork)); - memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t)); + ifp->if_broot_bytes = new_size; + xfs_ifork_move_broot(ip, whichfork, ifp->if_broot, new_size, + ifp->if_broot, old_size, cur_max); return; } @@ -448,8 +484,8 @@ xfs_iroot_realloc( * if_broot buffer. It must already exist. If we go to zero * records, just get rid of the root and clear the status bit. */ - ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); + ASSERT((ifp->if_broot != NULL) && (old_size > 0)); + cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); if (new_max > 0) @@ -461,35 +497,14 @@ xfs_iroot_realloc( return; } - /* First copy over the btree block header. */ + /* Reallocate the btree root and move the contents. */ new_broot = kmem_alloc(new_size, KM_NOFS); - memcpy(new_broot, ifp->if_broot, xfs_bmbt_block_len(ip->i_mount)); + xfs_ifork_move_broot(ip, whichfork, new_broot, new_size, ifp->if_broot, + old_size, new_max); - /* - * Only copy the keys and pointers if there are any. - */ - if (new_max > 0) { - /* - * First copy the keys. - */ - op = (char *)xfs_bmbt_key_addr(mp, ifp->if_broot, 1); - np = (char *)xfs_bmbt_key_addr(mp, new_broot, 1); - memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t)); - - /* - * Then copy the pointers. - */ - op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, - ifp->if_broot_bytes); - np = (char *)xfs_bmap_broot_ptr_addr(mp, new_broot, 1, - (int)new_size); - memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t)); - } kmem_free(ifp->if_broot); ifp->if_broot = new_broot; ifp->if_broot_bytes = (int)new_size; - ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= - xfs_inode_fork_size(ip, whichfork)); return; } From patchwork Fri Dec 30 22:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085392 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EEEBC4332F for ; Sat, 31 Dec 2022 01:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236052AbiLaBR4 (ORCPT ); Fri, 30 Dec 2022 20:17:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236051AbiLaBRz (ORCPT ); Fri, 30 Dec 2022 20:17:55 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 181C71D0C6 for ; Fri, 30 Dec 2022 17:17:55 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B2971B81DF6 for ; Sat, 31 Dec 2022 01:17:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4742DC433EF; Sat, 31 Dec 2022 01:17:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449472; bh=iTVfeaSUzSYQNV3y7Z5Rr0S/v24h0YUodMPOZwXIO60=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=EzDuax91BURHEtv62KvQzWHDnCXYO/etC4nWEjbRO11cxBJqzOuQUe3mdhHnGmajm dBV+Nj579q3fHL8eIJWMSE9E9xxrT/8LTYlmO8FdTLkNqCYnzwJ5dZIVBphWMDjgZc dlmh+3bu40Bs7EiRg3fIb71Lks2atdT7w1eSpN/IrrbSrZ9SXfTHws+x20Dmq+zL/p juqBOAePFXfZRP/UrlSju1Qfrmrrqaj/j6VDJbTx24pv0KxhmLumkbrwLohkXtlsIf OmBTW1eR4dk/NSioNN7xllwJbtNzT4+W9+n6ajrFdyuurGqkk3Q6Tnd5HCr0+iihYO zZGbHrYHRgh8A== Subject: [PATCH 06/14] xfs: move the zero records logic into xfs_bmap_broot_space_calc From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:31 -0800 Message-ID: <167243865194.708933.4077599318945848079.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong The bmap btree cannot ever have zero records in an incore btree block. If the number of records drops to zero, that means we're converting the fork to extents format and are trying to remove the tree. This logic won't hold for the future realtime rmap btree, so move the logic into the bmbt code. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap_btree.h | 7 +++++++ fs/xfs/libxfs/xfs_inode_fork.c | 6 ++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index 3fe9c4f7f1a0..5a3bae94debd 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -162,6 +162,13 @@ xfs_bmap_broot_space_calc( struct xfs_mount *mp, unsigned int nrecs) { + /* + * If the bmbt root block is empty, we should be converting the fork + * to extents format. Hence, the size is zero. + */ + if (nrecs == 0) + return 0; + return xfs_bmbt_block_len(mp) + \ (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t))); } diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 16782d3630d2..1bd8c1f9ce37 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -488,10 +488,8 @@ xfs_iroot_realloc( cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); - if (new_max > 0) - new_size = xfs_bmap_broot_space_calc(mp, new_max); - else - new_size = 0; + + new_size = xfs_bmap_broot_space_calc(mp, new_max); if (new_size == 0) { xfs_iroot_free(ip, whichfork); return; From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085393 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1F70C4332F for ; Sat, 31 Dec 2022 01:18:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236053AbiLaBSK (ORCPT ); Fri, 30 Dec 2022 20:18:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236054AbiLaBSJ (ORCPT ); Fri, 30 Dec 2022 20:18:09 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD9251D0C6 for ; Fri, 30 Dec 2022 17:18:08 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6C76761D7A for ; Sat, 31 Dec 2022 01:18:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CF367C433D2; Sat, 31 Dec 2022 01:18:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449487; bh=Y++h65fq+j2Hk0pGBesqI+ZJ6GIe5EVPUc2lqw0FTY8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=d5CPQCmLrZITH8LlJxylCnP+AD1+YMtpaUtqm1nUBH9xkKQQs8GxLXYhp60std/4h EWkvPomGi1y/5dYY5+kykPK4ciG4nA0Db7APz3A2UStDAWobWQGOmoFVzjBGqYOmeS hRIdOChyxqq1Ytjn/WCCEmfg1nycGlCzkPASG+GcHt36dZfsG8/JT6gvzIVmQVs7U+ dPAWsBMkeMrzz3fT8m3TIc48cOP2WZEbOinHZn94ECsXOiFzG4q86SNdzhhlohjewu 7bR38iA75w0uqsuS26hcUC38wYfIYxmKz5GzDqf4M0RYhGctR5hNIx4raOg7d54Hmu 89TJjHZGZYmvQ== Subject: [PATCH 07/14] xfs: rearrange xfs_iroot_realloc a bit From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865207.708933.6009722653433688860.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Rearrange the innards of xfs_iroot_realloc so that we can reduce duplicated code prior to genericizing the function. No functional changes. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_inode_fork.c | 49 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 1bd8c1f9ce37..ceab02b19d26 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -433,44 +433,46 @@ xfs_ifork_move_broot( */ void xfs_iroot_realloc( - xfs_inode_t *ip, + struct xfs_inode *ip, int rec_diff, int whichfork) { struct xfs_mount *mp = ip->i_mount; - int cur_max; struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); struct xfs_btree_block *new_broot; - int new_max; size_t new_size; size_t old_size = ifp->if_broot_bytes; + int cur_max; + int new_max; + + /* Handle degenerate cases. */ + if (rec_diff == 0) + return; /* - * Handle the degenerate case quietly. + * If there wasn't any memory allocated before, just allocate it now + * and get out. */ - if (rec_diff == 0) { + if (old_size == 0) { + ASSERT(rec_diff > 0); + + new_size = xfs_bmap_broot_space_calc(mp, rec_diff); + xfs_iroot_alloc(ip, whichfork, new_size); return; } + /* Compute the new and old record count and space requirements. */ + cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); + new_max = cur_max + rec_diff; + ASSERT(new_max >= 0); + new_size = xfs_bmap_broot_space_calc(mp, new_max); + if (rec_diff > 0) { - /* - * If there wasn't any memory allocated before, just - * allocate it now and get out. - */ - if (old_size == 0) { - new_size = xfs_bmap_broot_space_calc(mp, rec_diff); - xfs_iroot_alloc(ip, whichfork, new_size); - return; - } - /* * If there is already an existing if_broot, then we need * to realloc() it and shift the pointers to their new * location. */ - cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); - new_max = cur_max + rec_diff; - new_size = xfs_bmap_broot_space_calc(mp, new_max); ifp->if_broot = krealloc(ifp->if_broot, new_size, GFP_NOFS | __GFP_NOFAIL); ifp->if_broot_bytes = new_size; @@ -482,14 +484,8 @@ xfs_iroot_realloc( /* * rec_diff is less than 0. In this case, we are shrinking the * if_broot buffer. It must already exist. If we go to zero - * records, just get rid of the root and clear the status bit. + * bytes, just get rid of the root and clear the status bit. */ - ASSERT((ifp->if_broot != NULL) && (old_size > 0)); - cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); - new_max = cur_max + rec_diff; - ASSERT(new_max >= 0); - - new_size = xfs_bmap_broot_space_calc(mp, new_max); if (new_size == 0) { xfs_iroot_free(ip, whichfork); return; @@ -502,8 +498,7 @@ xfs_iroot_realloc( kmem_free(ifp->if_broot); ifp->if_broot = new_broot; - ifp->if_broot_bytes = (int)new_size; - return; + ifp->if_broot_bytes = new_size; } From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085394 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4CCEFC4332F for ; Sat, 31 Dec 2022 01:18:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236054AbiLaBS0 (ORCPT ); Fri, 30 Dec 2022 20:18:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236047AbiLaBSZ (ORCPT ); Fri, 30 Dec 2022 20:18:25 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FF9D1CB3B for ; Fri, 30 Dec 2022 17:18:24 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F29F161D7A for ; Sat, 31 Dec 2022 01:18:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E85DC433D2; Sat, 31 Dec 2022 01:18:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449503; bh=B35otfMdKkqr0KVqGqvaq8OdQgRhK7ZnGmNc70w6pgk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=TS0tqrd7MZDp34K0UmsLCWYeZUznrXjTk5rJ7OyZrexc8ukIOwwWSHh2ntPNrUtt5 F578d6wrMT2qEZ1wMCReuQWRkRSlSUPwFdE2UNPhq1NieB4KMWAh6p9V9Mn3guiYZI Oalby4trFAvGKw48Lj4BtQJb3G7FGRq9kx0qSnotDcGKwRleaD9fgjVcgM4Hl1lCvg af4pKUt+Qh1HOPACR71vYc45PeaidGsIRyRvCK2cYq4nxpLey7PK+lX6UtTFgAzbaT TLs8Da60thbjAmvXvxMeIrnVmKyJslbJiy7LvX20Ari7ZkdWLeWGvxiwRONvPyUMlM YOAXLx0w82KnQ== Subject: [PATCH 08/14] xfs: standardize the btree maxrecs function parameters From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865220.708933.2761563685766499261.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Standardize the parameters in xfs_{alloc,bm,ino,rmap,refcount}bt_maxrecs so that we have consistent calling conventions. This doesn't affect the kernel that much, but enables us to clean up userspace a bit. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc_btree.c | 6 +++--- fs/xfs/libxfs/xfs_alloc_btree.h | 3 ++- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_bmap_btree.c | 6 +++--- fs/xfs/libxfs/xfs_bmap_btree.h | 5 +++-- fs/xfs/libxfs/xfs_ialloc.c | 4 ++-- fs/xfs/libxfs/xfs_ialloc_btree.c | 6 +++--- fs/xfs/libxfs/xfs_ialloc_btree.h | 3 ++- fs/xfs/libxfs/xfs_inode_fork.c | 2 +- fs/xfs/libxfs/xfs_refcount_btree.c | 5 +++-- fs/xfs/libxfs/xfs_refcount_btree.h | 3 ++- fs/xfs/libxfs/xfs_rmap_btree.c | 9 +++++---- fs/xfs/libxfs/xfs_rmap_btree.h | 3 ++- fs/xfs/libxfs/xfs_sb.c | 16 ++++++++-------- 14 files changed, 40 insertions(+), 33 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 6f17fee31872..7f375c853492 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -609,11 +609,11 @@ xfs_allocbt_block_maxrecs( /* * Calculate number of records in an alloc btree block. */ -int +unsigned int xfs_allocbt_maxrecs( struct xfs_mount *mp, - int blocklen, - int leaf) + unsigned int blocklen, + bool leaf) { blocklen -= XFS_ALLOC_BLOCK_LEN(mp); return xfs_allocbt_block_maxrecs(blocklen, leaf); diff --git a/fs/xfs/libxfs/xfs_alloc_btree.h b/fs/xfs/libxfs/xfs_alloc_btree.h index 45df893ef6bb..f61f51d0bd76 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.h +++ b/fs/xfs/libxfs/xfs_alloc_btree.h @@ -53,7 +53,8 @@ extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *mp, struct xfs_btree_cur *xfs_allocbt_stage_cursor(struct xfs_mount *mp, struct xbtree_afakeroot *afake, struct xfs_perag *pag, xfs_btnum_t btnum); -extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int); +unsigned int xfs_allocbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, + bool leaf); extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp, unsigned long long len); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 98bd32da142d..eda20bb5c4af 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -565,7 +565,7 @@ xfs_bmap_btree_to_extents( ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); ASSERT(be16_to_cpu(rblock->bb_level) == 1); ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); - ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); + ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false) == 1); pp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, ifp->if_broot_bytes); cbno = be64_to_cpu(*pp); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 973fa6cc7aa6..1d226b284db3 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -682,11 +682,11 @@ xfs_bmbt_commit_staged_btree( /* * Calculate number of records in a bmap btree block. */ -int +unsigned int xfs_bmbt_maxrecs( struct xfs_mount *mp, - int blocklen, - int leaf) + unsigned int blocklen, + bool leaf) { blocklen -= xfs_bmbt_block_len(mp); return xfs_bmbt_block_maxrecs(blocklen, leaf); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index 5a3bae94debd..a9ddc9b42e61 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -35,7 +35,8 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int, extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level); extern int xfs_bmdr_maxrecs(int blocklen, int leaf); -extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); +unsigned int xfs_bmbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, + bool leaf); extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, xfs_ino_t new_owner, @@ -150,7 +151,7 @@ xfs_bmap_broot_ptr_addr( unsigned int i, unsigned int sz) { - return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)); + return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, false)); } /* diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 1d1c3cb0389c..331d22a60272 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2880,8 +2880,8 @@ xfs_ialloc_setup_geometry( /* Compute inode btree geometry. */ igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog; - igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); - igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); + igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, true); + igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, false); igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2; igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 84094e326a6e..9f3104db9171 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -560,11 +560,11 @@ xfs_inobt_block_maxrecs( /* * Calculate number of records in an inobt btree block. */ -int +unsigned int xfs_inobt_maxrecs( struct xfs_mount *mp, - int blocklen, - int leaf) + unsigned int blocklen, + bool leaf) { blocklen -= XFS_INOBT_BLOCK_LEN(mp); return xfs_inobt_block_maxrecs(blocklen, leaf); diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index 6d8d6bcd594d..1f219fae59c2 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -52,7 +52,8 @@ extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *mp, struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_mount *mp, struct xbtree_afakeroot *afake, struct xfs_perag *pag, xfs_btnum_t btnum); -extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); +unsigned int xfs_inobt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, + bool leaf); /* ir_holemask to inode allocation bitmap conversion */ uint64_t xfs_inobt_irec_to_allocmask(const struct xfs_inobt_rec_incore *irec); diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index ceab02b19d26..a9610452ca3a 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -462,7 +462,7 @@ xfs_iroot_realloc( } /* Compute the new and old record count and space requirements. */ - cur_max = xfs_bmbt_maxrecs(mp, old_size, 0); + cur_max = xfs_bmbt_maxrecs(mp, old_size, false); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); new_size = xfs_bmap_broot_space_calc(mp, new_max); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index b037fd949f8c..674a846aa121 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -439,9 +439,10 @@ xfs_refcountbt_block_maxrecs( /* * Calculate the number of records in a refcount btree block. */ -int +unsigned int xfs_refcountbt_maxrecs( - int blocklen, + struct xfs_mount *mp, + unsigned int blocklen, bool leaf) { blocklen -= XFS_REFCOUNT_BLOCK_LEN; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index d66b37259bed..fe3c20d67790 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -50,7 +50,8 @@ extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, struct xfs_perag *pag); struct xfs_btree_cur *xfs_refcountbt_stage_cursor(struct xfs_mount *mp, struct xbtree_afakeroot *afake, struct xfs_perag *pag); -extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf); +unsigned int xfs_refcountbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, + bool leaf); extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp); extern xfs_extlen_t xfs_refcountbt_calc_size(struct xfs_mount *mp, diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 1b88766ac497..81af6444e4b9 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -588,7 +588,7 @@ xfs_rmapbt_mem_verify( } return xfbtree_sblock_verify(bp, - xfs_rmapbt_maxrecs(xfo_to_b(1), level == 0)); + xfs_rmapbt_maxrecs(mp, xfo_to_b(1), level == 0)); } static void @@ -715,10 +715,11 @@ xfs_rmapbt_block_maxrecs( /* * Calculate number of records in an rmap btree block. */ -int +unsigned int xfs_rmapbt_maxrecs( - int blocklen, - int leaf) + struct xfs_mount *mp, + unsigned int blocklen, + bool leaf) { blocklen -= XFS_RMAP_BLOCK_LEN; return xfs_rmapbt_block_maxrecs(blocklen, leaf); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index a27a236111dd..bf88fba0392a 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -48,7 +48,8 @@ struct xfs_btree_cur *xfs_rmapbt_stage_cursor(struct xfs_mount *mp, struct xbtree_afakeroot *afake, struct xfs_perag *pag); void xfs_rmapbt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); -int xfs_rmapbt_maxrecs(int blocklen, int leaf); +unsigned int xfs_rmapbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, + bool leaf); extern void xfs_rmapbt_compute_maxlevels(struct xfs_mount *mp); extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp, diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index dbbea5b86f27..54f93e1b0f00 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -1049,23 +1049,23 @@ xfs_sb_mount_common( mp->m_rgblklog = log2_if_power2(sbp->sb_rgblocks); mp->m_rgblkmask = mask64_if_power2(sbp->sb_rgblocks); - mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); - mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, true); + mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, false); mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; - mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); - mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, true); + mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, false); mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; - mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(sbp->sb_blocksize, 1); - mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(sbp->sb_blocksize, 0); + mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, true); + mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, false); mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; - mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(sbp->sb_blocksize, true); - mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(sbp->sb_blocksize, false); + mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, true); + mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, false); mp->m_refc_mnr[0] = mp->m_refc_mxr[0] / 2; mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60408C4332F for ; Sat, 31 Dec 2022 01:18:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236047AbiLaBSo (ORCPT ); Fri, 30 Dec 2022 20:18:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236051AbiLaBSn (ORCPT ); Fri, 30 Dec 2022 20:18:43 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 06A391D0C6 for ; Fri, 30 Dec 2022 17:18:39 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8613B61B80 for ; Sat, 31 Dec 2022 01:18:39 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3346C433D2; Sat, 31 Dec 2022 01:18:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449519; bh=lP6Rzrgc7xLOU+BIDdxb6r3kZgJTE+ce101ljAAZkhs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=bPJTm7o6c9Z/mg1fQM1PiV7sZR162tU+9AIeEBIPcqhQAl5B1Ox2FxuRdzuzjSHqP 2693YfeL8S/+6nqcOpmw2bhMwjd+jCsvP0gpWJnXfdN1UrjXkToqmRmnuW8DQQUNP3 g70mY25CE7WEyvXEnxj9Ks8ss5wJQsw+yY1KQMKuBHdeCe5R3RDjkNYEHhg0ThKyQn GzgKQbnVRBB6gok1jvPVSKiOfdbeRCQdtqV3R0YbxUR/K5Z6Q25Z+2eFdF13bKwJ5P hmAoxTvpBbwke+DARCY5WeWv4KbYEWn/OWNkRzg2zKzKkPoR4WfLp6kJjeJV8xIRYN brv/p9KAXGskA== Subject: [PATCH 09/14] xfs: generalize the btree root reallocation function From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865235.708933.17221317441038700322.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong In preparation for storing realtime rmap btree roots in an inode fork, make xfs_iroot_realloc take an ops structure that takes care of all the btree-specific geometry pieces. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap_btree.c | 51 +++++++++++++++++++++++++ fs/xfs/libxfs/xfs_btree.c | 22 +++++++---- fs/xfs/libxfs/xfs_btree.h | 3 + fs/xfs/libxfs/xfs_inode_fork.c | 82 ++++++++-------------------------------- fs/xfs/libxfs/xfs_inode_fork.h | 23 +++++++++++ 5 files changed, 107 insertions(+), 74 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 1d226b284db3..f9d4ca6ced1f 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -527,6 +527,56 @@ xfs_bmbt_keys_contiguous( be64_to_cpu(key2->bmbt.br_startoff)); } +/* Move the bmap btree root from one incore buffer to another. */ +static void +xfs_bmbt_broot_move( + struct xfs_inode *ip, + int whichfork, + struct xfs_btree_block *dst_broot, + size_t dst_bytes, + struct xfs_btree_block *src_broot, + size_t src_bytes, + unsigned int numrecs) +{ + struct xfs_mount *mp = ip->i_mount; + void *dptr; + void *sptr; + + ASSERT(xfs_bmap_bmdr_space(src_broot) <= xfs_inode_fork_size(ip, whichfork)); + + /* + * We always have to move the pointers because they are not butted + * against the btree block header. + */ + if (numrecs) { + sptr = xfs_bmap_broot_ptr_addr(mp, src_broot, 1, src_bytes); + dptr = xfs_bmap_broot_ptr_addr(mp, dst_broot, 1, dst_bytes); + memmove(dptr, sptr, numrecs * sizeof(xfs_fsblock_t)); + } + + if (src_broot == dst_broot) + return; + + /* + * If the root is being totally relocated, we have to migrate the block + * header and the keys that come after it. + */ + memcpy(dst_broot, src_broot, xfs_bmbt_block_len(mp)); + + /* Now copy the keys, which come right after the header. */ + if (numrecs) { + sptr = xfs_bmbt_key_addr(mp, src_broot, 1); + dptr = xfs_bmbt_key_addr(mp, dst_broot, 1); + memcpy(dptr, sptr, numrecs * sizeof(struct xfs_bmbt_key)); + } +} + +static const struct xfs_ifork_broot_ops xfs_bmbt_iroot_ops = { + .maxrecs = xfs_bmbt_maxrecs, + .size = xfs_bmap_broot_space_calc, + .move = xfs_bmbt_broot_move, +}; + const struct xfs_btree_ops xfs_bmbt_ops = { .rec_len = sizeof(xfs_bmbt_rec_t), .key_len = sizeof(xfs_bmbt_key_t), @@ -549,6 +599,7 @@ const struct xfs_btree_ops xfs_bmbt_ops = { .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder, .keys_contiguous = xfs_bmbt_keys_contiguous, + .iroot_ops = &xfs_bmbt_iroot_ops, }; /* diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 5176947870f9..c2e6b4ea28bf 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3080,6 +3080,16 @@ xfs_btree_split( #define xfs_btree_split __xfs_btree_split #endif /* __KERNEL__ */ +static inline void +xfs_btree_iroot_realloc( + struct xfs_btree_cur *cur, + int rec_diff) +{ + ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); + + xfs_iroot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork, + cur->bc_ops->iroot_ops, rec_diff); +} /* * Copy the old inode root contents into a real block and make the @@ -3164,9 +3174,7 @@ xfs_btree_new_iroot( xfs_btree_copy_ptrs(cur, pp, &nptr, 1); - xfs_iroot_realloc(cur->bc_ino.ip, - 1 - xfs_btree_get_numrecs(cblock), - cur->bc_ino.whichfork); + xfs_btree_iroot_realloc(cur, 1 - xfs_btree_get_numrecs(cblock)); xfs_btree_setbuf(cur, level, cbp); @@ -3336,7 +3344,7 @@ xfs_btree_make_block_unfull( if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) { /* A root block that can be made bigger. */ - xfs_iroot_realloc(ip, 1, cur->bc_ino.whichfork); + xfs_btree_iroot_realloc(cur, 1); *stat = 1; } else { /* A root block that needs replacing */ @@ -3744,8 +3752,7 @@ xfs_btree_kill_iroot( index = numrecs - cur->bc_ops->get_maxrecs(cur, level); if (index) { - xfs_iroot_realloc(cur->bc_ino.ip, index, - cur->bc_ino.whichfork); + xfs_btree_iroot_realloc(cur, index); block = ifp->if_broot; } @@ -3942,8 +3949,7 @@ xfs_btree_delrec( */ if (level == cur->bc_nlevels - 1) { if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) { - xfs_iroot_realloc(cur->bc_ino.ip, -1, - cur->bc_ino.whichfork); + xfs_btree_iroot_realloc(cur, -1); error = xfs_btree_kill_iroot(cur); if (error) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 0e12360ae36d..3acfdcdf7561 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -202,6 +202,9 @@ struct xfs_btree_ops { const union xfs_btree_key *key1, const union xfs_btree_key *key2, const union xfs_btree_key *mask); + + /* Functions for manipulating the btree root block. */ + const struct xfs_ifork_broot_ops *iroot_ops; }; /* diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index a9610452ca3a..0ac1c8dba2ed 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -369,50 +369,6 @@ xfs_iroot_free( ifp->if_broot = NULL; } -/* Move the bmap btree root from one incore buffer to another. */ -static void -xfs_ifork_move_broot( - struct xfs_inode *ip, - int whichfork, - struct xfs_btree_block *dst_broot, - size_t dst_bytes, - struct xfs_btree_block *src_broot, - size_t src_bytes, - unsigned int numrecs) -{ - struct xfs_mount *mp = ip->i_mount; - void *dptr; - void *sptr; - - ASSERT(xfs_bmap_bmdr_space(src_broot) <= xfs_inode_fork_size(ip, whichfork)); - - /* - * We always have to move the pointers because they are not butted - * against the btree block header. - */ - if (numrecs) { - sptr = xfs_bmap_broot_ptr_addr(mp, src_broot, 1, src_bytes); - dptr = xfs_bmap_broot_ptr_addr(mp, dst_broot, 1, dst_bytes); - memmove(dptr, sptr, numrecs * sizeof(xfs_fsblock_t)); - } - - if (src_broot == dst_broot) - return; - - /* - * If the root is being totally relocated, we have to migrate the block - * header and the keys that come after it. - */ - memcpy(dst_broot, src_broot, xfs_bmbt_block_len(mp)); - - /* Now copy the keys, which come right after the header. */ - if (numrecs) { - sptr = xfs_bmbt_key_addr(mp, src_broot, 1); - dptr = xfs_bmbt_key_addr(mp, dst_broot, 1); - memcpy(dptr, sptr, numrecs * sizeof(struct xfs_bmbt_key)); - } -} - /* * Reallocate the space for if_broot based on the number of records * being added or deleted as indicated in rec_diff. Move the records @@ -426,24 +382,21 @@ xfs_ifork_move_broot( * if we are adding records, one will be allocated. The caller must also * not request that the number of records go below zero, although * it can go to zero. - * - * ip -- the inode whose if_broot area is changing - * ext_diff -- the change in the number of records, positive or negative, - * requested for the if_broot array. */ void xfs_iroot_realloc( - struct xfs_inode *ip, - int rec_diff, - int whichfork) + struct xfs_inode *ip, + int whichfork, + const struct xfs_ifork_broot_ops *ops, + int rec_diff) { - struct xfs_mount *mp = ip->i_mount; - struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); - struct xfs_btree_block *new_broot; - size_t new_size; - size_t old_size = ifp->if_broot_bytes; - int cur_max; - int new_max; + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); + struct xfs_btree_block *new_broot; + size_t new_size; + size_t old_size = ifp->if_broot_bytes; + int cur_max; + int new_max; /* Handle degenerate cases. */ if (rec_diff == 0) @@ -456,16 +409,16 @@ xfs_iroot_realloc( if (old_size == 0) { ASSERT(rec_diff > 0); - new_size = xfs_bmap_broot_space_calc(mp, rec_diff); + new_size = ops->size(mp, rec_diff); xfs_iroot_alloc(ip, whichfork, new_size); return; } /* Compute the new and old record count and space requirements. */ - cur_max = xfs_bmbt_maxrecs(mp, old_size, false); + cur_max = ops->maxrecs(mp, old_size, false); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); - new_size = xfs_bmap_broot_space_calc(mp, new_max); + new_size = ops->size(mp, new_max); if (rec_diff > 0) { /* @@ -476,7 +429,7 @@ xfs_iroot_realloc( ifp->if_broot = krealloc(ifp->if_broot, new_size, GFP_NOFS | __GFP_NOFAIL); ifp->if_broot_bytes = new_size; - xfs_ifork_move_broot(ip, whichfork, ifp->if_broot, new_size, + ops->move(ip, whichfork, ifp->if_broot, new_size, ifp->if_broot, old_size, cur_max); return; } @@ -493,15 +446,14 @@ xfs_iroot_realloc( /* Reallocate the btree root and move the contents. */ new_broot = kmem_alloc(new_size, KM_NOFS); - xfs_ifork_move_broot(ip, whichfork, new_broot, new_size, ifp->if_broot, - old_size, new_max); + ops->move(ip, whichfork, new_broot, new_size, ifp->if_broot, + ifp->if_broot_bytes, new_max); kmem_free(ifp->if_broot); ifp->if_broot = new_broot; ifp->if_broot_bytes = new_size; } - /* * This is called when the amount of space needed for if_data * is increased or decreased. The change in size is indicated by diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index f4379e2df616..7d95c402f870 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -174,7 +174,6 @@ void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, void xfs_iroot_alloc(struct xfs_inode *ip, int whichfork, size_t bytes); void xfs_iroot_free(struct xfs_inode *ip, int whichfork); -void xfs_iroot_realloc(struct xfs_inode *, int, int); int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, int); @@ -272,4 +271,26 @@ static inline bool xfs_need_iread_extents(struct xfs_ifork *ifp) return ifp->if_format == XFS_DINODE_FMT_BTREE && ifp->if_height == 0; } +struct xfs_ifork_broot_ops { + /* Calculate the number of records/keys in the incore btree block. */ + unsigned int (*maxrecs)(struct xfs_mount *mp, unsigned int blocksize, + bool leaf); + + /* Calculate the bytes required for the incore btree root block. */ + size_t (*size)(struct xfs_mount *mp, unsigned int nrecs); + + /* + * Move an incore btree root from one buffer to another. Note that + * src_broot and dst_broot could be the same or they could be totally + * separate memory regions. + */ + void (*move)(struct xfs_inode *ip, int whichfork, + struct xfs_btree_block *dst_broot, size_t dst_bytes, + struct xfs_btree_block *src_broot, size_t src_bytes, + unsigned int numrecs); +}; + +void xfs_iroot_realloc(struct xfs_inode *ip, int whichfork, + const struct xfs_ifork_broot_ops *ops, int rec_diff); + #endif /* __XFS_INODE_FORK_H__ */ From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085396 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB0AEC4332F for ; Sat, 31 Dec 2022 01:19:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236055AbiLaBS7 (ORCPT ); Fri, 30 Dec 2022 20:18:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236051AbiLaBS6 (ORCPT ); Fri, 30 Dec 2022 20:18:58 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 360AD1AD9A for ; Fri, 30 Dec 2022 17:18:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id DF6E3B81DF9 for ; Sat, 31 Dec 2022 01:18:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85EABC433EF; Sat, 31 Dec 2022 01:18:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449534; bh=Wpaa91irgJRDC7Jm1ipm9ZoYCEGj1HF9THhsRm6bAuY=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=eTlGlTXOQvTKZoUidA9neU4MFJJ8FWOE81vmaMESruzaZa/kZc5Xyjl4BgajRRbun ZxY2L5oBVgZgZOxbwxkMU7qQju7lYz0tkQQlf5glsoZUOnzZ+koufAvvSkiOrF4K9s D/kxrasV+eNzLa7TKbI4+iCFp3uJEcsB3J4QfcbbpT0G6wxFhq4L5+Mp5bIIF23o6N US8UP6xaNRwl6prVBCvk2tBkHtaydUcz2BvW9TdTFeOzPpYcHUJRSBBgOLX9iTbix9 Mvmfd9814LwV7+m7yUOk2mQgfO2tqsAfBjMsm84uyS+b1PKs1uYQ+PwJhNOmBNjF8b znTKB9RWH62iw== Subject: [PATCH 10/14] xfs: support leaves in the incore btree root block in xfs_iroot_realloc From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865250.708933.418868709687052909.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Add some logic to xfs_iroot_realloc so that we can handle leaf records in the btree root block correctly. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap_btree.c | 4 +++- fs/xfs/libxfs/xfs_bmap_btree.h | 5 ++++- fs/xfs/libxfs/xfs_inode_fork.c | 12 +++++++----- fs/xfs/libxfs/xfs_inode_fork.h | 5 +++-- fs/xfs/scrub/bmap_repair.c | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index f9d4ca6ced1f..4c6a91acdad6 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -536,6 +536,7 @@ xfs_bmbt_broot_move( size_t dst_bytes, struct xfs_btree_block *src_broot, size_t src_bytes, + unsigned int level, unsigned int numrecs) { struct xfs_mount *mp = ip->i_mount; @@ -543,6 +544,7 @@ xfs_bmbt_broot_move( void *sptr; ASSERT(xfs_bmap_bmdr_space(src_broot) <= xfs_inode_fork_size(ip, whichfork)); + ASSERT(level > 0); /* * We always have to move the pointers because they are not butted @@ -857,7 +859,7 @@ xfs_bmbt_iroot_alloc( struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); xfs_iroot_alloc(ip, whichfork, - xfs_bmap_broot_space_calc(ip->i_mount, 1)); + xfs_bmap_broot_space_calc(ip->i_mount, 1, 1)); /* Fill in the root. */ xfs_btree_init_block(ip->i_mount, ifp->if_broot, &xfs_bmbt_ops, 1, 1, diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index a9ddc9b42e61..d20321bfe2f6 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -161,8 +161,11 @@ xfs_bmap_broot_ptr_addr( static inline size_t xfs_bmap_broot_space_calc( struct xfs_mount *mp, + unsigned int level, unsigned int nrecs) { + ASSERT(level > 0); + /* * If the bmbt root block is empty, we should be converting the fork * to extents format. Hence, the size is zero. @@ -183,7 +186,7 @@ xfs_bmap_broot_space( struct xfs_mount *mp, struct xfs_bmdr_block *bb) { - return xfs_bmap_broot_space_calc(mp, be16_to_cpu(bb->bb_numrecs)); + return xfs_bmap_broot_space_calc(mp, 1, be16_to_cpu(bb->bb_numrecs)); } /* Compute the space required for the ondisk root block. */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0ac1c8dba2ed..b844bfd94e9c 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -395,6 +395,7 @@ xfs_iroot_realloc( struct xfs_btree_block *new_broot; size_t new_size; size_t old_size = ifp->if_broot_bytes; + unsigned int level; int cur_max; int new_max; @@ -409,16 +410,17 @@ xfs_iroot_realloc( if (old_size == 0) { ASSERT(rec_diff > 0); - new_size = ops->size(mp, rec_diff); + new_size = ops->size(mp, 0, rec_diff); xfs_iroot_alloc(ip, whichfork, new_size); return; } /* Compute the new and old record count and space requirements. */ - cur_max = ops->maxrecs(mp, old_size, false); + level = be16_to_cpu(ifp->if_broot->bb_level); + cur_max = ops->maxrecs(mp, old_size, level == 0); new_max = cur_max + rec_diff; ASSERT(new_max >= 0); - new_size = ops->size(mp, new_max); + new_size = ops->size(mp, level, new_max); if (rec_diff > 0) { /* @@ -430,7 +432,7 @@ xfs_iroot_realloc( GFP_NOFS | __GFP_NOFAIL); ifp->if_broot_bytes = new_size; ops->move(ip, whichfork, ifp->if_broot, new_size, - ifp->if_broot, old_size, cur_max); + ifp->if_broot, old_size, level, cur_max); return; } @@ -447,7 +449,7 @@ xfs_iroot_realloc( /* Reallocate the btree root and move the contents. */ new_broot = kmem_alloc(new_size, KM_NOFS); ops->move(ip, whichfork, new_broot, new_size, ifp->if_broot, - ifp->if_broot_bytes, new_max); + ifp->if_broot_bytes, level, new_max); kmem_free(ifp->if_broot); ifp->if_broot = new_broot; diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 7d95c402f870..3734642917a7 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -277,7 +277,8 @@ struct xfs_ifork_broot_ops { bool leaf); /* Calculate the bytes required for the incore btree root block. */ - size_t (*size)(struct xfs_mount *mp, unsigned int nrecs); + size_t (*size)(struct xfs_mount *mp, unsigned int level, + unsigned int nrecs); /* * Move an incore btree root from one buffer to another. Note that @@ -287,7 +288,7 @@ struct xfs_ifork_broot_ops { void (*move)(struct xfs_inode *ip, int whichfork, struct xfs_btree_block *dst_broot, size_t dst_bytes, struct xfs_btree_block *src_broot, size_t src_bytes, - unsigned int numrecs); + unsigned int level, unsigned int numrecs); }; void xfs_iroot_realloc(struct xfs_inode *ip, int whichfork, diff --git a/fs/xfs/scrub/bmap_repair.c b/fs/xfs/scrub/bmap_repair.c index 73ba5c514cde..0ad0f27fd8ca 100644 --- a/fs/xfs/scrub/bmap_repair.c +++ b/fs/xfs/scrub/bmap_repair.c @@ -437,7 +437,7 @@ xrep_bmap_iroot_size( { ASSERT(level > 0); - return xfs_bmap_broot_space_calc(cur->bc_mp, nr_this_level); + return xfs_bmap_broot_space_calc(cur->bc_mp, level, nr_this_level); } /* Update the inode counters. */ From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085397 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F27CEC4332F for ; Sat, 31 Dec 2022 01:19:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236056AbiLaBTP (ORCPT ); Fri, 30 Dec 2022 20:19:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236051AbiLaBTO (ORCPT ); Fri, 30 Dec 2022 20:19:14 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2B9A1DF2B for ; Fri, 30 Dec 2022 17:19:12 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 65F0AB81DF6 for ; Sat, 31 Dec 2022 01:19:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1ABADC433EF; Sat, 31 Dec 2022 01:19:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449550; bh=P40PRT6bIcYdkqa4pW2bJxsaJStQtWAgeSF5cmCPluw=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=Y5KNhYxt7kZeO/JtQBrTftEtem3OWtwKAyfuHIKL2L9DFxQnAmUsZ2IRfCN6npQc2 4RJEVn1BMXnyGiqQwkKKMgA1y4bq9XGdc+mOoDWbz4t0TeqrmLVUmzUaNEFChvQF9L 6IRrGqn8+gaAuOf6NmMvvhWrnass0bODHpdHznET9fsPcZ9KaI1TLCuYXjlBYqD5TT /Oo5zSjo28bDsBGmVXy+YcFIr/TrGALHOAb5Dt0jGSI3E9rufnzBpeTghYmvpieu+a PKSUj+pWlZAdtjvMzYUn4zP5LY+DM7+6ghFX185x0ejQ89pL6CFxa+9SsMNCscs8Ht iXHXN5vUnHXpA== Subject: [PATCH 11/14] xfs: hoist the node iroot update code out of xfs_btree_new_iroot From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865264.708933.17132105790885527230.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong In preparation for allowing records in an inode btree root, hoist the code that copies keyptrs from an existing node root into a child block to a separate function. Note that the new function explicitly computes the keys of the new child block and stores that in the root block; while the bmap btree could rely on leaving the key alone, realtime rmap needs to set the new high key. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.c | 113 +++++++++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 39 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index c2e6b4ea28bf..94df8c6000eb 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3091,6 +3091,77 @@ xfs_btree_iroot_realloc( cur->bc_ops->iroot_ops, rec_diff); } +/* + * Move the keys and pointers from a root block to a separate block. + * + * Since the keyptr size does not change, all we have to do is increase the + * tree height, copy the keyptrs to the new internal node (cblock), shrink + * the root, and copy the pointers there. + */ +STATIC int +xfs_btree_promote_node_iroot( + struct xfs_btree_cur *cur, + struct xfs_btree_block *block, + int level, + struct xfs_buf *cbp, + union xfs_btree_ptr *cptr, + struct xfs_btree_block *cblock) +{ + union xfs_btree_key *ckp; + union xfs_btree_key *kp; + union xfs_btree_ptr *cpp; + union xfs_btree_ptr *pp; + int i; + int error; + int numrecs = xfs_btree_get_numrecs(block); + + /* + * Increase tree height, adjusting the root block level to match. + * We cannot change the root btree node size until we've copied the + * block contents to the new child block. + */ + be16_add_cpu(&block->bb_level, 1); + cur->bc_nlevels++; + cur->bc_levels[level + 1].ptr = 1; + + /* + * Adjust the root btree record count, then copy the keys from the old + * root to the new child block. + */ + xfs_btree_set_numrecs(block, 1); + kp = xfs_btree_key_addr(cur, 1, block); + ckp = xfs_btree_key_addr(cur, 1, cblock); + xfs_btree_copy_keys(cur, ckp, kp, numrecs); + + /* Check the pointers and copy them to the new child block. */ + pp = xfs_btree_ptr_addr(cur, 1, block); + cpp = xfs_btree_ptr_addr(cur, 1, cblock); + for (i = 0; i < numrecs; i++) { + error = xfs_btree_debug_check_ptr(cur, pp, i, level); + if (error) + return error; + } + xfs_btree_copy_ptrs(cur, cpp, pp, numrecs); + + /* + * Set the first keyptr to point to the new child block, then shrink + * the memory buffer for the root block. + */ + error = xfs_btree_debug_check_ptr(cur, cptr, 0, level); + if (error) + return error; + xfs_btree_copy_ptrs(cur, pp, cptr, 1); + xfs_btree_get_keys(cur, cblock, kp); + xfs_btree_iroot_realloc(cur, 1 - numrecs); + + /* Attach the new block to the cursor and log it. */ + xfs_btree_setbuf(cur, level, cbp); + xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); + xfs_btree_log_keys(cur, cbp, 1, numrecs); + xfs_btree_log_ptrs(cur, cbp, 1, numrecs); + return 0; +} + /* * Copy the old inode root contents into a real block and make the * broot point to it. @@ -3104,14 +3175,10 @@ xfs_btree_new_iroot( struct xfs_buf *cbp; /* buffer for cblock */ struct xfs_btree_block *block; /* btree block */ struct xfs_btree_block *cblock; /* child btree block */ - union xfs_btree_key *ckp; /* child key pointer */ - union xfs_btree_ptr *cpp; /* child ptr pointer */ - union xfs_btree_key *kp; /* pointer to btree key */ - union xfs_btree_ptr *pp; /* pointer to block addr */ + union xfs_btree_ptr *pp; union xfs_btree_ptr nptr; /* new block addr */ int level; /* btree level */ int error; /* error return code */ - int i; /* loop counter */ XFS_BTREE_STATS_INC(cur, newroot); @@ -3149,43 +3216,11 @@ xfs_btree_new_iroot( cblock->bb_u.s.bb_blkno = bno; } - be16_add_cpu(&block->bb_level, 1); - xfs_btree_set_numrecs(block, 1); - cur->bc_nlevels++; - ASSERT(cur->bc_nlevels <= cur->bc_maxlevels); - cur->bc_levels[level + 1].ptr = 1; - - kp = xfs_btree_key_addr(cur, 1, block); - ckp = xfs_btree_key_addr(cur, 1, cblock); - xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock)); - - cpp = xfs_btree_ptr_addr(cur, 1, cblock); - for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { - error = xfs_btree_debug_check_ptr(cur, pp, i, level); - if (error) - goto error0; - } - - xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock)); - - error = xfs_btree_debug_check_ptr(cur, &nptr, 0, level); + error = xfs_btree_promote_node_iroot(cur, block, level, cbp, &nptr, + cblock); if (error) goto error0; - xfs_btree_copy_ptrs(cur, pp, &nptr, 1); - - xfs_btree_iroot_realloc(cur, 1 - xfs_btree_get_numrecs(cblock)); - - xfs_btree_setbuf(cur, level, cbp); - - /* - * Do all this logging at the end so that - * the root is at the right level. - */ - xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); - xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); - xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); - *logflags |= XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork); *stat = 1; From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085398 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0CA0DC4332F for ; Sat, 31 Dec 2022 01:19:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236051AbiLaBTb (ORCPT ); Fri, 30 Dec 2022 20:19:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236057AbiLaBTa (ORCPT ); Fri, 30 Dec 2022 20:19:30 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FA111AD9A for ; Fri, 30 Dec 2022 17:19:29 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 603F8CE19FC for ; Sat, 31 Dec 2022 01:19:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9BA6EC433EF; Sat, 31 Dec 2022 01:19:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449565; bh=VxM30yBAGXDxxD4J4i+l+Z6kPuxMOpbpBoZ4bGHahwA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=JdSMWdhk6gxByLsTvozsioj4exycRK1VVlXghbBQ4CTE8bTJAcC7PXAgT+mQ3JZEE V7X1pNjxOE8Pmspxj1sBNxVsBlcD39Ib6eO4GdtNsvzpk4IKgwgWF9bD6RMtdd1JLK 7lmpGCFUmxQVBqkT+kMR3is5vjFPZufhd1g9A+18CTyf+ibFCmziXXWy2R6KXHjv48 YZ+CzcIS4qNpJWaRvMVylhMINyxpTjjzTjH1dSAyJ+De3Nm1gGZYVbq9ZHSEJp5qm3 M5CcFHB3qQlUnO4ljE8BZZ2jmu6pua0Yz9S0YUhLs/jZr3d3zcTcPGkKH2jMpi78dO efP64zFBhGPeA== Subject: [PATCH 12/14] xfs: hoist the node iroot update code out of xfs_btree_kill_iroot From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865279.708933.8482908924042355927.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong In preparation for allowing records in an inode btree root, hoist the code that copies keyptrs from an existing node child into the root block to a separate function. Remove some unnecessary conditionals and clean up a few function calls in the new function. Note that this change reorders the ->free_block call with respect to the change in bc_nlevels to make it easier to support inode root leaf blocks in the next patch. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.c | 94 +++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 94df8c6000eb..d3e073a21063 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3716,6 +3716,63 @@ xfs_btree_insert( return error; } +/* + * Move the keyptrs from a child node block to the root block. + * + * Since the keyptr size does not change, all we have to do is increase the + * tree height, copy the keyptrs to the new internal node (cblock), shrink + * the root, and copy the pointers there. + */ +STATIC int +xfs_btree_demote_node_child( + struct xfs_btree_cur *cur, + struct xfs_btree_block *cblock, + int level, + int numrecs) +{ + struct xfs_btree_block *block; + union xfs_btree_key *ckp; + union xfs_btree_key *kp; + union xfs_btree_ptr *cpp; + union xfs_btree_ptr *pp; + int i; + int error; + int diff; + + /* + * Adjust the root btree node size and the record count to match the + * doomed child so that we can copy the keyptrs ahead of changing the + * tree shape. + */ + diff = numrecs - cur->bc_ops->get_maxrecs(cur, level); + xfs_btree_iroot_realloc(cur, diff); + block = xfs_btree_get_iroot(cur); + + xfs_btree_set_numrecs(block, numrecs); + ASSERT(block->bb_numrecs == cblock->bb_numrecs); + + /* Copy keys from the doomed block. */ + kp = xfs_btree_key_addr(cur, 1, block); + ckp = xfs_btree_key_addr(cur, 1, cblock); + xfs_btree_copy_keys(cur, kp, ckp, numrecs); + + /* Copy pointers from the doomed block. */ + pp = xfs_btree_ptr_addr(cur, 1, block); + cpp = xfs_btree_ptr_addr(cur, 1, cblock); + for (i = 0; i < numrecs; i++) { + error = xfs_btree_debug_check_ptr(cur, cpp, i, level - 1); + if (error) + return error; + } + xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); + + /* Decrease tree height, adjusting the root block level to match. */ + cur->bc_levels[level - 1].bp = NULL; + be16_add_cpu(&block->bb_level, -1); + cur->bc_nlevels--; + return 0; +} + /* * Try to merge a non-leaf block back into the inode root. * @@ -3728,24 +3785,16 @@ STATIC int xfs_btree_kill_iroot( struct xfs_btree_cur *cur) { - int whichfork = cur->bc_ino.whichfork; struct xfs_inode *ip = cur->bc_ino.ip; - struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork); struct xfs_btree_block *block; struct xfs_btree_block *cblock; - union xfs_btree_key *kp; - union xfs_btree_key *ckp; - union xfs_btree_ptr *pp; - union xfs_btree_ptr *cpp; struct xfs_buf *cbp; int level; - int index; int numrecs; int error; #ifdef DEBUG union xfs_btree_ptr ptr; #endif - int i; ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); ASSERT(cur->bc_nlevels > 1); @@ -3785,39 +3834,16 @@ xfs_btree_kill_iroot( ASSERT(xfs_btree_ptr_is_null(cur, &ptr)); #endif - index = numrecs - cur->bc_ops->get_maxrecs(cur, level); - if (index) { - xfs_btree_iroot_realloc(cur, index); - block = ifp->if_broot; - } - - be16_add_cpu(&block->bb_numrecs, index); - ASSERT(block->bb_numrecs == cblock->bb_numrecs); - - kp = xfs_btree_key_addr(cur, 1, block); - ckp = xfs_btree_key_addr(cur, 1, cblock); - xfs_btree_copy_keys(cur, kp, ckp, numrecs); - - pp = xfs_btree_ptr_addr(cur, 1, block); - cpp = xfs_btree_ptr_addr(cur, 1, cblock); - - for (i = 0; i < numrecs; i++) { - error = xfs_btree_debug_check_ptr(cur, cpp, i, level - 1); - if (error) - return error; - } - - xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); + error = xfs_btree_demote_node_child(cur, cblock, level, numrecs); + if (error) + return error; error = xfs_btree_free_block(cur, cbp); if (error) return error; - cur->bc_levels[level - 1].bp = NULL; - be16_add_cpu(&block->bb_level, -1); xfs_trans_log_inode(cur->bc_tp, ip, XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork)); - cur->bc_nlevels--; out0: return 0; } From patchwork Fri Dec 30 22:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085399 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89D75C4332F for ; Sat, 31 Dec 2022 01:19:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236058AbiLaBTp (ORCPT ); Fri, 30 Dec 2022 20:19:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236057AbiLaBTp (ORCPT ); Fri, 30 Dec 2022 20:19:45 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E36461AD9A for ; Fri, 30 Dec 2022 17:19:43 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 95C20B81DF9 for ; Sat, 31 Dec 2022 01:19:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 35D2EC433EF; Sat, 31 Dec 2022 01:19:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449581; bh=jUVTKpPBbPz8GmXRI4LI/YrasP0iy3Y0LlZgDFr7TH8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=lgKLOVuT5mBzZSDPq1Gl4XcbESJOSUqxvirdcQ9ACyHLtKYI53tv1ZTvTM5VAL+yO b6iWQNmFuH/gfC34OkPzNv51mMIaIPj7+5+neNYtzNnVxMJ25U6uoC9WntrnotwGeX r2p66mYO2I9rP9Acr1783GQSvmiLvgCqZY/gZwtrOkNTPLqsQKxNy9FUaMTxAAjW8j ab52aOJ36WmEfvCuTYHfqRYB4GgS0wlq7j6ZNEkxAv1b7qfLl7VUhiB8hQWa0K4Ojg bRfkbP9ugi5G6W7SqkqRY5i5BxiOWxZz7l4cllEbE9E+haLwapAwO1JGHcMzQEIjD3 dzwzNtd6rXsPQ== Subject: [PATCH 13/14] xfs: support storing records in the inode core root From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:32 -0800 Message-ID: <167243865293.708933.10507661776400225777.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Add the necessary flags and code so that we can support storing leaf records in the inode root block of a btree. This hasn't been necessary before, but the realtime rmapbt will need to be able to do this. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.c | 150 ++++++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_btree.h | 1 fs/xfs/libxfs/xfs_btree_staging.c | 4 + 3 files changed, 141 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index d3e073a21063..18628542d316 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -267,6 +267,11 @@ xfs_btree_check_block( int level, /* level of the btree block */ struct xfs_buf *bp) /* buffer containing block, if any */ { + /* Don't check the inode-core root. */ + if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && + level == cur->bc_nlevels - 1) + return 0; + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return xfs_btree_check_lblock(cur, block, level, bp); else @@ -1570,12 +1575,16 @@ xfs_btree_log_recs( int first, int last) { + if (!bp) { + xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, + xfs_ilog_fbroot(cur->bc_ino.whichfork)); + return; + } xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); xfs_trans_log_buf(cur->bc_tp, bp, xfs_btree_rec_offset(cur, first), xfs_btree_rec_offset(cur, last + 1) - 1); - } /* @@ -3091,6 +3100,64 @@ xfs_btree_iroot_realloc( cur->bc_ops->iroot_ops, rec_diff); } +/* + * Move the records from a root leaf block to a separate block. + * + * Trickery here: The amount of memory that we need per record for the incore + * root block changes when we convert a leaf block to an internal block. + * Therefore, we copy leaf records into the new btree block (cblock) before + * freeing the incore root block and changing the tree height. + * + * Once we've changed the tree height, we allocate a new incore root block + * (which will now be an internal root block) and populate it with a pointer to + * cblock and the relevant keys. + */ +STATIC void +xfs_btree_promote_leaf_iroot( + struct xfs_btree_cur *cur, + struct xfs_btree_block *block, + struct xfs_buf *cbp, + union xfs_btree_ptr *cptr, + struct xfs_btree_block *cblock) +{ + union xfs_btree_rec *rp; + union xfs_btree_rec *crp; + union xfs_btree_key *kp; + union xfs_btree_ptr *pp; + size_t size; + int numrecs = xfs_btree_get_numrecs(block); + + /* Copy the records from the leaf root into the new child block. */ + rp = xfs_btree_rec_addr(cur, 1, block); + crp = xfs_btree_rec_addr(cur, 1, cblock); + xfs_btree_copy_recs(cur, crp, rp, numrecs); + + /* Zap the old root and change the tree height. */ + xfs_iroot_free(cur->bc_ino.ip, cur->bc_ino.whichfork); + cur->bc_nlevels++; + cur->bc_levels[1].ptr = 1; + + /* + * Allocate a new internal root block buffer and reinitialize it to + * point to a single new child. + */ + size = cur->bc_ops->iroot_ops->size(cur->bc_mp, cur->bc_nlevels - 1, 1); + xfs_iroot_alloc(cur->bc_ino.ip, cur->bc_ino.whichfork, size); + block = xfs_btree_get_iroot(cur); + xfs_btree_init_block(cur->bc_mp, block, cur->bc_ops, + cur->bc_nlevels - 1, 1, cur->bc_ino.ip->i_ino); + + pp = xfs_btree_ptr_addr(cur, 1, block); + kp = xfs_btree_key_addr(cur, 1, block); + xfs_btree_copy_ptrs(cur, pp, cptr, 1); + xfs_btree_get_keys(cur, cblock, kp); + + /* Attach the new block to the cursor and log it. */ + xfs_btree_setbuf(cur, 0, cbp); + xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); + xfs_btree_log_recs(cur, cbp, 1, numrecs); +} + /* * Move the keys and pointers from a root block to a separate block. * @@ -3175,7 +3242,7 @@ xfs_btree_new_iroot( struct xfs_buf *cbp; /* buffer for cblock */ struct xfs_btree_block *block; /* btree block */ struct xfs_btree_block *cblock; /* child btree block */ - union xfs_btree_ptr *pp; + union xfs_btree_ptr aptr; union xfs_btree_ptr nptr; /* new block addr */ int level; /* btree level */ int error; /* error return code */ @@ -3187,10 +3254,15 @@ xfs_btree_new_iroot( level = cur->bc_nlevels - 1; block = xfs_btree_get_iroot(cur); - pp = xfs_btree_ptr_addr(cur, 1, block); + ASSERT(level > 0 || (cur->bc_flags & XFS_BTREE_IROOT_RECORDS)); + if (level > 0) + aptr = *xfs_btree_ptr_addr(cur, 1, block); + else + aptr.l = cpu_to_be64(XFS_INO_TO_FSB(cur->bc_mp, + cur->bc_ino.ip->i_ino)); /* Allocate the new block. If we can't do it, we're toast. Give up. */ - error = xfs_btree_alloc_block(cur, pp, &nptr, stat); + error = xfs_btree_alloc_block(cur, &aptr, &nptr, stat); if (error) goto error0; if (*stat == 0) @@ -3216,10 +3288,14 @@ xfs_btree_new_iroot( cblock->bb_u.s.bb_blkno = bno; } - error = xfs_btree_promote_node_iroot(cur, block, level, cbp, &nptr, - cblock); - if (error) - goto error0; + if (level > 0) { + error = xfs_btree_promote_node_iroot(cur, block, level, cbp, + &nptr, cblock); + if (error) + goto error0; + } else { + xfs_btree_promote_leaf_iroot(cur, block, cbp, &nptr, cblock); + } *logflags |= XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork); @@ -3716,6 +3792,45 @@ xfs_btree_insert( return error; } +/* + * Move the records from a child leaf block to the root block. + * + * Trickery here: The amount of memory we need per record for the incore root + * block changes when we convert a leaf block to an internal block. Therefore, + * we free the incore root block, change the tree height, allocate a new incore + * root, and copy the records from the doomed block into the new root. + */ +STATIC void +xfs_btree_demote_leaf_child( + struct xfs_btree_cur *cur, + struct xfs_btree_block *cblock, + int numrecs) +{ + union xfs_btree_rec *rp; + union xfs_btree_rec *crp; + struct xfs_btree_block *block; + size_t size; + + /* Zap the old root and change the tree height. */ + xfs_iroot_free(cur->bc_ino.ip, cur->bc_ino.whichfork); + cur->bc_levels[0].bp = NULL; + cur->bc_nlevels--; + + /* + * Allocate a new internal root block buffer and reinitialize it with + * the leaf records in the child. + */ + size = cur->bc_ops->iroot_ops->size(cur->bc_mp, 0, numrecs); + xfs_iroot_alloc(cur->bc_ino.ip, cur->bc_ino.whichfork, size); + block = xfs_btree_get_iroot(cur); + xfs_btree_init_block(cur->bc_mp, block, cur->bc_ops, 0, numrecs, + cur->bc_ino.ip->i_ino); + + rp = xfs_btree_rec_addr(cur, 1, block); + crp = xfs_btree_rec_addr(cur, 1, cblock); + xfs_btree_copy_recs(cur, rp, crp, numrecs); +} + /* * Move the keyptrs from a child node block to the root block. * @@ -3797,14 +3912,19 @@ xfs_btree_kill_iroot( #endif ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); - ASSERT(cur->bc_nlevels > 1); + ASSERT((cur->bc_flags & XFS_BTREE_IROOT_RECORDS) || + cur->bc_nlevels > 1); /* * Don't deal with the root block needs to be a leaf case. * We're just going to turn the thing back into extents anyway. */ level = cur->bc_nlevels - 1; - if (level == 1) + if (level == 1 && !(cur->bc_flags & XFS_BTREE_IROOT_RECORDS)) + goto out0; + + /* If we're already a leaf, jump out. */ + if (level == 0) goto out0; /* @@ -3834,9 +3954,13 @@ xfs_btree_kill_iroot( ASSERT(xfs_btree_ptr_is_null(cur, &ptr)); #endif - error = xfs_btree_demote_node_child(cur, cblock, level, numrecs); - if (error) - return error; + if (level > 1) { + error = xfs_btree_demote_node_child(cur, cblock, level, + numrecs); + if (error) + return error; + } else + xfs_btree_demote_leaf_child(cur, cblock, numrecs); error = xfs_btree_free_block(cur, cbp); if (error) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 3acfdcdf7561..b15bc77369cf 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -334,6 +334,7 @@ xfs_btree_cur_sizeof(unsigned int nlevels) * is dynamically allocated and must be freed when the cursor is deleted. */ #define XFS_BTREE_STAGING (1<<5) +#define XFS_BTREE_IROOT_RECORDS (1<<6) /* iroot can store records */ /* btree stored in memory; not compatible with ROOT_IN_INODE */ #ifdef CONFIG_XFS_IN_MEMORY_BTREE diff --git a/fs/xfs/libxfs/xfs_btree_staging.c b/fs/xfs/libxfs/xfs_btree_staging.c index 73d9aaeafead..d647b40351c8 100644 --- a/fs/xfs/libxfs/xfs_btree_staging.c +++ b/fs/xfs/libxfs/xfs_btree_staging.c @@ -699,7 +699,9 @@ xfs_btree_bload_compute_geometry( * * Note that bmap btrees forbid records in the root. */ - if (level != 0 && nr_this_level <= avg_per_block) { + if ((level != 0 || + (cur->bc_flags & XFS_BTREE_IROOT_RECORDS)) && + nr_this_level <= avg_per_block) { nr_blocks++; break; } From patchwork Fri Dec 30 22:17:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085400 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47A07C4332F for ; Sat, 31 Dec 2022 01:20:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236059AbiLaBUB (ORCPT ); Fri, 30 Dec 2022 20:20:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236057AbiLaBUA (ORCPT ); Fri, 30 Dec 2022 20:20:00 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 573A91AD9A for ; Fri, 30 Dec 2022 17:19:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 159E6B81DDA for ; Sat, 31 Dec 2022 01:19:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B528CC433D2; Sat, 31 Dec 2022 01:19:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672449596; bh=PdQBP08GXvZVZHVT/QpbHZ2xdyVlqEdZOeepipZ4nqQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=HRNUmyasy8bVMOXR3lZ4HAbopzTY7lyDEYearvNgQCC/CPxQsF0Vto7m+UYD9PTwC ktK289kj57oYmOYeQ3Bz70aA+0XerL0+TDhGKVVWfYzp+zhlL1+hwV7l+pkx71LaAl zEgIi3HA+mEMgETYT+vabRvlwrJwGcKbmIAusUs+JumKJQfKhRemyZnwCjaaEjniM4 aS1vfbohqJIwhfoKG1DcPkh8XR71+dbKVxb4sKKVv5Hwi6AiQscPrTdJYm21vo3HZ0 tAMQg/DuXwJigFI7MYezStvIu7D+vxuc3UCKA3yBItrncmAPqMU2zDbe5Hza8xMOCi owL/Fso/aoulA== Subject: [PATCH 14/14] xfs: update btree keys correctly when _insrec splits an inode root block From: "Darrick J. Wong" To: djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:17:33 -0800 Message-ID: <167243865308.708933.13650417799146260510.stgit@magnolia> In-Reply-To: <167243865089.708933.5645420573863731083.stgit@magnolia> References: <167243865089.708933.5645420573863731083.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong In commit 2c813ad66a72, I partially fixed a bug wherein xfs_btree_insrec would erroneously try to update the parent's key for a block that had been split if we decided to insert the new record into the new block. The solution was to detect this situation and update the in-core key value that we pass up to the caller so that the caller will (eventually) add the new block to the parent level of the tree with the correct key. However, I missed a subtlety about the way inode-rooted btrees work. If the full block was a maximally sized inode root block, we'll solve that fullness by moving the root block's records to a new block, resizing the root block, and updating the root to point to the new block. We don't pass a pointer to the new block to the caller because that work has already been done. The new record will /always/ land in the new block, so in this case we need to use xfs_btree_update_keys to update the keys. This bug can theoretically manifest itself in the very rare case that we split a bmbt root block and the new record lands in the very first slot of the new block, though I've never managed to trigger it in practice. However, it is very easy to reproduce by running generic/522 with the realtime rmapbt patchset if rtinherit=1. Fixes: 2c813ad66a72 ("xfs: support btrees with overlapping intervals for keys") Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 18628542d316..00bc1dd73675 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3665,14 +3665,31 @@ xfs_btree_insrec( xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS); /* - * If we just inserted into a new tree block, we have to - * recalculate nkey here because nkey is out of date. + * Update btree keys to reflect the newly added record or keyptr. + * There are three cases here to be aware of. Normally, all we have to + * do is walk towards the root, updating keys as necessary. * - * Otherwise we're just updating an existing block (having shoved - * some records into the new tree block), so use the regular key - * update mechanism. + * If the caller had us target a full block for the insertion, we dealt + * with that by calling the _make_block_unfull function. If the + * "make unfull" function splits the block, it'll hand us back the key + * and pointer of the new block. We haven't yet added the new block to + * the next level up, so if we decide to add the new record to the new + * block (bp->b_bn != old_bn), we have to update the caller's pointer + * so that the caller adds the new block with the correct key. + * + * However, there is a third possibility-- if the selected block is the + * root block of an inode-rooted btree and cannot be expanded further, + * the "make unfull" function moves the root block contents to a new + * block and updates the root block to point to the new block. In this + * case, no block pointer is passed back because the block has already + * been added to the btree. In this case, we need to use the regular + * key update function, just like the first case. This is critical for + * overlapping btrees, because the high key must be updated to reflect + * the entire tree, not just the subtree accessible through the first + * child of the root (which is now two levels down from the root). */ - if (bp && xfs_buf_daddr(bp) != old_bn) { + if (!xfs_btree_ptr_is_null(cur, &nptr) && + bp && xfs_buf_daddr(bp) != old_bn) { xfs_btree_get_keys(cur, block, lkey); } else if (xfs_btree_needs_key_update(cur, optr)) { error = xfs_btree_update_keys(cur, level);