From patchwork Tue Oct 12 23:32:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553933 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5959C433F5 for ; Tue, 12 Oct 2021 23:32:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF5F760ED4 for ; Tue, 12 Oct 2021 23:32:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235541AbhJLXem (ORCPT ); Tue, 12 Oct 2021 19:34:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:48086 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234169AbhJLXel (ORCPT ); Tue, 12 Oct 2021 19:34:41 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8D6DA60E53; Tue, 12 Oct 2021 23:32:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081559; bh=4F6K/QG6wH1qhqYOUuEKtyGHLGPZG8SV64N8qHlbXWI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=uG0MrFBDa+CFdsTIq12y/sAm1Mgr2CvOQ6JDPUld2koLZzu2aJ0WR5JY9XFBoky8m e0+NBgFADCXer7su+AApDxQaijpyLK0l+7YTs31s+SeBTkKZY/0YlLMnvX/cg82Rif HguaivSCZ17IOiVghg0Xk5HUJKwUFuFwoXJFrcYc3DylJL/u6ilDWqZy50XMhppbU8 5gci9mVzA94GllI5fqcDY8WjXJ6Md5RnC6bWKQDpyjBvpn8Ov3ZzXua4tde1fOExXa /V+a0swCtiNLjbHrCyZ/LX+D7jzZpqYHGs+afQRCfDX5KKihGN1Z2ZtlVJwU7eBoIp MuKGinsB5quug== Subject: [PATCH 01/15] xfs: remove xfs_btree_cur.bc_blocklog From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:32:39 -0700 Message-ID: <163408155929.4151249.7734053676233395860.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 This field isn't used by anyone, so get rid of it. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc_btree.c | 1 - fs/xfs/libxfs/xfs_bmap_btree.c | 1 - fs/xfs/libxfs/xfs_btree.h | 1 - fs/xfs/libxfs/xfs_ialloc_btree.c | 2 -- fs/xfs/libxfs/xfs_refcount_btree.c | 1 - fs/xfs/libxfs/xfs_rmap_btree.c | 1 - 6 files changed, 7 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 6746fd735550..152ed2a202f4 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -482,7 +482,6 @@ xfs_allocbt_init_common( cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_btnum = btnum; - cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_ag.abt.active = false; if (btnum == XFS_BTNUM_CNT) { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 72444b8b38a6..a43dea8d6a65 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -558,7 +558,6 @@ xfs_bmbt_init_cursor( cur->bc_mp = mp; cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; cur->bc_btnum = XFS_BTNUM_BMAP; - cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2); cur->bc_ops = &xfs_bmbt_ops; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 513ade4a89f8..49ecc496238f 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -229,7 +229,6 @@ struct xfs_btree_cur #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ uint8_t bc_nlevels; /* number of levels in the tree */ - uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ xfs_btnum_t bc_btnum; /* identifies which btree type */ int bc_statoff; /* offset of btre stats array */ diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 27190840c5d8..10736b89b679 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -444,8 +444,6 @@ xfs_inobt_init_common( cur->bc_ops = &xfs_finobt_ops; } - cur->bc_blocklog = mp->m_sb.sb_blocklog; - if (xfs_has_crc(mp)) cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 1ef9b99962ab..3ea589f15b14 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -326,7 +326,6 @@ xfs_refcountbt_init_common( cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_btnum = XFS_BTNUM_REFC; - cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index b7dbbfb3aeed..d65bf3c6f25e 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -457,7 +457,6 @@ xfs_rmapbt_init_common( /* Overlapping btree; 2 keys per pointer. */ cur->bc_btnum = XFS_BTNUM_RMAP; cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING; - cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); cur->bc_ops = &xfs_rmapbt_ops; From patchwork Tue Oct 12 23:32:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553935 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51041C433EF for ; Tue, 12 Oct 2021 23:32:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 371C260F3A for ; Tue, 12 Oct 2021 23:32:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236017AbhJLXer (ORCPT ); Tue, 12 Oct 2021 19:34:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:48128 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234169AbhJLXer (ORCPT ); Tue, 12 Oct 2021 19:34:47 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1461E60E53; Tue, 12 Oct 2021 23:32:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081565; bh=F4g2UazaWv01ejlMAQqqzohNcrUMXGAzdR+xqJn+Ol8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=R4tOIeR1ubp/m5BtNwvPsrWBznwyKLBTIWmCrpuuUQ/8FzE+rTsitKAguV4MIG/xx 3PrdpFpjJHWNI3xLNvfesW1gd9XPEI2ivgOUu+Aj/B2JC6M2+OSxyB6jN2ipt1UPI8 U7DTOKN72A3m8MyZGqbyNvun0DErzPEkJtPIWA5f+47NWUNnPdliLMk0NwOFQWhfxY K7n7PFK9uOPAjrnMhv22xGx8cmgrFNDEieE47JjlEFbllZcPC9+BVqvQswo0gpptde LulRpL5DVxmMt/jfX/U1BxHmcTay7AXIGEDgIXs9JujBi/Nb5PDo9sxSsy9kPglJIT wsr0FAFlfg34Q== Subject: [PATCH 02/15] xfs: reduce the size of nr_ops for refcount btree cursors From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:32:44 -0700 Message-ID: <163408156479.4151249.4245850917668794754.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 We're never going to run more than 4 billion btree operations on a refcount cursor, so shrink the field to an unsigned int to reduce the structure size. Fix whitespace alignment too. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 49ecc496238f..1018bcc43d66 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -181,18 +181,18 @@ union xfs_btree_irec { /* Per-AG btree information. */ struct xfs_btree_cur_ag { - struct xfs_perag *pag; + struct xfs_perag *pag; union { struct xfs_buf *agbp; struct xbtree_afakeroot *afake; /* for staging cursor */ }; union { struct { - unsigned long nr_ops; /* # record updates */ - int shape_changes; /* # of extent splits */ + unsigned int nr_ops; /* # record updates */ + unsigned int shape_changes; /* # of extent splits */ } refc; struct { - bool active; /* allocation cursor state */ + bool active; /* allocation cursor state */ } abt; }; }; From patchwork Tue Oct 12 23:32:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553937 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC703C433EF for ; Tue, 12 Oct 2021 23:32:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C620B60E53 for ; Tue, 12 Oct 2021 23:32:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235952AbhJLXez (ORCPT ); Tue, 12 Oct 2021 19:34:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:48158 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236036AbhJLXew (ORCPT ); Tue, 12 Oct 2021 19:34:52 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 87F9D60EBB; Tue, 12 Oct 2021 23:32:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081570; bh=sNJjbq4zgu3E7qHYyP8nBf4+O8vWbDjXD5+5DlzGGkM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=cDjDaRYRf6HnXLmOBBMErv40bhxhwPwIKh6v+5AFW1XK3zGT2p38k5lHvBHMWjsG1 jm9QeT0MV0NTDqd+1lYyAg7wLTxK+E4w42BAamSE27ATVg2ohZfZADCPVf86o/Jg0H dvz/0d2ND33uboMg4CnR5+o3qCrdzBqIU7P5S32EHlVEkXiel1e13MVCsprDvkw2/t ucESyRpaICGgy6GSxEU34U0XAdaTwwN58yO92NnOxrGI7503o0QYtXZNX4x12aWnKh T6RSCIGh8pheAeJ/HGlq09eQDQQ3Y0zlvA0FWyjD6TUytBI6MOd/ViSvJ3IQQZUQbY Vo502u6VOH3vw== Subject: [PATCH 03/15] xfs: don't track firstrec/firstkey separately in xchk_btree From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:32:50 -0700 Message-ID: <163408157028.4151249.16573862981315637553.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 btree scrubbing code checks that the records (or keys) that it finds in a btree block are all in order by calling the btree cursor's ->recs_inorder function. This of course makes no sense for the first item in the block, so we switch that off with a separate variable in struct xchk_btree. Christoph helped me figure out that the variable is unnecessary, since we just accessed bc_ptrs[level] and can compare that against zero. Use that, and save ourselves some memory space. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/scrub/btree.c | 11 +++-------- fs/xfs/scrub/btree.h | 2 -- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index 26dcb4691e31..d5e1ca521fc4 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -141,9 +141,9 @@ xchk_btree_rec( trace_xchk_btree_rec(bs->sc, cur, 0); /* If this isn't the first record, are they in order? */ - if (!bs->firstrec && !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec)) + if (cur->bc_ptrs[0] > 1 && + !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec)) xchk_btree_set_corrupt(bs->sc, cur, 0); - bs->firstrec = false; memcpy(&bs->lastrec, rec, cur->bc_ops->rec_len); if (cur->bc_nlevels == 1) @@ -188,10 +188,9 @@ xchk_btree_key( trace_xchk_btree_key(bs->sc, cur, level); /* If this isn't the first key, are they in order? */ - if (!bs->firstkey[level] && + if (cur->bc_ptrs[level] > 1 && !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level], key)) xchk_btree_set_corrupt(bs->sc, cur, level); - bs->firstkey[level] = false; memcpy(&bs->lastkey[level], key, cur->bc_ops->key_len); if (level + 1 >= cur->bc_nlevels) @@ -636,7 +635,6 @@ xchk_btree( struct xfs_buf *bp; struct check_owner *co; struct check_owner *n; - int i; int error = 0; /* @@ -649,13 +647,10 @@ xchk_btree( bs->cur = cur; bs->scrub_rec = scrub_fn; bs->oinfo = oinfo; - bs->firstrec = true; bs->private = private; bs->sc = sc; /* Initialize scrub state */ - for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) - bs->firstkey[i] = true; INIT_LIST_HEAD(&bs->to_check); /* Don't try to check a tree with a height we can't handle. */ diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h index b7d2fc01fbf9..7671108f9f85 100644 --- a/fs/xfs/scrub/btree.h +++ b/fs/xfs/scrub/btree.h @@ -39,9 +39,7 @@ struct xchk_btree { /* internal scrub state */ union xfs_btree_rec lastrec; - bool firstrec; union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS]; - bool firstkey[XFS_BTREE_MAXLEVELS]; struct list_head to_check; }; int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, From patchwork Tue Oct 12 23:32:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553939 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D1A1C433F5 for ; Tue, 12 Oct 2021 23:32:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 35CF960EB6 for ; Tue, 12 Oct 2021 23:32:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236020AbhJLXe6 (ORCPT ); Tue, 12 Oct 2021 19:34:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:48182 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234169AbhJLXe6 (ORCPT ); Tue, 12 Oct 2021 19:34:58 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 0C9EF60ED4; Tue, 12 Oct 2021 23:32:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081576; bh=xIxgn0LFOJwHz4W92pNB2OQeNrfhXlpB/xkQp4rb+7Y=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=ldrxS2nArEdEacA1D0NiABwL6lTWF2v+Cn1S2Mkx9cwuZ04edO1RqNJiVnXTHIg9l Ljbx9UhzLMjQOZetAmMvT0AffkNufLS30SFOv1Dz86BRX/vfPJORjiEPc7+T19lUCc RSr2tfXQdCf0pRNRZszTfw7iDKRRFeXpAX7rRjxEa8khisADSVr1XPZSTidNKSy2pj XTgRac0H72e4P1GrTnsnFv8RcOMVyfciXMHjBB5gtbVoJgJpgZwol/OV2iD66T8v0W 6LYNSRsFT2fV91f7Yb6OJh6Fik0WNeIUpRVoIQh9u9LBLKutYS7H+c1zN5mvCtPwfF Bjj9rqdZAZPdA== Subject: [PATCH 04/15] xfs: dynamically allocate btree scrub context structure From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:32:55 -0700 Message-ID: <163408157576.4151249.1044656167414078424.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Reorganize struct xchk_btree so that we can dynamically size the context structure to fit the type of btree cursor that we have. This will enable us to use memory more efficiently once we start adding very tall btree types. Right-size the lastkey array so that we stop wasting the first array element. Signed-off-by: Darrick J. Wong --- fs/xfs/scrub/btree.c | 23 ++++++++++++----------- fs/xfs/scrub/btree.h | 11 ++++++++++- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index d5e1ca521fc4..6d4eba85ef77 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -189,9 +189,9 @@ xchk_btree_key( /* If this isn't the first key, are they in order? */ if (cur->bc_ptrs[level] > 1 && - !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level], key)) + !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level - 1], key)) xchk_btree_set_corrupt(bs->sc, cur, level); - memcpy(&bs->lastkey[level], key, cur->bc_ops->key_len); + memcpy(&bs->lastkey[level - 1], key, cur->bc_ops->key_len); if (level + 1 >= cur->bc_nlevels) return; @@ -631,17 +631,24 @@ xchk_btree( union xfs_btree_ptr *pp; union xfs_btree_rec *recp; struct xfs_btree_block *block; - int level; struct xfs_buf *bp; struct check_owner *co; struct check_owner *n; + size_t cur_sz; + int level; int error = 0; /* * Allocate the btree scrub context from the heap, because this - * structure can get rather large. + * structure can get rather large. Don't let a caller feed us a + * totally absurd size. */ - bs = kmem_zalloc(sizeof(struct xchk_btree), KM_NOFS | KM_MAYFAIL); + cur_sz = xchk_btree_sizeof(cur->bc_nlevels); + if (cur_sz > PAGE_SIZE) { + xchk_btree_set_corrupt(sc, cur, 0); + return 0; + } + bs = kmem_zalloc(cur_sz, KM_NOFS | KM_MAYFAIL); if (!bs) return -ENOMEM; bs->cur = cur; @@ -653,12 +660,6 @@ xchk_btree( /* Initialize scrub state */ INIT_LIST_HEAD(&bs->to_check); - /* Don't try to check a tree with a height we can't handle. */ - if (cur->bc_nlevels > XFS_BTREE_MAXLEVELS) { - xchk_btree_set_corrupt(sc, cur, 0); - goto out; - } - /* * Load the root of the btree. The helper function absorbs * error codes for us. diff --git a/fs/xfs/scrub/btree.h b/fs/xfs/scrub/btree.h index 7671108f9f85..62c3091ef20f 100644 --- a/fs/xfs/scrub/btree.h +++ b/fs/xfs/scrub/btree.h @@ -39,9 +39,18 @@ struct xchk_btree { /* internal scrub state */ union xfs_btree_rec lastrec; - union xfs_btree_key lastkey[XFS_BTREE_MAXLEVELS]; struct list_head to_check; + + /* this element must come last! */ + union xfs_btree_key lastkey[]; }; + +static inline size_t +xchk_btree_sizeof(unsigned int nlevels) +{ + return struct_size((struct xchk_btree *)NULL, lastkey, nlevels - 1); +} + int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur, xchk_btree_rec_fn scrub_fn, const struct xfs_owner_info *oinfo, void *private); From patchwork Tue Oct 12 23:33:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553941 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 040F1C433EF for ; Tue, 12 Oct 2021 23:33:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DF6AE60EB6 for ; Tue, 12 Oct 2021 23:33:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233870AbhJLXfE (ORCPT ); Tue, 12 Oct 2021 19:35:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:48214 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234169AbhJLXfD (ORCPT ); Tue, 12 Oct 2021 19:35:03 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8CD9260E53; Tue, 12 Oct 2021 23:33:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081581; bh=IoP8ACdtRhWVfT8Qj9RArcOyswVJ908AaIRT92LyUks=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=H1WMJlY96cArFTSLU+aamo7NRRMVzsL8S48ugyyjGsY10O5Zvg2BlCi/C8/uR9AmK LgzZWqJDOslqbLa4avrkw8keKrW6VHreAkLBDXtz4N98R9oNr2jk07+QAdT5B+HXwG IrCitQBQAT+GPlJZAnHfHorFP6hOnBE503hxn2wb4cNIqLmKOAaY0yiwi2mtrpzRuo WME/wJF7PTWtYZd5/sOFoLpKi5GSzC0HFo32kMQqO7bSOUe48sQIqqTdG3tJ4hIliu 59hcPJI4zkDRdk6x2XSWPTIih1MOQkhYAACPfl/1JGUhVmNYdovQhjmqCqklnEs7sz WEe3DJA4U/b9g== Subject: [PATCH 05/15] xfs: support dynamic btree cursor heights From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: Chandan Babu R , Christoph Hellwig , linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:01 -0700 Message-ID: <163408158126.4151249.1899753599807152513.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Split out the btree level information into a separate struct and put it at the end of the cursor structure as a VLA. The realtime rmap btree (which is rooted in an inode) will require the ability to support many more levels than a per-AG btree cursor, which means that we're going to create two btree cursor caches to conserve memory for the more common case. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_alloc.c | 6 +- fs/xfs/libxfs/xfs_bmap.c | 10 +-- fs/xfs/libxfs/xfs_btree.c | 168 +++++++++++++++++++++++---------------------- fs/xfs/libxfs/xfs_btree.h | 28 ++++++-- fs/xfs/scrub/bitmap.c | 22 +++--- fs/xfs/scrub/bmap.c | 2 - fs/xfs/scrub/btree.c | 47 +++++++------ fs/xfs/scrub/trace.c | 7 +- fs/xfs/scrub/trace.h | 10 +-- fs/xfs/xfs_super.c | 2 - fs/xfs/xfs_trace.h | 2 - 11 files changed, 164 insertions(+), 140 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 35fb1dd3be95..55c5adc9b54e 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -488,8 +488,8 @@ xfs_alloc_fixup_trees( struct xfs_btree_block *bnoblock; struct xfs_btree_block *cntblock; - bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); - cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); + bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_levels[0].bp); + cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_levels[0].bp); if (XFS_IS_CORRUPT(mp, bnoblock->bb_numrecs != @@ -1512,7 +1512,7 @@ xfs_alloc_ag_vextent_lastblock( * than minlen. */ if (*len || args->alignment > 1) { - acur->cnt->bc_ptrs[0] = 1; + acur->cnt->bc_levels[0].ptr = 1; do { error = xfs_alloc_get_rec(acur->cnt, bno, len, &i); if (error) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 499c977cbf56..644b956301b6 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -240,10 +240,10 @@ xfs_bmap_get_bp( return NULL; for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) { - if (!cur->bc_bufs[i]) + if (!cur->bc_levels[i].bp) break; - if (xfs_buf_daddr(cur->bc_bufs[i]) == bno) - return cur->bc_bufs[i]; + if (xfs_buf_daddr(cur->bc_levels[i].bp) == bno) + return cur->bc_levels[i].bp; } /* Chase down all the log items to see if the bp is there */ @@ -629,8 +629,8 @@ xfs_bmap_btree_to_extents( ip->i_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); - if (cur->bc_bufs[0] == cbp) - cur->bc_bufs[0] = NULL; + if (cur->bc_levels[0].bp == cbp) + cur->bc_levels[0].bp = NULL; xfs_iroot_realloc(ip, -1, whichfork); ASSERT(ifp->if_broot == NULL); ifp->if_format = XFS_DINODE_FMT_EXTENTS; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index bc4e49f0456a..25dfab81025f 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -367,8 +367,8 @@ xfs_btree_del_cursor( * way we won't have initialized all the entries down to 0. */ for (i = 0; i < cur->bc_nlevels; i++) { - if (cur->bc_bufs[i]) - xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]); + if (cur->bc_levels[i].bp) + xfs_trans_brelse(cur->bc_tp, cur->bc_levels[i].bp); else if (!error) break; } @@ -415,9 +415,9 @@ xfs_btree_dup_cursor( * For each level current, re-get the buffer and copy the ptr value. */ for (i = 0; i < new->bc_nlevels; i++) { - new->bc_ptrs[i] = cur->bc_ptrs[i]; - new->bc_ra[i] = cur->bc_ra[i]; - bp = cur->bc_bufs[i]; + new->bc_levels[i].ptr = cur->bc_levels[i].ptr; + new->bc_levels[i].ra = cur->bc_levels[i].ra; + bp = cur->bc_levels[i].bp; if (bp) { error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, xfs_buf_daddr(bp), mp->m_bsize, @@ -429,7 +429,7 @@ xfs_btree_dup_cursor( return error; } } - new->bc_bufs[i] = bp; + new->bc_levels[i].bp = bp; } *ncur = new; return 0; @@ -681,7 +681,7 @@ xfs_btree_get_block( return xfs_btree_get_iroot(cur); } - *bpp = cur->bc_bufs[level]; + *bpp = cur->bc_levels[level].bp; return XFS_BUF_TO_BLOCK(*bpp); } @@ -711,7 +711,7 @@ xfs_btree_firstrec( /* * Set the ptr value to 1, that's the first record/key. */ - cur->bc_ptrs[level] = 1; + cur->bc_levels[level].ptr = 1; return 1; } @@ -741,7 +741,7 @@ xfs_btree_lastrec( /* * Set the ptr value to numrecs, that's the last record/key. */ - cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs); + cur->bc_levels[level].ptr = be16_to_cpu(block->bb_numrecs); return 1; } @@ -922,11 +922,11 @@ xfs_btree_readahead( (lev == cur->bc_nlevels - 1)) return 0; - if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev]) + if ((cur->bc_levels[lev].ra | lr) == cur->bc_levels[lev].ra) return 0; - cur->bc_ra[lev] |= lr; - block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]); + cur->bc_levels[lev].ra |= lr; + block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) return xfs_btree_readahead_lblock(cur, lr, block); @@ -991,22 +991,22 @@ xfs_btree_setbuf( { struct xfs_btree_block *b; /* btree block */ - if (cur->bc_bufs[lev]) - xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[lev]); - cur->bc_bufs[lev] = bp; - cur->bc_ra[lev] = 0; + if (cur->bc_levels[lev].bp) + xfs_trans_brelse(cur->bc_tp, cur->bc_levels[lev].bp); + cur->bc_levels[lev].bp = bp; + cur->bc_levels[lev].ra = 0; b = XFS_BUF_TO_BLOCK(bp); if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK)) - cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; + cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA; if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK)) - cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; + cur->bc_levels[lev].ra |= XFS_BTCUR_RIGHTRA; } else { if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK)) - cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; + cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA; if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK)) - cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; + cur->bc_levels[lev].ra |= XFS_BTCUR_RIGHTRA; } } @@ -1548,7 +1548,7 @@ xfs_btree_increment( #endif /* We're done if we remain in the block after the increment. */ - if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block)) + if (++cur->bc_levels[level].ptr <= xfs_btree_get_numrecs(block)) goto out1; /* Fail if we just went off the right edge of the tree. */ @@ -1571,7 +1571,7 @@ xfs_btree_increment( goto error0; #endif - if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block)) + if (++cur->bc_levels[lev].ptr <= xfs_btree_get_numrecs(block)) break; /* Read-ahead the right block for the next loop. */ @@ -1598,14 +1598,14 @@ xfs_btree_increment( for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { union xfs_btree_ptr *ptrp; - ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); + ptrp = xfs_btree_ptr_addr(cur, cur->bc_levels[lev].ptr, block); --lev; error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp); if (error) goto error0; xfs_btree_setbuf(cur, lev, bp); - cur->bc_ptrs[lev] = 1; + cur->bc_levels[lev].ptr = 1; } out1: *stat = 1; @@ -1641,7 +1641,7 @@ xfs_btree_decrement( xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA); /* We're done if we remain in the block after the decrement. */ - if (--cur->bc_ptrs[level] > 0) + if (--cur->bc_levels[level].ptr > 0) goto out1; /* Get a pointer to the btree block. */ @@ -1665,7 +1665,7 @@ xfs_btree_decrement( * Stop when we don't go off the left edge of a block. */ for (lev = level + 1; lev < cur->bc_nlevels; lev++) { - if (--cur->bc_ptrs[lev] > 0) + if (--cur->bc_levels[lev].ptr > 0) break; /* Read-ahead the left block for the next loop. */ xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA); @@ -1691,13 +1691,13 @@ xfs_btree_decrement( for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { union xfs_btree_ptr *ptrp; - ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); + ptrp = xfs_btree_ptr_addr(cur, cur->bc_levels[lev].ptr, block); --lev; error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp); if (error) goto error0; xfs_btree_setbuf(cur, lev, bp); - cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block); + cur->bc_levels[lev].ptr = xfs_btree_get_numrecs(block); } out1: *stat = 1; @@ -1735,7 +1735,7 @@ xfs_btree_lookup_get_block( * * Otherwise throw it away and get a new one. */ - bp = cur->bc_bufs[level]; + bp = cur->bc_levels[level].bp; error = xfs_btree_ptr_to_daddr(cur, pp, &daddr); if (error) return error; @@ -1864,7 +1864,7 @@ xfs_btree_lookup( return -EFSCORRUPTED; } - cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE; + cur->bc_levels[0].ptr = dir != XFS_LOOKUP_LE; *stat = 0; return 0; } @@ -1916,7 +1916,7 @@ xfs_btree_lookup( if (error) goto error0; - cur->bc_ptrs[level] = keyno; + cur->bc_levels[level].ptr = keyno; } } @@ -1933,7 +1933,7 @@ xfs_btree_lookup( !xfs_btree_ptr_is_null(cur, &ptr)) { int i; - cur->bc_ptrs[0] = keyno; + cur->bc_levels[0].ptr = keyno; error = xfs_btree_increment(cur, 0, &i); if (error) goto error0; @@ -1944,7 +1944,7 @@ xfs_btree_lookup( } } else if (dir == XFS_LOOKUP_LE && diff > 0) keyno--; - cur->bc_ptrs[0] = keyno; + cur->bc_levels[0].ptr = keyno; /* Return if we succeeded or not. */ if (keyno == 0 || keyno > xfs_btree_get_numrecs(block)) @@ -2104,7 +2104,7 @@ __xfs_btree_updkeys( if (error) return error; #endif - ptr = cur->bc_ptrs[level]; + ptr = cur->bc_levels[level].ptr; nlkey = xfs_btree_key_addr(cur, ptr, block); nhkey = xfs_btree_high_key_addr(cur, ptr, block); if (!force_all && @@ -2171,7 +2171,7 @@ xfs_btree_update_keys( if (error) return error; #endif - ptr = cur->bc_ptrs[level]; + ptr = cur->bc_levels[level].ptr; kp = xfs_btree_key_addr(cur, ptr, block); xfs_btree_copy_keys(cur, kp, &key, 1); xfs_btree_log_keys(cur, bp, ptr, ptr); @@ -2205,7 +2205,7 @@ xfs_btree_update( goto error0; #endif /* Get the address of the rec to be updated. */ - ptr = cur->bc_ptrs[0]; + ptr = cur->bc_levels[0].ptr; rp = xfs_btree_rec_addr(cur, ptr, block); /* Fill in the new contents and log them. */ @@ -2280,7 +2280,7 @@ xfs_btree_lshift( * If the cursor entry is the one that would be moved, don't * do it... it's too complicated. */ - if (cur->bc_ptrs[level] <= 1) + if (cur->bc_levels[level].ptr <= 1) goto out0; /* Set up the left neighbor as "left". */ @@ -2414,7 +2414,7 @@ xfs_btree_lshift( goto error0; /* Slide the cursor value left one. */ - cur->bc_ptrs[level]--; + cur->bc_levels[level].ptr--; *stat = 1; return 0; @@ -2476,7 +2476,7 @@ xfs_btree_rshift( * do it... it's too complicated. */ lrecs = xfs_btree_get_numrecs(left); - if (cur->bc_ptrs[level] >= lrecs) + if (cur->bc_levels[level].ptr >= lrecs) goto out0; /* Set up the right neighbor as "right". */ @@ -2664,7 +2664,7 @@ __xfs_btree_split( */ lrecs = xfs_btree_get_numrecs(left); rrecs = lrecs / 2; - if ((lrecs & 1) && cur->bc_ptrs[level] <= rrecs + 1) + if ((lrecs & 1) && cur->bc_levels[level].ptr <= rrecs + 1) rrecs++; src_index = (lrecs - rrecs + 1); @@ -2760,9 +2760,9 @@ __xfs_btree_split( * If it's just pointing past the last entry in left, then we'll * insert there, so don't change anything in that case. */ - if (cur->bc_ptrs[level] > lrecs + 1) { + if (cur->bc_levels[level].ptr > lrecs + 1) { xfs_btree_setbuf(cur, level, rbp); - cur->bc_ptrs[level] -= lrecs; + cur->bc_levels[level].ptr -= lrecs; } /* * If there are more levels, we'll need another cursor which refers @@ -2772,7 +2772,7 @@ __xfs_btree_split( error = xfs_btree_dup_cursor(cur, curp); if (error) goto error0; - (*curp)->bc_ptrs[level + 1]++; + (*curp)->bc_levels[level + 1].ptr++; } *ptrp = rptr; *stat = 1; @@ -2934,7 +2934,7 @@ xfs_btree_new_iroot( xfs_btree_set_numrecs(block, 1); cur->bc_nlevels++; ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); - cur->bc_ptrs[level + 1] = 1; + cur->bc_levels[level + 1].ptr = 1; kp = xfs_btree_key_addr(cur, 1, block); ckp = xfs_btree_key_addr(cur, 1, cblock); @@ -3095,7 +3095,7 @@ xfs_btree_new_root( /* Fix up the cursor. */ xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); - cur->bc_ptrs[cur->bc_nlevels] = nptr; + cur->bc_levels[cur->bc_nlevels].ptr = nptr; cur->bc_nlevels++; ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); *stat = 1; @@ -3154,7 +3154,7 @@ xfs_btree_make_block_unfull( return error; if (*stat) { - *oindex = *index = cur->bc_ptrs[level]; + *oindex = *index = cur->bc_levels[level].ptr; return 0; } @@ -3169,7 +3169,7 @@ xfs_btree_make_block_unfull( return error; - *index = cur->bc_ptrs[level]; + *index = cur->bc_levels[level].ptr; return 0; } @@ -3216,7 +3216,7 @@ xfs_btree_insrec( } /* If we're off the left edge, return failure. */ - ptr = cur->bc_ptrs[level]; + ptr = cur->bc_levels[level].ptr; if (ptr == 0) { *stat = 0; return 0; @@ -3559,7 +3559,7 @@ xfs_btree_kill_iroot( if (error) return error; - cur->bc_bufs[level - 1] = NULL; + 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)); @@ -3592,8 +3592,8 @@ xfs_btree_kill_root( if (error) return error; - cur->bc_bufs[level] = NULL; - cur->bc_ra[level] = 0; + cur->bc_levels[level].bp = NULL; + cur->bc_levels[level].ra = 0; cur->bc_nlevels--; return 0; @@ -3652,7 +3652,7 @@ xfs_btree_delrec( tcur = NULL; /* Get the index of the entry being deleted, check for nothing there. */ - ptr = cur->bc_ptrs[level]; + ptr = cur->bc_levels[level].ptr; if (ptr == 0) { *stat = 0; return 0; @@ -3962,7 +3962,7 @@ xfs_btree_delrec( xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); tcur = NULL; if (level == 0) - cur->bc_ptrs[0]++; + cur->bc_levels[0].ptr++; *stat = 1; return 0; @@ -4099,9 +4099,9 @@ xfs_btree_delrec( * cursor to the left block, and fix up the index. */ if (bp != lbp) { - cur->bc_bufs[level] = lbp; - cur->bc_ptrs[level] += lrecs; - cur->bc_ra[level] = 0; + cur->bc_levels[level].bp = lbp; + cur->bc_levels[level].ptr += lrecs; + cur->bc_levels[level].ra = 0; } /* * If we joined with the right neighbor and there's a level above @@ -4121,16 +4121,16 @@ xfs_btree_delrec( * We can't use decrement because it would change the next level up. */ if (level > 0) - cur->bc_ptrs[level]--; + cur->bc_levels[level].ptr--; /* * We combined blocks, so we have to update the parent keys if the - * btree supports overlapped intervals. However, bc_ptrs[level + 1] - * points to the old block so that the caller knows which record to - * delete. Therefore, the caller must be savvy enough to call updkeys - * for us if we return stat == 2. The other exit points from this - * function don't require deletions further up the tree, so they can - * call updkeys directly. + * btree supports overlapped intervals. However, + * bc_levels[level + 1].ptr points to the old block so that the caller + * knows which record to delete. Therefore, the caller must be savvy + * enough to call updkeys for us if we return stat == 2. The other + * exit points from this function don't require deletions further up + * the tree, so they can call updkeys directly. */ /* Return value means the next level up has something to do. */ @@ -4184,7 +4184,7 @@ xfs_btree_delete( if (i == 0) { for (level = 1; level < cur->bc_nlevels; level++) { - if (cur->bc_ptrs[level] == 0) { + if (cur->bc_levels[level].ptr == 0) { error = xfs_btree_decrement(cur, level, &i); if (error) goto error0; @@ -4215,7 +4215,7 @@ xfs_btree_get_rec( int error; /* error return value */ #endif - ptr = cur->bc_ptrs[0]; + ptr = cur->bc_levels[0].ptr; block = xfs_btree_get_block(cur, 0, &bp); #ifdef DEBUG @@ -4663,23 +4663,25 @@ xfs_btree_overlapped_query_range( if (error) goto out; #endif - cur->bc_ptrs[level] = 1; + cur->bc_levels[level].ptr = 1; while (level < cur->bc_nlevels) { block = xfs_btree_get_block(cur, level, &bp); /* End of node, pop back towards the root. */ - if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) { + if (cur->bc_levels[level].ptr > + be16_to_cpu(block->bb_numrecs)) { pop_up: if (level < cur->bc_nlevels - 1) - cur->bc_ptrs[level + 1]++; + cur->bc_levels[level + 1].ptr++; level++; continue; } if (level == 0) { /* Handle a leaf node. */ - recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block); + recp = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, + block); cur->bc_ops->init_high_key_from_rec(&rec_hkey, recp); ldiff = cur->bc_ops->diff_two_keys(cur, &rec_hkey, @@ -4702,14 +4704,15 @@ xfs_btree_overlapped_query_range( /* Record is larger than high key; pop. */ goto pop_up; } - cur->bc_ptrs[level]++; + cur->bc_levels[level].ptr++; continue; } /* Handle an internal node. */ - lkp = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block); - hkp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block); - pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block); + lkp = xfs_btree_key_addr(cur, cur->bc_levels[level].ptr, block); + hkp = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, + block); + pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block); ldiff = cur->bc_ops->diff_two_keys(cur, hkp, low_key); hdiff = cur->bc_ops->diff_two_keys(cur, high_key, lkp); @@ -4732,13 +4735,13 @@ xfs_btree_overlapped_query_range( if (error) goto out; #endif - cur->bc_ptrs[level] = 1; + cur->bc_levels[level].ptr = 1; continue; } else if (hdiff < 0) { /* The low key is larger than the upper range; pop. */ goto pop_up; } - cur->bc_ptrs[level]++; + cur->bc_levels[level].ptr++; } out: @@ -4749,13 +4752,14 @@ xfs_btree_overlapped_query_range( * with a zero-results range query, so release the buffers if we * failed to return any results. */ - if (cur->bc_bufs[0] == NULL) { + if (cur->bc_levels[0].bp == NULL) { for (i = 0; i < cur->bc_nlevels; i++) { - if (cur->bc_bufs[i]) { - xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]); - cur->bc_bufs[i] = NULL; - cur->bc_ptrs[i] = 0; - cur->bc_ra[i] = 0; + if (cur->bc_levels[i].bp) { + xfs_trans_brelse(cur->bc_tp, + cur->bc_levels[i].bp); + cur->bc_levels[i].bp = NULL; + cur->bc_levels[i].ptr = 0; + cur->bc_levels[i].ra = 0; } } } @@ -4917,7 +4921,7 @@ xfs_btree_has_more_records( block = xfs_btree_get_block(cur, 0, &bp); /* There are still records in this block. */ - if (cur->bc_ptrs[0] < xfs_btree_get_numrecs(block)) + if (cur->bc_levels[0].ptr < xfs_btree_get_numrecs(block)) return true; /* There are more record blocks. */ diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 1018bcc43d66..f31f057bec9d 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -212,6 +212,19 @@ struct xfs_btree_cur_ino { #define XFS_BTCUR_BMBT_INVALID_OWNER (1 << 1) }; +struct xfs_btree_level { + /* buffer pointer */ + struct xfs_buf *bp; + + /* key/record number */ + uint16_t ptr; + + /* readahead info */ +#define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ +#define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ + uint16_t ra; +}; + /* * Btree cursor structure. * This collects all information needed by the btree code in one place. @@ -223,11 +236,6 @@ struct xfs_btree_cur const struct xfs_btree_ops *bc_ops; uint bc_flags; /* btree features - below */ union xfs_btree_irec bc_rec; /* current insert/search record value */ - struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ - int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ - uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ -#define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ -#define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ uint8_t bc_nlevels; /* number of levels in the tree */ xfs_btnum_t bc_btnum; /* identifies which btree type */ int bc_statoff; /* offset of btre stats array */ @@ -242,8 +250,17 @@ struct xfs_btree_cur struct xfs_btree_cur_ag bc_ag; struct xfs_btree_cur_ino bc_ino; }; + + /* Must be at the end of the struct! */ + struct xfs_btree_level bc_levels[]; }; +static inline size_t +xfs_btree_cur_sizeof(unsigned int nlevels) +{ + return struct_size((struct xfs_btree_cur *)NULL, bc_levels, nlevels); +} + /* cursor flags */ #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ @@ -257,7 +274,6 @@ struct xfs_btree_cur */ #define XFS_BTREE_STAGING (1<<5) - #define XFS_BTREE_NOERROR 0 #define XFS_BTREE_ERROR 1 diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c index d6d24c866bc4..b89bf9de9b1c 100644 --- a/fs/xfs/scrub/bitmap.c +++ b/fs/xfs/scrub/bitmap.c @@ -222,21 +222,21 @@ xbitmap_disunion( * 1 2 3 * * Pretend for this example that each leaf block has 100 btree records. For - * the first btree record, we'll observe that bc_ptrs[0] == 1, so we record - * that we saw block 1. Then we observe that bc_ptrs[1] == 1, so we record - * block 4. The list is [1, 4]. + * the first btree record, we'll observe that bc_levels[0].ptr == 1, so we + * record that we saw block 1. Then we observe that bc_levels[1].ptr == 1, so + * we record block 4. The list is [1, 4]. * - * For the second btree record, we see that bc_ptrs[0] == 2, so we exit the - * loop. The list remains [1, 4]. + * For the second btree record, we see that bc_levels[0].ptr == 2, so we exit + * the loop. The list remains [1, 4]. * * For the 101st btree record, we've moved onto leaf block 2. Now - * bc_ptrs[0] == 1 again, so we record that we saw block 2. We see that - * bc_ptrs[1] == 2, so we exit the loop. The list is now [1, 4, 2]. + * bc_levels[0].ptr == 1 again, so we record that we saw block 2. We see that + * bc_levels[1].ptr == 2, so we exit the loop. The list is now [1, 4, 2]. * - * For the 102nd record, bc_ptrs[0] == 2, so we continue. + * For the 102nd record, bc_levels[0].ptr == 2, so we continue. * - * For the 201st record, we've moved on to leaf block 3. bc_ptrs[0] == 1, so - * we add 3 to the list. Now it is [1, 4, 2, 3]. + * For the 201st record, we've moved on to leaf block 3. + * bc_levels[0].ptr == 1, so we add 3 to the list. Now it is [1, 4, 2, 3]. * * For the 300th record we just exit, with the list being [1, 4, 2, 3]. */ @@ -256,7 +256,7 @@ xbitmap_set_btcur_path( int i; int error; - for (i = 0; i < cur->bc_nlevels && cur->bc_ptrs[i] == 1; i++) { + for (i = 0; i < cur->bc_nlevels && cur->bc_levels[i].ptr == 1; i++) { xfs_btree_get_block(cur, i, &bp); if (!bp) continue; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 017da9ceaee9..a4cbbc346f60 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -402,7 +402,7 @@ xchk_bmapbt_rec( * the root since the verifiers don't do that. */ if (xfs_has_crc(bs->cur->bc_mp) && - bs->cur->bc_ptrs[0] == 1) { + bs->cur->bc_levels[0].ptr == 1) { for (i = 0; i < bs->cur->bc_nlevels - 1; i++) { block = xfs_btree_get_block(bs->cur, i, &bp); owner = be64_to_cpu(block->bb_u.l.bb_owner); diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index 6d4eba85ef77..39dd46f038fe 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -136,12 +136,12 @@ xchk_btree_rec( struct xfs_buf *bp; block = xfs_btree_get_block(cur, 0, &bp); - rec = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block); + rec = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, block); trace_xchk_btree_rec(bs->sc, cur, 0); /* If this isn't the first record, are they in order? */ - if (cur->bc_ptrs[0] > 1 && + if (cur->bc_levels[0].ptr > 1 && !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec)) xchk_btree_set_corrupt(bs->sc, cur, 0); memcpy(&bs->lastrec, rec, cur->bc_ops->rec_len); @@ -152,7 +152,7 @@ xchk_btree_rec( /* Is this at least as large as the parent low key? */ cur->bc_ops->init_key_from_rec(&key, rec); keyblock = xfs_btree_get_block(cur, 1, &bp); - keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[1], keyblock); + keyp = xfs_btree_key_addr(cur, cur->bc_levels[1].ptr, keyblock); if (cur->bc_ops->diff_two_keys(cur, &key, keyp) < 0) xchk_btree_set_corrupt(bs->sc, cur, 1); @@ -161,7 +161,7 @@ xchk_btree_rec( /* Is this no larger than the parent high key? */ cur->bc_ops->init_high_key_from_rec(&hkey, rec); - keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[1], keyblock); + keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[1].ptr, keyblock); if (cur->bc_ops->diff_two_keys(cur, keyp, &hkey) < 0) xchk_btree_set_corrupt(bs->sc, cur, 1); } @@ -183,12 +183,12 @@ xchk_btree_key( struct xfs_buf *bp; block = xfs_btree_get_block(cur, level, &bp); - key = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block); + key = xfs_btree_key_addr(cur, cur->bc_levels[level].ptr, block); trace_xchk_btree_key(bs->sc, cur, level); /* If this isn't the first key, are they in order? */ - if (cur->bc_ptrs[level] > 1 && + if (cur->bc_levels[level].ptr > 1 && !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level - 1], key)) xchk_btree_set_corrupt(bs->sc, cur, level); memcpy(&bs->lastkey[level - 1], key, cur->bc_ops->key_len); @@ -198,7 +198,7 @@ xchk_btree_key( /* Is this at least as large as the parent low key? */ keyblock = xfs_btree_get_block(cur, level + 1, &bp); - keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1], keyblock); + keyp = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr, keyblock); if (cur->bc_ops->diff_two_keys(cur, key, keyp) < 0) xchk_btree_set_corrupt(bs->sc, cur, level); @@ -206,8 +206,9 @@ xchk_btree_key( return; /* Is this no larger than the parent high key? */ - key = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block); - keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1], keyblock); + key = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, block); + keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr, + keyblock); if (cur->bc_ops->diff_two_keys(cur, keyp, key) < 0) xchk_btree_set_corrupt(bs->sc, cur, level); } @@ -290,7 +291,7 @@ xchk_btree_block_check_sibling( /* Compare upper level pointer to sibling pointer. */ pblock = xfs_btree_get_block(ncur, level + 1, &pbp); - pp = xfs_btree_ptr_addr(ncur, ncur->bc_ptrs[level + 1], pblock); + pp = xfs_btree_ptr_addr(ncur, ncur->bc_levels[level + 1].ptr, pblock); if (!xchk_btree_ptr_ok(bs, level + 1, pp)) goto out; if (pbp) @@ -595,7 +596,7 @@ xchk_btree_block_keys( /* Obtain the parent's copy of the keys for this block. */ parent_block = xfs_btree_get_block(cur, level + 1, &bp); - parent_keys = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1], + parent_keys = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr, parent_block); if (cur->bc_ops->diff_two_keys(cur, &block_keys, parent_keys) != 0) @@ -606,7 +607,7 @@ xchk_btree_block_keys( /* Get high keys */ high_bk = xfs_btree_high_key_from_key(cur, &block_keys); - high_pk = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1], + high_pk = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr, parent_block); if (cur->bc_ops->diff_two_keys(cur, high_bk, high_pk) != 0) @@ -672,18 +673,18 @@ xchk_btree( if (error || !block) goto out; - cur->bc_ptrs[level] = 1; + cur->bc_levels[level].ptr = 1; while (level < cur->bc_nlevels) { block = xfs_btree_get_block(cur, level, &bp); if (level == 0) { /* End of leaf, pop back towards the root. */ - if (cur->bc_ptrs[level] > + if (cur->bc_levels[level].ptr > be16_to_cpu(block->bb_numrecs)) { xchk_btree_block_keys(bs, level, block); if (level < cur->bc_nlevels - 1) - cur->bc_ptrs[level + 1]++; + cur->bc_levels[level + 1].ptr++; level++; continue; } @@ -692,7 +693,8 @@ xchk_btree( xchk_btree_rec(bs); /* Call out to the record checker. */ - recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block); + recp = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, + block); error = bs->scrub_rec(bs, recp); if (error) break; @@ -700,15 +702,16 @@ xchk_btree( (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) break; - cur->bc_ptrs[level]++; + cur->bc_levels[level].ptr++; continue; } /* End of node, pop back towards the root. */ - if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) { + if (cur->bc_levels[level].ptr > + be16_to_cpu(block->bb_numrecs)) { xchk_btree_block_keys(bs, level, block); if (level < cur->bc_nlevels - 1) - cur->bc_ptrs[level + 1]++; + cur->bc_levels[level + 1].ptr++; level++; continue; } @@ -717,9 +720,9 @@ xchk_btree( xchk_btree_key(bs, level); /* Drill another level deeper. */ - pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block); + pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block); if (!xchk_btree_ptr_ok(bs, level, pp)) { - cur->bc_ptrs[level]++; + cur->bc_levels[level].ptr++; continue; } level--; @@ -727,7 +730,7 @@ xchk_btree( if (error || !block) goto out; - cur->bc_ptrs[level] = 1; + cur->bc_levels[level].ptr = 1; } out: diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c index c0ef53fe6611..816dfc8e5a80 100644 --- a/fs/xfs/scrub/trace.c +++ b/fs/xfs/scrub/trace.c @@ -21,10 +21,11 @@ xchk_btree_cur_fsbno( struct xfs_btree_cur *cur, int level) { - if (level < cur->bc_nlevels && cur->bc_bufs[level]) + if (level < cur->bc_nlevels && cur->bc_levels[level].bp) return XFS_DADDR_TO_FSB(cur->bc_mp, - xfs_buf_daddr(cur->bc_bufs[level])); - if (level == cur->bc_nlevels - 1 && cur->bc_flags & XFS_BTREE_LONG_PTRS) + xfs_buf_daddr(cur->bc_levels[level].bp)); + else if (level == cur->bc_nlevels - 1 && + cur->bc_flags & XFS_BTREE_LONG_PTRS) return XFS_INO_TO_FSB(cur->bc_mp, cur->bc_ino.ip->i_ino); if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS)) return XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, 0); diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index a7bbb84f91a7..93ece6df02e3 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -348,7 +348,7 @@ TRACE_EVENT(xchk_btree_op_error, __entry->level = level; __entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno); __entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno); - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; __entry->error = error; __entry->ret_ip = ret_ip; ), @@ -389,7 +389,7 @@ TRACE_EVENT(xchk_ifork_btree_op_error, __entry->type = sc->sm->sm_type; __entry->btnum = cur->bc_btnum; __entry->level = level; - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; __entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno); __entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno); __entry->error = error; @@ -431,7 +431,7 @@ TRACE_EVENT(xchk_btree_error, __entry->level = level; __entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno); __entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno); - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; __entry->ret_ip = ret_ip; ), TP_printk("dev %d:%d type %s btree %s level %d ptr %d agno 0x%x agbno 0x%x ret_ip %pS", @@ -471,7 +471,7 @@ TRACE_EVENT(xchk_ifork_btree_error, __entry->level = level; __entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno); __entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno); - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; __entry->ret_ip = ret_ip; ), TP_printk("dev %d:%d ino 0x%llx fork %s type %s btree %s level %d ptr %d agno 0x%x agbno 0x%x ret_ip %pS", @@ -511,7 +511,7 @@ DECLARE_EVENT_CLASS(xchk_sbtree_class, __entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno); __entry->level = level; __entry->nlevels = cur->bc_nlevels; - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; ), TP_printk("dev %d:%d type %s btree %s agno 0x%x agbno 0x%x level %d nlevels %d ptr %d", MAJOR(__entry->dev), MINOR(__entry->dev), diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index c4e0cd1c1c8c..30bae0657343 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1966,7 +1966,7 @@ xfs_init_zones(void) goto out_destroy_log_ticket_zone; xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur", - sizeof(struct xfs_btree_cur), + xfs_btree_cur_sizeof(XFS_BTREE_MAXLEVELS), 0, 0, NULL); if (!xfs_btree_cur_zone) goto out_destroy_bmap_free_item_zone; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 1033a95fbf8e..4a8076ef8cb4 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2476,7 +2476,7 @@ DECLARE_EVENT_CLASS(xfs_btree_cur_class, __entry->btnum = cur->bc_btnum; __entry->level = level; __entry->nlevels = cur->bc_nlevels; - __entry->ptr = cur->bc_ptrs[level]; + __entry->ptr = cur->bc_levels[level].ptr; __entry->daddr = bp ? xfs_buf_daddr(bp) : -1; ), TP_printk("dev %d:%d btree %s level %d/%d ptr %d daddr 0x%llx", From patchwork Tue Oct 12 23:33:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553943 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC5E7C433EF for ; Tue, 12 Oct 2021 23:33:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B838F60ED4 for ; Tue, 12 Oct 2021 23:33:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234169AbhJLXfJ (ORCPT ); Tue, 12 Oct 2021 19:35:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:48244 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234129AbhJLXfJ (ORCPT ); Tue, 12 Oct 2021 19:35:09 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 18FF760E53; Tue, 12 Oct 2021 23:33:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081587; bh=4pf79IE/0zNHwYe1S8jrCDlOFIOHSxBep67laOaxw+Y=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=W0DjnPc+4riccz1O0N7LwYQe8EU5B6Qy4Tr8TdPYFCP7cbnTmxbL9q21d6zLDMun+ zRbn0t5VEEx9hE5lCK8OmtIKf71Yvf+OftqrZvLMSseqIMFEawSEZLmuJbne9es/vb 6OkhuqhvaNONRdrOzOYoQpw8+Ag2F3FCmzVvcbMH2VBywOOewW85kvMSQVK19RLZ7S AiRQQEgctWK7Y/G7B/3dSWGRkbWBRej2ACXsCe6njIlTTHxXA48xTV7NtmDSLAoWGo 6HZNtpKMNRI6/foYEeG+PBctkKqEo0WdYm0ZgypNrbT+IuMrpaPmkF2WazCmZ6URjx 6+xrUKokPT5GA== Subject: [PATCH 06/15] xfs: rearrange xfs_btree_cur fields for better packing From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:06 -0700 Message-ID: <163408158681.4151249.744541700094003708.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Reduce the size of the btree cursor structure some more by rearranging fields to eliminate unused space. While we're at it, fix the ragged indentation and a spelling error. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index f31f057bec9d..613f7a303cc6 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -234,11 +234,11 @@ struct xfs_btree_cur struct xfs_trans *bc_tp; /* transaction we're in, if any */ struct xfs_mount *bc_mp; /* file system mount struct */ const struct xfs_btree_ops *bc_ops; - uint bc_flags; /* btree features - below */ + unsigned int bc_flags; /* btree features - below */ + xfs_btnum_t bc_btnum; /* identifies which btree type */ union xfs_btree_irec bc_rec; /* current insert/search record value */ - uint8_t bc_nlevels; /* number of levels in the tree */ - xfs_btnum_t bc_btnum; /* identifies which btree type */ - int bc_statoff; /* offset of btre stats array */ + uint8_t bc_nlevels; /* number of levels in the tree */ + int bc_statoff; /* offset of btree stats array */ /* * Short btree pointers need an agno to be able to turn the pointers From patchwork Tue Oct 12 23:33:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553945 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBAABC433F5 for ; Tue, 12 Oct 2021 23:33:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C2FDC60EB6 for ; Tue, 12 Oct 2021 23:33:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235640AbhJLXfP (ORCPT ); Tue, 12 Oct 2021 19:35:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:48264 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234129AbhJLXfO (ORCPT ); Tue, 12 Oct 2021 19:35:14 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9A09960E53; Tue, 12 Oct 2021 23:33:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081592; bh=cS2TPX7Hdf+X5nAStlCWZqcdFHUlsDAf70yMWNuhkTU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=C9n0P1XHbnrIGVUNmQSQMldf1l41agFulfHycjxen0vW0RbuPAJRdsvCP2ktMAQPL pwFmfXH1B60DYBbC6iqBCfLV+1s0dLYv5Bu/xrcwKycDyc1ZkWO6yx8vY7xhWjmm2V gsxju+o63HLwGP0vAkVoSTuiDKF3t7MmBymSRvUKAN4jjTk+lv8PpQDZWM/TKGde8a Q2EhngtGDyXpDOC0yvgyiGY+HkjlCapNT+x020uBoLG8+Apg4tmpK1UcmOskIGUsGN I0R+ohUhtpTJTPUaATXy/GYWMFEJ8CuNPUFC71C+DhCL1gCsz8pHZWC2nHDX3gBUZf zFMmVPbNFjDyw== Subject: [PATCH 07/15] xfs: refactor btree cursor allocation function From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: Chandan Babu R , Christoph Hellwig , linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:12 -0700 Message-ID: <163408159230.4151249.14190118477095749260.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 btree allocation to a common helper. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc_btree.c | 6 +----- fs/xfs/libxfs/xfs_bmap_btree.c | 6 +----- fs/xfs/libxfs/xfs_btree.h | 16 ++++++++++++++++ fs/xfs/libxfs/xfs_ialloc_btree.c | 5 +---- fs/xfs/libxfs/xfs_refcount_btree.c | 5 +---- fs/xfs/libxfs/xfs_rmap_btree.c | 5 +---- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 152ed2a202f4..c644b11132f6 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -477,11 +477,7 @@ xfs_allocbt_init_common( ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); - - cur->bc_tp = tp; - cur->bc_mp = mp; - cur->bc_btnum = btnum; + cur = xfs_btree_alloc_cursor(mp, tp, btnum); cur->bc_ag.abt.active = false; if (btnum == XFS_BTNUM_CNT) { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index a43dea8d6a65..a06987e36db5 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -552,12 +552,8 @@ xfs_bmbt_init_cursor( struct xfs_btree_cur *cur; ASSERT(whichfork != XFS_COW_FORK); - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); - - cur->bc_tp = tp; - cur->bc_mp = mp; + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP); cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; - cur->bc_btnum = XFS_BTNUM_BMAP; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2); cur->bc_ops = &xfs_bmbt_ops; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 613f7a303cc6..76509e819d60 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -573,4 +573,20 @@ void xfs_btree_copy_keys(struct xfs_btree_cur *cur, union xfs_btree_key *dst_key, const union xfs_btree_key *src_key, int numkeys); +static inline struct xfs_btree_cur * +xfs_btree_alloc_cursor( + struct xfs_mount *mp, + struct xfs_trans *tp, + xfs_btnum_t btnum) +{ + struct xfs_btree_cur *cur; + + cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); + cur->bc_tp = tp; + cur->bc_mp = mp; + cur->bc_btnum = btnum; + + return cur; +} + #endif /* __XFS_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 10736b89b679..c8fea6a464d5 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -432,10 +432,7 @@ xfs_inobt_init_common( { struct xfs_btree_cur *cur; - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); - cur->bc_tp = tp; - cur->bc_mp = mp; - cur->bc_btnum = btnum; + cur = xfs_btree_alloc_cursor(mp, tp, btnum); if (btnum == XFS_BTNUM_INO) { cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2); cur->bc_ops = &xfs_inobt_ops; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 3ea589f15b14..48c45e31d897 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -322,10 +322,7 @@ xfs_refcountbt_init_common( ASSERT(pag->pag_agno < mp->m_sb.sb_agcount); - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); - cur->bc_tp = tp; - cur->bc_mp = mp; - cur->bc_btnum = XFS_BTNUM_REFC; + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC); cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index d65bf3c6f25e..f3c4d0965cc9 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -451,11 +451,8 @@ xfs_rmapbt_init_common( { struct xfs_btree_cur *cur; - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); - cur->bc_tp = tp; - cur->bc_mp = mp; /* Overlapping btree; 2 keys per pointer. */ - cur->bc_btnum = XFS_BTNUM_RMAP; + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP); cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); cur->bc_ops = &xfs_rmapbt_ops; From patchwork Tue Oct 12 23:33:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553947 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2AC21C433EF for ; Tue, 12 Oct 2021 23:33:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0144C60F92 for ; Tue, 12 Oct 2021 23:33:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235950AbhJLXfV (ORCPT ); Tue, 12 Oct 2021 19:35:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:48292 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234129AbhJLXfU (ORCPT ); Tue, 12 Oct 2021 19:35:20 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 239D760ED4; Tue, 12 Oct 2021 23:33:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081598; bh=Zvk7U/b35ya2g/SZFSUqx9RGV0HxoSvhrDfx119UcQI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=TyLL5wstManFvOwxk5fQitchOXcYe0iasdUzPcb5iFOHNuaI/ZxnapAKaEYyhTAVr 2drk3qL32uusWXjj2FL+YSlDe/EgYFaEEZeqyMAkHzbjNYY0yNr/6Lgk2jxWgC8Hgk Yf//DouoCDhqAPXRZt8AihT3jkx+f4JXg/K5Z8Y/aSkepJMYHPR9OuWxQfn+fSAbNr SDDc8IUfEBiIFCxKHOggue/Xmw2KAkH7ZnhklF+BxatIji7qE2tsWUTC7cZQK9GD4U EFEyAVQpfbS1lpRHq5stBjvZIVs/sd9wdQPRHN8MQFyIj/CiWUu+0umAepqMvH3oyO kYkFnfV5RGwRA== Subject: [PATCH 08/15] xfs: encode the max btree height in the cursor From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:17 -0700 Message-ID: <163408159784.4151249.6976364349258667730.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Encode the maximum btree height in the cursor, since we're soon going to allow smaller cursors for AG btrees and larger cursors for file btrees. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 2 +- fs/xfs/libxfs/xfs_btree.c | 4 ++-- fs/xfs/libxfs/xfs_btree.h | 2 ++ fs/xfs/libxfs/xfs_btree_staging.c | 10 +++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 644b956301b6..2ae5bf9a74e7 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -239,7 +239,7 @@ xfs_bmap_get_bp( if (!cur) return NULL; - for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) { + for (i = 0; i < cur->bc_maxlevels; i++) { if (!cur->bc_levels[i].bp) break; if (xfs_buf_daddr(cur->bc_levels[i].bp) == bno) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 25dfab81025f..6ced8f028d47 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -2933,7 +2933,7 @@ xfs_btree_new_iroot( be16_add_cpu(&block->bb_level, 1); xfs_btree_set_numrecs(block, 1); cur->bc_nlevels++; - ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); + ASSERT(cur->bc_nlevels <= cur->bc_maxlevels); cur->bc_levels[level + 1].ptr = 1; kp = xfs_btree_key_addr(cur, 1, block); @@ -3097,7 +3097,7 @@ xfs_btree_new_root( xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); cur->bc_levels[cur->bc_nlevels].ptr = nptr; cur->bc_nlevels++; - ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); + ASSERT(cur->bc_nlevels <= cur->bc_maxlevels); *stat = 1; return 0; error0: diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 76509e819d60..43766e5b680f 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -238,6 +238,7 @@ struct xfs_btree_cur xfs_btnum_t bc_btnum; /* identifies which btree type */ union xfs_btree_irec bc_rec; /* current insert/search record value */ uint8_t bc_nlevels; /* number of levels in the tree */ + uint8_t bc_maxlevels; /* maximum levels for this btree type */ int bc_statoff; /* offset of btree stats array */ /* @@ -585,6 +586,7 @@ xfs_btree_alloc_cursor( cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_btnum = btnum; + cur->bc_maxlevels = XFS_BTREE_MAXLEVELS; return cur; } diff --git a/fs/xfs/libxfs/xfs_btree_staging.c b/fs/xfs/libxfs/xfs_btree_staging.c index cc56efc2b90a..dd75e208b543 100644 --- a/fs/xfs/libxfs/xfs_btree_staging.c +++ b/fs/xfs/libxfs/xfs_btree_staging.c @@ -657,12 +657,12 @@ xfs_btree_bload_compute_geometry( * checking levels 0 and 1 here, so set bc_nlevels such that the btree * code doesn't interpret either as the root level. */ - cur->bc_nlevels = XFS_BTREE_MAXLEVELS - 1; + cur->bc_nlevels = cur->bc_maxlevels - 1; xfs_btree_bload_ensure_slack(cur, &bbl->leaf_slack, 0); xfs_btree_bload_ensure_slack(cur, &bbl->node_slack, 1); bbl->nr_records = nr_this_level = nr_records; - for (cur->bc_nlevels = 1; cur->bc_nlevels <= XFS_BTREE_MAXLEVELS;) { + for (cur->bc_nlevels = 1; cur->bc_nlevels <= cur->bc_maxlevels;) { uint64_t level_blocks; uint64_t dontcare64; unsigned int level = cur->bc_nlevels - 1; @@ -703,7 +703,7 @@ xfs_btree_bload_compute_geometry( * block-based btree level. */ cur->bc_nlevels++; - ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); + ASSERT(cur->bc_nlevels <= cur->bc_maxlevels); xfs_btree_bload_level_geometry(cur, bbl, level, nr_this_level, &avg_per_block, &level_blocks, &dontcare64); @@ -719,14 +719,14 @@ xfs_btree_bload_compute_geometry( /* Otherwise, we need another level of btree. */ cur->bc_nlevels++; - ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS); + ASSERT(cur->bc_nlevels <= cur->bc_maxlevels); } nr_blocks += level_blocks; nr_this_level = level_blocks; } - if (cur->bc_nlevels > XFS_BTREE_MAXLEVELS) + if (cur->bc_nlevels > cur->bc_maxlevels) return -EOVERFLOW; bbl->btree_height = cur->bc_nlevels; From patchwork Tue Oct 12 23:33:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553949 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F392C433F5 for ; Tue, 12 Oct 2021 23:33:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E798D60F92 for ; Tue, 12 Oct 2021 23:33:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234129AbhJLXf0 (ORCPT ); Tue, 12 Oct 2021 19:35:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:48322 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235972AbhJLXfZ (ORCPT ); Tue, 12 Oct 2021 19:35:25 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 97B0460EBB; Tue, 12 Oct 2021 23:33:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081603; bh=70RmJRLQAep4+0HUwvQeagPTpCQgjNe6TK/+LnXTpuA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=fE8OIwwNbhpjD00FKEhCjAjatLvPn64md6u4MMeuiXNSZZ3KiW8tl+u5tjuAWpFKx Lxy6jtkQ6JC2qK9PKz86oxVWa7ephlhbVHLB5WDyvsycLZNrgNGF4peeNMpzILCvb0 g3iSjHH7jlLcuH67mekXsFi8YFQ7tqN5bq1mpjzspMbMfoVxKnWCsScNCm+h/0A8Qz ziIQhyGZYoxNd+0Xbu9CAItl1OE8pPCmBbH3dN4km3zO5h/2+2cID5yVk9RohDkmGd CbjQQSvrq8cp0p5y7Xer1e3MfLBytJqqqVmG1hGFSnz5GZxz+C7yRSKUbixJhCOeX5 BGJqU/yUyF/8g== Subject: [PATCH 09/15] xfs: dynamically allocate cursors based on maxlevels From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:23 -0700 Message-ID: <163408160334.4151249.13708314780740357223.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 To support future btree code, we need to be able to size btree cursors dynamically for very large btrees. Switch the maxlevels computation to use the precomputed values in the superblock, and create cursors that can handle a certain height. For now, we retain the btree cursor zone that can handle up to 9-level btrees, and create larger cursors (which shouldn't happen currently) from the heap as a failsafe. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc_btree.c | 2 +- fs/xfs/libxfs/xfs_bmap_btree.c | 3 ++- fs/xfs/libxfs/xfs_btree.h | 13 +++++++++++-- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 ++- fs/xfs/libxfs/xfs_refcount_btree.c | 3 ++- fs/xfs/libxfs/xfs_rmap_btree.c | 3 ++- fs/xfs/xfs_super.c | 4 ++-- 7 files changed, 22 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index c644b11132f6..f14bad21503f 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -477,7 +477,7 @@ xfs_allocbt_init_common( ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); - cur = xfs_btree_alloc_cursor(mp, tp, btnum); + cur = xfs_btree_alloc_cursor(mp, tp, btnum, mp->m_ag_maxlevels); cur->bc_ag.abt.active = false; if (btnum == XFS_BTNUM_CNT) { diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index a06987e36db5..b90122de0df0 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -552,7 +552,8 @@ xfs_bmbt_init_cursor( struct xfs_btree_cur *cur; ASSERT(whichfork != XFS_COW_FORK); - cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP); + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, + mp->m_bm_maxlevels[whichfork]); cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2); diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 43766e5b680f..b8761a2fc24b 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -94,6 +94,12 @@ uint32_t xfs_btree_magic(int crc, xfs_btnum_t btnum); #define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */ +/* + * The btree cursor zone hands out cursors that can handle up to this many + * levels. This is the known maximum for all btree types. + */ +#define XFS_BTREE_CUR_ZONE_MAXLEVELS (9) + struct xfs_btree_ops { /* size of the key and record structures */ size_t key_len; @@ -578,15 +584,18 @@ static inline struct xfs_btree_cur * xfs_btree_alloc_cursor( struct xfs_mount *mp, struct xfs_trans *tp, - xfs_btnum_t btnum) + xfs_btnum_t btnum, + uint8_t maxlevels) { struct xfs_btree_cur *cur; + ASSERT(maxlevels <= XFS_BTREE_CUR_ZONE_MAXLEVELS); + cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_btnum = btnum; - cur->bc_maxlevels = XFS_BTREE_MAXLEVELS; + cur->bc_maxlevels = maxlevels; return cur; } diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index c8fea6a464d5..3a5a24648b87 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -432,7 +432,8 @@ xfs_inobt_init_common( { struct xfs_btree_cur *cur; - cur = xfs_btree_alloc_cursor(mp, tp, btnum); + cur = xfs_btree_alloc_cursor(mp, tp, btnum, + M_IGEO(mp)->inobt_maxlevels); if (btnum == XFS_BTNUM_INO) { cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2); cur->bc_ops = &xfs_inobt_ops; diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 48c45e31d897..995b0d86ddc0 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -322,7 +322,8 @@ xfs_refcountbt_init_common( ASSERT(pag->pag_agno < mp->m_sb.sb_agcount); - cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC); + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC, + mp->m_refc_maxlevels); cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index f3c4d0965cc9..1b48b7b3ee30 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -452,7 +452,8 @@ xfs_rmapbt_init_common( struct xfs_btree_cur *cur; /* Overlapping btree; 2 keys per pointer. */ - cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP); + cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, + mp->m_rmap_maxlevels); cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); cur->bc_ops = &xfs_rmapbt_ops; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 30bae0657343..90c92a6a49e0 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1966,8 +1966,8 @@ xfs_init_zones(void) goto out_destroy_log_ticket_zone; xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur", - xfs_btree_cur_sizeof(XFS_BTREE_MAXLEVELS), - 0, 0, NULL); + xfs_btree_cur_sizeof(XFS_BTREE_CUR_ZONE_MAXLEVELS), + 0, 0, NULL); if (!xfs_btree_cur_zone) goto out_destroy_bmap_free_item_zone; From patchwork Tue Oct 12 23:33:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553951 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89364C433EF for ; Tue, 12 Oct 2021 23:33:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6BAC56101B for ; Tue, 12 Oct 2021 23:33:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235972AbhJLXfb (ORCPT ); Tue, 12 Oct 2021 19:35:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:48348 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235893AbhJLXfb (ORCPT ); Tue, 12 Oct 2021 19:35:31 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 22F2D60EB6; Tue, 12 Oct 2021 23:33:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081609; bh=pEcAaTs9Uwi0IDiRSEBncOKYvUCukqs6d2HDdfMf4r8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=NX/EsCjgzZeQc6hPY5qQHlYS/0a7IfhvG+0IxSis2Io8G7ypbgPojUY3aoHiYHx74 1Po6Fm+sSgDv3mNZZZh0BBln6qp4LlSUUbMvTSczKP4XZlzHUti0t7z1PioU3QwBIN 8OPu7zKcDajjg4rw3jLxoDrTEsBZ3zNWZfAvlgvDluYE3STayHgH5WCpUJWPn9TdFb 5euHYF6aR+v4VjBoXehOIjPFcO1VHbogiSsWZG2cHACMAhww5Mqqe6Ozr4iD/S7UbW lIioKAvQFdNmz/hzoAlBAN9Tc1jdoklBUoLvwBuvAf+3q62Qbhp4Clay2n8gaFDfuW eYPxO6y/pnzcw== Subject: [PATCH 10/15] xfs: compute actual maximum btree height for critical reservation calculation From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:28 -0700 Message-ID: <163408160882.4151249.14701173486144926020.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Compute the actual maximum btree height when deciding if per-AG block reservation is critically low. This only affects the sanity check condition, since we /generally/ will trigger on the 10% threshold. This is a long-winded way of saying that we're removing one more usage of XFS_BTREE_MAXLEVELS. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_ag_resv.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index 2aa2b3484c28..d34d4614f175 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -60,6 +60,20 @@ * to use the reservation system should update ask/used in xfs_ag_resv_init. */ +/* Compute maximum possible height for per-AG btree types for this fs. */ +static unsigned int +xfs_ag_btree_maxlevels( + struct xfs_mount *mp) +{ + unsigned int ret = mp->m_ag_maxlevels; + + ret = max(ret, mp->m_bm_maxlevels[XFS_DATA_FORK]); + ret = max(ret, mp->m_bm_maxlevels[XFS_ATTR_FORK]); + ret = max(ret, M_IGEO(mp)->inobt_maxlevels); + ret = max(ret, mp->m_rmap_maxlevels); + return max(ret, mp->m_refc_maxlevels); +} + /* * Are we critically low on blocks? For now we'll define that as the number * of blocks we can get our hands on being less than 10% of what we reserved @@ -72,6 +86,7 @@ xfs_ag_resv_critical( { xfs_extlen_t avail; xfs_extlen_t orig; + xfs_extlen_t btree_maxlevels; switch (type) { case XFS_AG_RESV_METADATA: @@ -91,7 +106,8 @@ xfs_ag_resv_critical( trace_xfs_ag_resv_critical(pag, type, avail); /* Critically low if less than 10% or max btree height remains. */ - return XFS_TEST_ERROR(avail < orig / 10 || avail < XFS_BTREE_MAXLEVELS, + btree_maxlevels = xfs_ag_btree_maxlevels(pag->pag_mount); + return XFS_TEST_ERROR(avail < orig / 10 || avail < btree_maxlevels, pag->pag_mount, XFS_ERRTAG_AG_RESV_CRITICAL); } From patchwork Tue Oct 12 23:33:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553953 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25531C433EF for ; Tue, 12 Oct 2021 23:33:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 034A460F92 for ; Tue, 12 Oct 2021 23:33:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235893AbhJLXfh (ORCPT ); Tue, 12 Oct 2021 19:35:37 -0400 Received: from mail.kernel.org ([198.145.29.99]:48386 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235541AbhJLXfg (ORCPT ); Tue, 12 Oct 2021 19:35:36 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A0CC860F3A; Tue, 12 Oct 2021 23:33:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081614; bh=4F2oy9Mc/dhi8H9PEv2juPDUCg/nsJo6mvhzvtgoxs4=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=C6U8J1Ps+Cwi+eO+hE9975IVh1WWfPCAj+RU6mgOkX8qTNffnIP5VLj8yGXIfyLEz NgAy8iTGWKPc0ojZgT4JvD5VE/R2B1T7ljxETlMulaGkczSwMd1WL+8mnjS0yKo3yy QkRn/gdTazOyV5pERAczIRV/eUDHzSiJA09glKuTRFafl6ugXl4qz2vGdrtbfhV7SD If7qUhgMUdW7Q3CWbTfWdRDo00dhXOcme4XPDcSvpTO2Rs4qDobYVhmbIKoj/0fDMf aX5CAo9EtZmDBNvgw0RF6/1ma5PTnOLlBXDh+Bu4xVv2VeBUTM3vmAvYugd6DTszHQ BzySU1etXIFSQ== Subject: [PATCH 11/15] xfs: compute the maximum height of the rmap btree when reflink enabled From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: Chandan Babu R , linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:34 -0700 Message-ID: <163408161434.4151249.874557928540897102.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Instead of assuming that the hardcoded XFS_BTREE_MAXLEVELS value is big enough to handle the maximally tall rmap btree when all blocks are in use and maximally shared, let's compute the maximum height assuming the rmapbt consumes as many blocks as possible. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R --- fs/xfs/libxfs/xfs_btree.c | 34 ++++++++++++++++++++++++ fs/xfs/libxfs/xfs_btree.h | 2 + fs/xfs/libxfs/xfs_rmap_btree.c | 55 ++++++++++++++++++++++++--------------- fs/xfs/libxfs/xfs_trans_resv.c | 13 +++++++++ fs/xfs/libxfs/xfs_trans_space.h | 7 +++++ 5 files changed, 90 insertions(+), 21 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 6ced8f028d47..201b81d54622 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4531,6 +4531,40 @@ xfs_btree_compute_maxlevels( return level; } +/* + * Compute the maximum height of a btree that is allowed to consume up to the + * given number of blocks. + */ +unsigned int +xfs_btree_compute_maxlevels_size( + unsigned long long max_btblocks, + unsigned int leaf_mnr) +{ + unsigned long long leaf_blocks = leaf_mnr; + unsigned long long blocks_left; + unsigned int maxlevels; + + if (max_btblocks < 1) + return 0; + + /* + * The loop increments maxlevels as long as there would be enough + * blocks left in the reservation to handle each node block at the + * current level pointing to the minimum possible number of leaf blocks + * at the next level down. We start the loop assuming a single-level + * btree consuming one block. + */ + maxlevels = 1; + blocks_left = max_btblocks - 1; + while (leaf_blocks < blocks_left) { + maxlevels++; + blocks_left -= leaf_blocks; + leaf_blocks *= leaf_mnr; + } + + return maxlevels; +} + /* * Query a regular btree for all records overlapping a given interval. * Start with a LE lookup of the key of low_rec and return all records diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index b8761a2fc24b..fccb374a8399 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -483,6 +483,8 @@ xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp, unsigned int max_recs); uint xfs_btree_compute_maxlevels(uint *limits, unsigned long len); +unsigned int xfs_btree_compute_maxlevels_size(unsigned long long max_btblocks, + unsigned int leaf_mnr); unsigned long long xfs_btree_calc_size(uint *limits, unsigned long long len); /* diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 1b48b7b3ee30..b1b55a6e7d25 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -538,28 +538,41 @@ xfs_rmapbt_maxrecs( /* Compute the maximum height of an rmap btree. */ void xfs_rmapbt_compute_maxlevels( - struct xfs_mount *mp) + struct xfs_mount *mp) { - /* - * On a non-reflink filesystem, the maximum number of rmap - * records is the number of blocks in the AG, hence the max - * rmapbt height is log_$maxrecs($agblocks). However, with - * reflink each AG block can have up to 2^32 (per the refcount - * record format) owners, which means that theoretically we - * could face up to 2^64 rmap records. - * - * That effectively means that the max rmapbt height must be - * XFS_BTREE_MAXLEVELS. "Fortunately" we'll run out of AG - * blocks to feed the rmapbt long before the rmapbt reaches - * maximum height. The reflink code uses ag_resv_critical to - * disallow reflinking when less than 10% of the per-AG metadata - * block reservation since the fallback is a regular file copy. - */ - if (xfs_has_reflink(mp)) - mp->m_rmap_maxlevels = XFS_BTREE_MAXLEVELS; - else - mp->m_rmap_maxlevels = xfs_btree_compute_maxlevels( - mp->m_rmap_mnr, mp->m_sb.sb_agblocks); + unsigned int val; + + if (!xfs_has_rmapbt(mp)) { + mp->m_rmap_maxlevels = 0; + return; + } + + if (xfs_has_reflink(mp)) { + /* + * Compute the asymptotic maxlevels for an rmap btree on a + * filesystem that supports reflink. + * + * On a reflink filesystem, each AG block can have up to 2^32 + * (per the refcount record format) owners, which means that + * theoretically we could face up to 2^64 rmap records. + * However, we're likely to run out of blocks in the AG long + * before that happens, which means that we must compute the + * max height based on what the btree will look like if it + * consumes almost all the blocks in the AG due to maximal + * sharing factor. + */ + val = xfs_btree_compute_maxlevels_size(mp->m_sb.sb_agblocks, + mp->m_rmap_mnr[1]); + } else { + /* + * If there's no block sharing, compute the maximum rmapbt + * height assuming one rmap record per AG block. + */ + val = xfs_btree_compute_maxlevels(mp->m_rmap_mnr, + mp->m_sb.sb_agblocks); + } + + mp->m_rmap_maxlevels = val; } /* Calculate the refcount btree size for some records. */ diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 5e300daa2559..97bd17d84a23 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -814,6 +814,16 @@ xfs_trans_resv_calc( struct xfs_mount *mp, struct xfs_trans_resv *resp) { + unsigned int rmap_maxlevels = mp->m_rmap_maxlevels; + + /* + * In the early days of rmap+reflink, we always set the rmap maxlevels + * to 9 even if the AG was small enough that it would never grow to + * that height. + */ + if (xfs_has_rmapbt(mp) && xfs_has_reflink(mp)) + mp->m_rmap_maxlevels = XFS_OLD_REFLINK_RMAP_MAXLEVELS; + /* * The following transactions are logged in physical format and * require a permanent reservation on space. @@ -916,4 +926,7 @@ xfs_trans_resv_calc( resp->tr_clearagi.tr_logres = xfs_calc_clear_agi_bucket_reservation(mp); resp->tr_growrtzero.tr_logres = xfs_calc_growrtzero_reservation(mp); resp->tr_growrtfree.tr_logres = xfs_calc_growrtfree_reservation(mp); + + /* Put everything back the way it was. This goes at the end. */ + mp->m_rmap_maxlevels = rmap_maxlevels; } diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h index 50332be34388..440c9c390b86 100644 --- a/fs/xfs/libxfs/xfs_trans_space.h +++ b/fs/xfs/libxfs/xfs_trans_space.h @@ -17,6 +17,13 @@ /* Adding one rmap could split every level up to the top of the tree. */ #define XFS_RMAPADD_SPACE_RES(mp) ((mp)->m_rmap_maxlevels) +/* + * Note that we historically set m_rmap_maxlevels to 9 when reflink was + * enabled, so we must preserve this behavior to avoid changing the transaction + * space reservations. + */ +#define XFS_OLD_REFLINK_RMAP_MAXLEVELS (9) + /* Blocks we might need to add "b" rmaps to a tree. */ #define XFS_NRMAPADD_SPACE_RES(mp, b)\ (((b + XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp) - 1) / \ From patchwork Tue Oct 12 23:33:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553955 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B377C433EF for ; Tue, 12 Oct 2021 23:33:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 79E7260FDA for ; Tue, 12 Oct 2021 23:33:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235541AbhJLXfm (ORCPT ); Tue, 12 Oct 2021 19:35:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:48420 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235840AbhJLXfm (ORCPT ); Tue, 12 Oct 2021 19:35:42 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2859D60EB6; Tue, 12 Oct 2021 23:33:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081620; bh=OIe+7+YYg/GpzE1UA5wn+g9fz8T9Bpxj0lWK+0UZGDk=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=O/z2C1+EiJ450qimvWdIlTz+5kk9YpYuYywfsOA4cvNYc9MMENuA1DBNnbAwZiytI DoTUvjqUhOEWm0U7iFJZLX7W525gDfCDajOIO79xGJuZr9HWQla/zsmAjJ47QqeFSl uWIkodmgn46+yJrrzVhax8+nph/A0ZxcQGHSHPxoDortRvDO0MvsGQ27gEKhoyBgYW CNllGYqg2lCwkoFl5rYLBXZStP+8vl0g8U4YzvJPUugO1HKjhRkM0TR/krU36nKgph +JJsHH0jYdOimRDPAz1ARa3rkkLpRaP/CWpzCQXJW4cjnajL3n3ApbigdKI2wjT2RV P7kl03EMPepOg== Subject: [PATCH 12/15] xfs: kill XFS_BTREE_MAXLEVELS From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: Chandan Babu R , linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:39 -0700 Message-ID: <163408161986.4151249.17284868227162995652.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Nobody uses this symbol anymore, so kill it. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index fccb374a8399..d5f03550cec9 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -92,8 +92,6 @@ uint32_t xfs_btree_magic(int crc, xfs_btnum_t btnum); #define XFS_BTREE_STATS_ADD(cur, stat, val) \ XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val) -#define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */ - /* * The btree cursor zone hands out cursors that can handle up to this many * levels. This is the known maximum for all btree types. From patchwork Tue Oct 12 23:33:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553957 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 483D8C433F5 for ; Tue, 12 Oct 2021 23:33:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2AF9860FDA for ; Tue, 12 Oct 2021 23:33:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233870AbhJLXfs (ORCPT ); Tue, 12 Oct 2021 19:35:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:48442 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234169AbhJLXfr (ORCPT ); Tue, 12 Oct 2021 19:35:47 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9D18360F92; Tue, 12 Oct 2021 23:33:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081625; bh=zVWTkpaV3cx0bT2tZoyo+LrrUlZh8TVjFI7PHF0GeW8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=KWN3L48taUaYSoq/TrUhiwr2y68xOS/KEO9BNrXJNTkaf2qRITMaJt8MEV2VYx9cI VUlIunvZQKT6wH5MBzKJRHpW3VoogARbndb3mJSrGPVyBIV2JS22pXmllptY1dlKxf IX7ykbwr7ZBC1UhVmI7iiFbSu7oD5Gi8wPRpVE6ZeNnjF+Y6oJyok/7QersaXcuWUm zz3CAxNaDlcis3NXAgXX1Ehh5aFXwrVx78vxBPgC1JQ91szLAaw6HXV1AWfXRPaw2t Mrkp/XdesQvJWKW3Lw/lCndBi+A3HktnJusBbcLYA9oaZSXH6K6TDYtcn7sF55kvti gPlnHvip7gKvg== Subject: [PATCH 13/15] xfs: widen btree maxlevels computation to handle 64-bit record counts From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:45 -0700 Message-ID: <163408162537.4151249.5138465633448556647.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 Rework xfs_btree_compute_maxlevels to handle larger record counts, since we're about to add support for very large data forks. Eventually the realtime reverse mapping btree will need this too. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_btree.h | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 201b81d54622..b95c817ad90d 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4515,19 +4515,19 @@ xfs_btree_sblock_verify( /* * Calculate the number of btree levels needed to store a given number of - * records in a short-format btree. + * records in btree blocks. This does not include the inode root level. */ -uint +unsigned int xfs_btree_compute_maxlevels( - uint *limits, - unsigned long len) + unsigned int *limits, + unsigned long long len) { - uint level; - unsigned long maxblocks; + unsigned int level; + unsigned long long maxblocks; - maxblocks = (len + limits[0] - 1) / limits[0]; + maxblocks = howmany_64(len, limits[0]); for (level = 1; maxblocks > 1; level++) - maxblocks = (maxblocks + limits[1] - 1) / limits[1]; + maxblocks = howmany_64(maxblocks, limits[1]); return level; } diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index d5f03550cec9..20a2828c11ef 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -480,7 +480,8 @@ xfs_failaddr_t xfs_btree_lblock_v5hdr_verify(struct xfs_buf *bp, xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp, unsigned int max_recs); -uint xfs_btree_compute_maxlevels(uint *limits, unsigned long len); +unsigned int xfs_btree_compute_maxlevels(unsigned int *limits, + unsigned long long len); unsigned int xfs_btree_compute_maxlevels_size(unsigned long long max_btblocks, unsigned int leaf_mnr); unsigned long long xfs_btree_calc_size(uint *limits, unsigned long long len); From patchwork Tue Oct 12 23:33:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553959 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77DB9C433EF for ; Tue, 12 Oct 2021 23:33:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 581DA60ED4 for ; Tue, 12 Oct 2021 23:33:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235952AbhJLXfx (ORCPT ); Tue, 12 Oct 2021 19:35:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:48474 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235840AbhJLXfx (ORCPT ); Tue, 12 Oct 2021 19:35:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 20D3F60E53; Tue, 12 Oct 2021 23:33:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081631; bh=4Wl4/fCtaZrK5Qwat+yF9Twq5uE5Y/LpB4ai0x+lyTc=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=QPUlY9Fm6gMtBdsmK+YLaKbcSShKblQ7CfMxlA1jcSLywz0cZtQDrk/qG8p8JTGDO XjNoEP6qddlfckoPb1rTylXg6JdhDfXJVNtShK2mm9SiC5u7XJbvg94mp8lRn0ocCE wx4fSS87/HgG0mAgfzbx1mOlg1brcXWJgOXtkc2w3zDWkDDsP62hVNRgWsYpPBuGap uwBiDdnaEOB+RZku6AWBL0iRNRXQ8+PRHuxjVLE7O42fXaA55bCwDoyLmgp0w52DV+ KOHNEv623YNBtI1qA4UT5zOhSaiphmemriB1gD+uv4WH0CqjhSbScJKC3EMn9r9O0M OUznjokJEH7+g== Subject: [PATCH 14/15] xfs: compute absolute maximum nlevels for each btree type From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:50 -0700 Message-ID: <163408163084.4151249.13133029541413030318.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 code for all five btree types so that we can compute the absolute maximum possible btree height for each btree type. This is a setup for the next patch, which makes every btree type have its own cursor cache. The functions are exported so that we can have xfs_db report the absolute maximum btree heights for each btree type, rather than making everyone run their own ad-hoc computations. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 1 + fs/xfs/libxfs/xfs_alloc_btree.c | 13 +++++++++++ fs/xfs/libxfs/xfs_alloc_btree.h | 2 ++ fs/xfs/libxfs/xfs_bmap.c | 1 + fs/xfs/libxfs/xfs_bmap_btree.c | 14 ++++++++++++ fs/xfs/libxfs/xfs_bmap_btree.h | 2 ++ fs/xfs/libxfs/xfs_btree.c | 41 ++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_btree.h | 3 +++ fs/xfs/libxfs/xfs_fs.h | 2 ++ fs/xfs/libxfs/xfs_ialloc.c | 1 + fs/xfs/libxfs/xfs_ialloc_btree.c | 19 +++++++++++++++++ fs/xfs/libxfs/xfs_ialloc_btree.h | 2 ++ fs/xfs/libxfs/xfs_refcount_btree.c | 20 ++++++++++++++++++ fs/xfs/libxfs/xfs_refcount_btree.h | 2 ++ fs/xfs/libxfs/xfs_rmap_btree.c | 27 ++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 2 ++ 16 files changed, 152 insertions(+) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 55c5adc9b54e..7145416a230c 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2198,6 +2198,7 @@ xfs_alloc_compute_maxlevels( { mp->m_ag_maxlevels = xfs_btree_compute_maxlevels(mp->m_alloc_mnr, (mp->m_sb.sb_agblocks + 1) / 2); + ASSERT(mp->m_ag_maxlevels <= xfs_allocbt_absolute_maxlevels()); } /* diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index f14bad21503f..61f6d266b822 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -582,6 +582,19 @@ xfs_allocbt_maxrecs( return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t)); } +/* Compute the max possible height of the maximally sized free space btree. */ +unsigned int +xfs_allocbt_absolute_maxlevels(void) +{ + unsigned int minrecs[2]; + + xfs_btree_absolute_minrecs(minrecs, 0, sizeof(xfs_alloc_rec_t), + sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t)); + + return xfs_btree_compute_maxlevels(minrecs, + (XFS_MAX_AG_BLOCKS + 1) / 2); +} + /* Calculate the freespace btree size for some records. */ xfs_extlen_t xfs_allocbt_calc_size( diff --git a/fs/xfs/libxfs/xfs_alloc_btree.h b/fs/xfs/libxfs/xfs_alloc_btree.h index 2f6b816aaf9f..c47d0e285435 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.h +++ b/fs/xfs/libxfs/xfs_alloc_btree.h @@ -60,4 +60,6 @@ extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp, void xfs_allocbt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); +unsigned int xfs_allocbt_absolute_maxlevels(void); + #endif /* __XFS_ALLOC_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 2ae5bf9a74e7..7e70df8d1a9b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -93,6 +93,7 @@ xfs_bmap_compute_maxlevels( maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs; } mp->m_bm_maxlevels[whichfork] = level; + ASSERT(mp->m_bm_maxlevels[whichfork] <= xfs_bmbt_absolute_maxlevels()); } unsigned int diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index b90122de0df0..7001aff639d2 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -587,6 +587,20 @@ xfs_bmbt_maxrecs( return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)); } +/* Compute the max possible height of the maximally sized bmap btree. */ +unsigned int +xfs_bmbt_absolute_maxlevels(void) +{ + unsigned int minrecs[2]; + + xfs_btree_absolute_minrecs(minrecs, XFS_BTREE_LONG_PTRS, + sizeof(struct xfs_bmbt_rec), + sizeof(struct xfs_bmbt_key) + + sizeof(xfs_bmbt_ptr_t)); + + return xfs_btree_compute_maxlevels(minrecs, MAXEXTNUM) + 1; +} + /* * Calculate number of records in a bmap btree inode root. */ diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index 729e3bc569be..e9218e92526b 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -110,4 +110,6 @@ extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, extern unsigned long long xfs_bmbt_calc_size(struct xfs_mount *mp, unsigned long long len); +unsigned int xfs_bmbt_absolute_maxlevels(void); + #endif /* __XFS_BMAP_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index b95c817ad90d..bea1bdf9b8b9 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4964,3 +4964,44 @@ xfs_btree_has_more_records( else return block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK); } + +/* + * Compute absolute minrecs for leaf and node btree blocks. Callers should set + * BTREE_LONG_PTRS and BTREE_OVERLAPPING as they would for regular cursors. + * Set BTREE_CRC_BLOCKS if the btree type is supported /only/ on V5 or newer + * filesystems. + */ +void +xfs_btree_absolute_minrecs( + unsigned int *minrecs, + unsigned int bc_flags, + unsigned int leaf_recbytes, + unsigned int node_recbytes) +{ + unsigned int min_recbytes; + + /* + * If this btree type is supported on V4, we use the smaller V4 min + * block size along with the V4 header size. If the btree type is only + * supported on V5, use the (twice as large) V5 min block size along + * with the V5 header size. + */ + if (!(bc_flags & XFS_BTREE_CRC_BLOCKS)) { + if (bc_flags & XFS_BTREE_LONG_PTRS) + min_recbytes = XFS_MIN_BLOCKSIZE - + XFS_BTREE_LBLOCK_LEN; + else + min_recbytes = XFS_MIN_BLOCKSIZE - + XFS_BTREE_SBLOCK_LEN; + } else if (bc_flags & XFS_BTREE_LONG_PTRS) { + min_recbytes = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_LBLOCK_CRC_LEN; + } else { + min_recbytes = XFS_MIN_CRC_BLOCKSIZE - XFS_BTREE_SBLOCK_CRC_LEN; + } + + if (bc_flags & XFS_BTREE_OVERLAPPING) + node_recbytes <<= 1; + + minrecs[0] = min_recbytes / (2 * leaf_recbytes); + minrecs[1] = min_recbytes / (2 * node_recbytes); +} diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 20a2828c11ef..acb202839afd 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -601,4 +601,7 @@ xfs_btree_alloc_cursor( return cur; } +void xfs_btree_absolute_minrecs(unsigned int *minrecs, unsigned int bc_flags, + unsigned int leaf_recbytes, unsigned int node_recbytes); + #endif /* __XFS_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index bde2b4c64dbe..c43877c8a279 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -268,6 +268,8 @@ typedef struct xfs_fsop_resblks { */ #define XFS_MIN_AG_BYTES (1ULL << 24) /* 16 MB */ #define XFS_MAX_AG_BYTES (1ULL << 40) /* 1 TB */ +#define XFS_MAX_AG_BLOCKS (XFS_MAX_AG_BYTES / XFS_MIN_BLOCKSIZE) +#define XFS_MAX_CRC_AG_BLOCKS (XFS_MAX_AG_BYTES / XFS_MIN_CRC_BLOCKSIZE) /* keep the maximum size under 2^31 by a small amount */ #define XFS_MAX_LOG_BYTES \ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 994ad783d407..017aebdda42f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2793,6 +2793,7 @@ xfs_ialloc_setup_geometry( inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG; igeo->inobt_maxlevels = xfs_btree_compute_maxlevels(igeo->inobt_mnr, inodes); + ASSERT(igeo->inobt_maxlevels <= xfs_inobt_absolute_maxlevels()); /* * Set the maximum inode count for this filesystem, being careful not diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 3a5a24648b87..2e3dd1d798bd 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -542,6 +542,25 @@ xfs_inobt_maxrecs( return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t)); } +/* Compute the max possible height of the maximally sized inode btree. */ +unsigned int +xfs_inobt_absolute_maxlevels(void) +{ + unsigned int minrecs[2]; + unsigned long long max_ag_inodes; + + /* + * For the absolute maximum, pretend that we can fill an entire AG + * completely full of inodes except for the AG headers. + */ + max_ag_inodes = (XFS_MAX_AG_BYTES - (4 * BBSIZE)) / XFS_DINODE_MIN_SIZE; + + xfs_btree_absolute_minrecs(minrecs, 0, sizeof(xfs_inobt_rec_t), + sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t)); + + return xfs_btree_compute_maxlevels(minrecs, max_ag_inodes); +} + /* * Convert the inode record holemask to an inode allocation bitmap. The inode * allocation bitmap is inode granularity and specifies whether an inode is diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index 8a322d402e61..1f09530bf856 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -75,4 +75,6 @@ int xfs_inobt_cur(struct xfs_mount *mp, struct xfs_trans *tp, void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); +unsigned int xfs_inobt_absolute_maxlevels(void); + #endif /* __XFS_IALLOC_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 995b0d86ddc0..bacd1b442b09 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -409,13 +409,33 @@ xfs_refcountbt_maxrecs( sizeof(xfs_refcount_ptr_t)); } +/* Compute the max possible height of the maximally sized refcount btree. */ +unsigned int +xfs_refcountbt_absolute_maxlevels(void) +{ + unsigned int minrecs[2]; + + xfs_btree_absolute_minrecs(minrecs, XFS_BTREE_CRC_BLOCKS, + sizeof(struct xfs_refcount_rec), + sizeof(struct xfs_refcount_key) + + sizeof(xfs_refcount_ptr_t)); + + return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_CRC_AG_BLOCKS); +} + /* Compute the maximum height of a refcount btree. */ void xfs_refcountbt_compute_maxlevels( struct xfs_mount *mp) { + if (!xfs_has_reflink(mp)) { + mp->m_refc_maxlevels = 0; + return; + } + mp->m_refc_maxlevels = xfs_btree_compute_maxlevels( mp->m_refc_mnr, mp->m_sb.sb_agblocks); + ASSERT(mp->m_refc_maxlevels <= xfs_refcountbt_absolute_maxlevels()); } /* Calculate the refcount btree size for some records. */ diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index bd9ed9e1e41f..2625b08f50a8 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -65,4 +65,6 @@ extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp, void xfs_refcountbt_commit_staged_btree(struct xfs_btree_cur *cur, struct xfs_trans *tp, struct xfs_buf *agbp); +unsigned int xfs_refcountbt_absolute_maxlevels(void); + #endif /* __XFS_REFCOUNT_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index b1b55a6e7d25..860627b5ec08 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -535,6 +535,32 @@ xfs_rmapbt_maxrecs( (2 * sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t)); } +/* Compute the max possible height of the maximally sized rmap btree. */ +unsigned int +xfs_rmapbt_absolute_maxlevels(void) +{ + unsigned int minrecs[2]; + + xfs_btree_absolute_minrecs(minrecs, + XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING, + sizeof(struct xfs_rmap_rec), + sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t)); + + /* + * Compute the asymptotic maxlevels for an rmapbt on any reflink fs. + * + * On a reflink filesystem, each AG block can have up to 2^32 (per the + * refcount record format) owners, which means that theoretically we + * could face up to 2^64 rmap records. However, we're likely to run + * out of blocks in the AG long before that happens, which means that + * we must compute the max height based on what the btree will look + * like if it consumes almost all the blocks in the AG due to maximal + * sharing factor. + */ + return xfs_btree_compute_maxlevels_size(XFS_MAX_CRC_AG_BLOCKS, + minrecs[1]); +} + /* Compute the maximum height of an rmap btree. */ void xfs_rmapbt_compute_maxlevels( @@ -573,6 +599,7 @@ xfs_rmapbt_compute_maxlevels( } mp->m_rmap_maxlevels = val; + ASSERT(mp->m_rmap_maxlevels <= xfs_rmapbt_absolute_maxlevels()); } /* Calculate the refcount btree size for some records. */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index f2eee6572af4..84fe74de923f 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -59,4 +59,6 @@ extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_perag *pag, xfs_extlen_t *ask, xfs_extlen_t *used); +unsigned int xfs_rmapbt_absolute_maxlevels(void); + #endif /* __XFS_RMAP_BTREE_H__ */ From patchwork Tue Oct 12 23:33:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12553961 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FA14C433F5 for ; Tue, 12 Oct 2021 23:33:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0ABCE60F3A for ; Tue, 12 Oct 2021 23:33:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234169AbhJLXf7 (ORCPT ); Tue, 12 Oct 2021 19:35:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:48512 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235840AbhJLXf6 (ORCPT ); Tue, 12 Oct 2021 19:35:58 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A334060ED4; Tue, 12 Oct 2021 23:33:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634081636; bh=dGuD/x1oXCIeVu9Rf401sWLdANsdMfnnp3dVlPP3nzo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=YM4HfJHbYYzRZOReFOXwKR+0okbUWMA72CfGojc0+YxutLqk2c94Oo51hWp+yHfE7 S4ruwJyS1ZuWpsokPHrJETm4cFVpSGAwQ5sdlWYsvOIy3QEUR+GuuQPyNEe6pELreJ TLzeyaMSQf7mlusY7I7YYLi41TYzMnrG7Pb36r7qWh3ckhmUJS0zdEQWdoQtVAy48y sKzN1XJM/r3OmraS90J63jHfvXSoGMx1mOt39AKW4U1gcOf+jrO0U3kQPRq9jBIu/p 2Ifl+t+xdE0DRGNfB2vnOGl4dCkD2RFtt9aKfSTnk/83Ue6VroFIEyAYEXkuyxEAup l5SVJYKowzRXA== Subject: [PATCH 15/15] xfs: use separate btree cursor cache for each btree type From: "Darrick J. Wong" To: djwong@kernel.org, david@fromorbit.com Cc: linux-xfs@vger.kernel.org, chandan.babu@oracle.com, hch@lst.de Date: Tue, 12 Oct 2021 16:33:56 -0700 Message-ID: <163408163634.4151249.5333674876821248862.stgit@magnolia> In-Reply-To: <163408155346.4151249.8364703447365270670.stgit@magnolia> References: <163408155346.4151249.8364703447365270670.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 have the infrastructure to track the max possible height of each btree type, we can create a separate slab cache for cursors of each type of btree. For smaller indices like the free space btrees, this means that we can pack more cursors into a slab page, improving slab utilization. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc_btree.c | 21 ++++++++++++++ fs/xfs/libxfs/xfs_alloc_btree.h | 3 ++ fs/xfs/libxfs/xfs_bmap_btree.c | 21 ++++++++++++++ fs/xfs/libxfs/xfs_bmap_btree.h | 3 ++ fs/xfs/libxfs/xfs_btree.c | 7 +---- fs/xfs/libxfs/xfs_btree.h | 17 +++--------- fs/xfs/libxfs/xfs_ialloc_btree.c | 21 ++++++++++++++ fs/xfs/libxfs/xfs_ialloc_btree.h | 3 ++ fs/xfs/libxfs/xfs_refcount_btree.c | 21 ++++++++++++++ fs/xfs/libxfs/xfs_refcount_btree.h | 3 ++ fs/xfs/libxfs/xfs_rmap_btree.c | 21 ++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 3 ++ fs/xfs/xfs_super.c | 53 ++++++++++++++++++++++++++++++++---- 13 files changed, 168 insertions(+), 29 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 61f6d266b822..4c5942146b05 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -20,6 +20,7 @@ #include "xfs_trans.h" #include "xfs_ag.h" +static kmem_zone_t *xfs_allocbt_cur_cache; STATIC struct xfs_btree_cur * xfs_allocbt_dup_cursor( @@ -477,7 +478,8 @@ xfs_allocbt_init_common( ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); - cur = xfs_btree_alloc_cursor(mp, tp, btnum, mp->m_ag_maxlevels); + cur = xfs_btree_alloc_cursor(mp, tp, btnum, mp->m_ag_maxlevels, + xfs_allocbt_cur_cache); cur->bc_ag.abt.active = false; if (btnum == XFS_BTNUM_CNT) { @@ -603,3 +605,20 @@ xfs_allocbt_calc_size( { return xfs_btree_calc_size(mp->m_alloc_mnr, len); } + +int __init +xfs_allocbt_init_cur_cache(void) +{ + xfs_allocbt_cur_cache = kmem_cache_create("xfs_bnobt_cur", + xfs_btree_cur_sizeof(xfs_allocbt_absolute_maxlevels()), + 0, 0, NULL); + + return xfs_allocbt_cur_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_allocbt_destroy_cur_cache(void) +{ + kmem_cache_destroy(xfs_allocbt_cur_cache); + xfs_allocbt_cur_cache = NULL; +} diff --git a/fs/xfs/libxfs/xfs_alloc_btree.h b/fs/xfs/libxfs/xfs_alloc_btree.h index c47d0e285435..82a9b3201f91 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.h +++ b/fs/xfs/libxfs/xfs_alloc_btree.h @@ -62,4 +62,7 @@ void xfs_allocbt_commit_staged_btree(struct xfs_btree_cur *cur, unsigned int xfs_allocbt_absolute_maxlevels(void); +int __init xfs_allocbt_init_cur_cache(void); +void xfs_allocbt_destroy_cur_cache(void); + #endif /* __XFS_ALLOC_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 7001aff639d2..99261d51d2c3 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -22,6 +22,8 @@ #include "xfs_trace.h" #include "xfs_rmap.h" +static kmem_zone_t *xfs_bmbt_cur_cache; + /* * Convert on-disk form of btree root to in-memory form. */ @@ -553,7 +555,7 @@ xfs_bmbt_init_cursor( ASSERT(whichfork != XFS_COW_FORK); cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_BMAP, - mp->m_bm_maxlevels[whichfork]); + mp->m_bm_maxlevels[whichfork], xfs_bmbt_cur_cache); cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2); @@ -664,3 +666,20 @@ xfs_bmbt_calc_size( { return xfs_btree_calc_size(mp->m_bmap_dmnr, len); } + +int __init +xfs_bmbt_init_cur_cache(void) +{ + xfs_bmbt_cur_cache = kmem_cache_create("xfs_bmbt_cur", + xfs_btree_cur_sizeof(xfs_bmbt_absolute_maxlevels()), + 0, 0, NULL); + + return xfs_bmbt_cur_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_bmbt_destroy_cur_cache(void) +{ + kmem_cache_destroy(xfs_bmbt_cur_cache); + xfs_bmbt_cur_cache = NULL; +} diff --git a/fs/xfs/libxfs/xfs_bmap_btree.h b/fs/xfs/libxfs/xfs_bmap_btree.h index e9218e92526b..4c752f7341df 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.h +++ b/fs/xfs/libxfs/xfs_bmap_btree.h @@ -112,4 +112,7 @@ extern unsigned long long xfs_bmbt_calc_size(struct xfs_mount *mp, unsigned int xfs_bmbt_absolute_maxlevels(void); +int __init xfs_bmbt_init_cur_cache(void); +void xfs_bmbt_destroy_cur_cache(void); + #endif /* __XFS_BMAP_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index bea1bdf9b8b9..11ff814996a1 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -23,11 +23,6 @@ #include "xfs_btree_staging.h" #include "xfs_ag.h" -/* - * Cursor allocation zone. - */ -kmem_zone_t *xfs_btree_cur_zone; - /* * Btree magic numbers. */ @@ -379,7 +374,7 @@ xfs_btree_del_cursor( kmem_free(cur->bc_ops); if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS) && cur->bc_ag.pag) xfs_perag_put(cur->bc_ag.pag); - kmem_cache_free(xfs_btree_cur_zone, cur); + kmem_cache_free(cur->bc_cache, cur); } /* diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index acb202839afd..6d61ce1559e2 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -13,8 +13,6 @@ struct xfs_trans; struct xfs_ifork; struct xfs_perag; -extern kmem_zone_t *xfs_btree_cur_zone; - /* * Generic key, ptr and record wrapper structures. * @@ -92,12 +90,6 @@ uint32_t xfs_btree_magic(int crc, xfs_btnum_t btnum); #define XFS_BTREE_STATS_ADD(cur, stat, val) \ XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val) -/* - * The btree cursor zone hands out cursors that can handle up to this many - * levels. This is the known maximum for all btree types. - */ -#define XFS_BTREE_CUR_ZONE_MAXLEVELS (9) - struct xfs_btree_ops { /* size of the key and record structures */ size_t key_len; @@ -238,6 +230,7 @@ struct xfs_btree_cur struct xfs_trans *bc_tp; /* transaction we're in, if any */ struct xfs_mount *bc_mp; /* file system mount struct */ const struct xfs_btree_ops *bc_ops; + kmem_zone_t *bc_cache; /* cursor cache */ unsigned int bc_flags; /* btree features - below */ xfs_btnum_t bc_btnum; /* identifies which btree type */ union xfs_btree_irec bc_rec; /* current insert/search record value */ @@ -586,17 +579,17 @@ xfs_btree_alloc_cursor( struct xfs_mount *mp, struct xfs_trans *tp, xfs_btnum_t btnum, - uint8_t maxlevels) + uint8_t maxlevels, + kmem_zone_t *cache) { struct xfs_btree_cur *cur; - ASSERT(maxlevels <= XFS_BTREE_CUR_ZONE_MAXLEVELS); - - cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); + cur = kmem_cache_zalloc(cache, GFP_NOFS | __GFP_NOFAIL); cur->bc_tp = tp; cur->bc_mp = mp; cur->bc_btnum = btnum; cur->bc_maxlevels = maxlevels; + cur->bc_cache = cache; return cur; } diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 2e3dd1d798bd..2502085d476c 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -22,6 +22,8 @@ #include "xfs_rmap.h" #include "xfs_ag.h" +static kmem_zone_t *xfs_inobt_cur_cache; + STATIC int xfs_inobt_get_minrecs( struct xfs_btree_cur *cur, @@ -433,7 +435,7 @@ xfs_inobt_init_common( struct xfs_btree_cur *cur; cur = xfs_btree_alloc_cursor(mp, tp, btnum, - M_IGEO(mp)->inobt_maxlevels); + M_IGEO(mp)->inobt_maxlevels, xfs_inobt_cur_cache); if (btnum == XFS_BTNUM_INO) { cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2); cur->bc_ops = &xfs_inobt_ops; @@ -776,3 +778,20 @@ xfs_iallocbt_calc_size( { return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, len); } + +int __init +xfs_inobt_init_cur_cache(void) +{ + xfs_inobt_cur_cache = kmem_cache_create("xfs_inobt_cur", + xfs_btree_cur_sizeof(xfs_inobt_absolute_maxlevels()), + 0, 0, NULL); + + return xfs_inobt_cur_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_inobt_destroy_cur_cache(void) +{ + kmem_cache_destroy(xfs_inobt_cur_cache); + xfs_inobt_cur_cache = NULL; +} diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.h b/fs/xfs/libxfs/xfs_ialloc_btree.h index 1f09530bf856..b384733d5e0f 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.h +++ b/fs/xfs/libxfs/xfs_ialloc_btree.h @@ -77,4 +77,7 @@ void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur, unsigned int xfs_inobt_absolute_maxlevels(void); +int __init xfs_inobt_init_cur_cache(void); +void xfs_inobt_destroy_cur_cache(void); + #endif /* __XFS_IALLOC_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index bacd1b442b09..ba27a3ea2ce2 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -21,6 +21,8 @@ #include "xfs_rmap.h" #include "xfs_ag.h" +static kmem_zone_t *xfs_refcountbt_cur_cache; + static struct xfs_btree_cur * xfs_refcountbt_dup_cursor( struct xfs_btree_cur *cur) @@ -323,7 +325,7 @@ xfs_refcountbt_init_common( ASSERT(pag->pag_agno < mp->m_sb.sb_agcount); cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_REFC, - mp->m_refc_maxlevels); + mp->m_refc_maxlevels, xfs_refcountbt_cur_cache); cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; @@ -505,3 +507,20 @@ xfs_refcountbt_calc_reserves( return error; } + +int __init +xfs_refcountbt_init_cur_cache(void) +{ + xfs_refcountbt_cur_cache = kmem_cache_create("xfs_refcbt_cur", + xfs_btree_cur_sizeof(xfs_refcountbt_absolute_maxlevels()), + 0, 0, NULL); + + return xfs_refcountbt_cur_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_refcountbt_destroy_cur_cache(void) +{ + kmem_cache_destroy(xfs_refcountbt_cur_cache); + xfs_refcountbt_cur_cache = NULL; +} diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h index 2625b08f50a8..a1437d0a5717 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.h +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -67,4 +67,7 @@ void xfs_refcountbt_commit_staged_btree(struct xfs_btree_cur *cur, unsigned int xfs_refcountbt_absolute_maxlevels(void); +int __init xfs_refcountbt_init_cur_cache(void); +void xfs_refcountbt_destroy_cur_cache(void); + #endif /* __XFS_REFCOUNT_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 860627b5ec08..0a9bc37c01d0 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -22,6 +22,8 @@ #include "xfs_ag.h" #include "xfs_ag_resv.h" +static kmem_zone_t *xfs_rmapbt_cur_cache; + /* * Reverse map btree. * @@ -453,7 +455,7 @@ xfs_rmapbt_init_common( /* Overlapping btree; 2 keys per pointer. */ cur = xfs_btree_alloc_cursor(mp, tp, XFS_BTNUM_RMAP, - mp->m_rmap_maxlevels); + mp->m_rmap_maxlevels, xfs_rmapbt_cur_cache); cur->bc_flags = XFS_BTREE_CRC_BLOCKS | XFS_BTREE_OVERLAPPING; cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); cur->bc_ops = &xfs_rmapbt_ops; @@ -670,3 +672,20 @@ xfs_rmapbt_calc_reserves( return error; } + +int __init +xfs_rmapbt_init_cur_cache(void) +{ + xfs_rmapbt_cur_cache = kmem_cache_create("xfs_rmapbt_cur", + xfs_btree_cur_sizeof(xfs_rmapbt_absolute_maxlevels()), + 0, 0, NULL); + + return xfs_rmapbt_cur_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_rmapbt_destroy_cur_cache(void) +{ + kmem_cache_destroy(xfs_rmapbt_cur_cache); + xfs_rmapbt_cur_cache = NULL; +} diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 84fe74de923f..dd5422850656 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -61,4 +61,7 @@ extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, unsigned int xfs_rmapbt_absolute_maxlevels(void); +int __init xfs_rmapbt_init_cur_cache(void); +void xfs_rmapbt_destroy_cur_cache(void); + #endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 90c92a6a49e0..399d7cfc7d4b 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -37,6 +37,13 @@ #include "xfs_reflink.h" #include "xfs_pwork.h" #include "xfs_ag.h" +#include "xfs_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_ialloc_btree.h" +#include "xfs_bmap_btree.h" +#include "xfs_rmap_btree.h" +#include "xfs_refcount_btree.h" + #include #include @@ -1950,9 +1957,45 @@ static struct file_system_type xfs_fs_type = { }; MODULE_ALIAS_FS("xfs"); +STATIC int __init +xfs_init_btree_cur_caches(void) +{ + int error; + + error = xfs_allocbt_init_cur_cache(); + if (error) + return error; + error = xfs_inobt_init_cur_cache(); + if (error) + return error; + error = xfs_bmbt_init_cur_cache(); + if (error) + return error; + error = xfs_rmapbt_init_cur_cache(); + if (error) + return error; + error = xfs_refcountbt_init_cur_cache(); + if (error) + return error; + + return 0; +} + +STATIC void +xfs_destroy_btree_cur_caches(void) +{ + xfs_allocbt_destroy_cur_cache(); + xfs_inobt_destroy_cur_cache(); + xfs_bmbt_destroy_cur_cache(); + xfs_rmapbt_destroy_cur_cache(); + xfs_refcountbt_destroy_cur_cache(); +} + STATIC int __init xfs_init_zones(void) { + int error; + xfs_log_ticket_zone = kmem_cache_create("xfs_log_ticket", sizeof(struct xlog_ticket), 0, 0, NULL); @@ -1965,10 +2008,8 @@ xfs_init_zones(void) if (!xfs_bmap_free_item_zone) goto out_destroy_log_ticket_zone; - xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur", - xfs_btree_cur_sizeof(XFS_BTREE_CUR_ZONE_MAXLEVELS), - 0, 0, NULL); - if (!xfs_btree_cur_zone) + error = xfs_init_btree_cur_caches(); + if (error) goto out_destroy_bmap_free_item_zone; xfs_da_state_zone = kmem_cache_create("xfs_da_state", @@ -2106,7 +2147,7 @@ xfs_init_zones(void) out_destroy_da_state_zone: kmem_cache_destroy(xfs_da_state_zone); out_destroy_btree_cur_zone: - kmem_cache_destroy(xfs_btree_cur_zone); + xfs_destroy_btree_cur_caches(); out_destroy_bmap_free_item_zone: kmem_cache_destroy(xfs_bmap_free_item_zone); out_destroy_log_ticket_zone: @@ -2138,7 +2179,7 @@ xfs_destroy_zones(void) kmem_cache_destroy(xfs_trans_zone); kmem_cache_destroy(xfs_ifork_zone); kmem_cache_destroy(xfs_da_state_zone); - kmem_cache_destroy(xfs_btree_cur_zone); + xfs_destroy_btree_cur_caches(); kmem_cache_destroy(xfs_bmap_free_item_zone); kmem_cache_destroy(xfs_log_ticket_zone); }