]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: make xfs_iroot_realloc a bmap btree function
authorDarrick J. Wong <djwong@kernel.org>
Mon, 24 Feb 2025 18:21:45 +0000 (10:21 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 25 Feb 2025 17:15:57 +0000 (09:15 -0800)
Source kernel commit: eb9bff22311ca47ef4848bbdcf24dae06ae3f243

Move the inode fork btree root reallocation function part of the btree
ops because it's now mostly bmbt-specific code.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_bmap.c
libxfs/xfs_bmap_btree.c
libxfs/xfs_bmap_btree.h
libxfs/xfs_btree.c
libxfs/xfs_btree.h
libxfs/xfs_inode_fork.c
libxfs/xfs_inode_fork.h

index 2482f56dbb6ad66170d9c6913c7e422f523f0e5a..fcb400bc768c2fdb305920e7383175c09e630d7a 100644 (file)
@@ -609,7 +609,7 @@ xfs_bmap_btree_to_extents(
        xfs_trans_binval(tp, cbp);
        if (cur->bc_levels[0].bp == cbp)
                cur->bc_levels[0].bp = NULL;
-       xfs_iroot_realloc(ip, whichfork, 0);
+       xfs_bmap_broot_realloc(ip, whichfork, 0);
        ASSERT(ifp->if_broot == NULL);
        ifp->if_format = XFS_DINODE_FMT_EXTENTS;
        *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
@@ -653,7 +653,7 @@ xfs_bmap_extents_to_btree(
         * Make space in the inode incore. This needs to be undone if we fail
         * to expand the root.
         */
-       block = xfs_iroot_realloc(ip, whichfork, 1);
+       block = xfs_bmap_broot_realloc(ip, whichfork, 1);
 
        /*
         * Fill in the root.
@@ -739,7 +739,7 @@ xfs_bmap_extents_to_btree(
 out_unreserve_dquot:
        xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
 out_root_realloc:
-       xfs_iroot_realloc(ip, whichfork, 0);
+       xfs_bmap_broot_realloc(ip, whichfork, 0);
        ifp->if_format = XFS_DINODE_FMT_EXTENTS;
        ASSERT(ifp->if_broot == NULL);
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
index 62e79d8fc49784e44f0eec27ef8a74f16470e1b3..baae9ab91fa9086b6efdaf6faa2691fa71ca9397 100644 (file)
@@ -515,6 +515,109 @@ xfs_bmbt_keys_contiguous(
                                 be64_to_cpu(key2->bmbt.br_startoff));
 }
 
+/*
+ * Reallocate the space for if_broot based on the number of records.  Move the
+ * records and pointers in if_broot to fit the new size.  When shrinking this
+ * will eliminate holes between the records and pointers created by the caller.
+ * When growing this will create holes to be filled in by the caller.
+ *
+ * The caller must not request to add more records than would fit in the
+ * on-disk inode root.  If the if_broot is currently NULL, then if we are
+ * adding records, one will be allocated.  The caller must also not request
+ * that the number of records go below zero, although it can go to zero.
+ *
+ * ip -- the inode whose if_broot area is changing
+ * whichfork -- which inode fork to change
+ * new_numrecs -- the new number of records requested for the if_broot array
+ *
+ * Returns the incore btree root block.
+ */
+struct xfs_btree_block *
+xfs_bmap_broot_realloc(
+       struct xfs_inode        *ip,
+       int                     whichfork,
+       unsigned int            new_numrecs)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
+       char                    *np;
+       char                    *op;
+       unsigned int            new_size;
+       unsigned int            old_size = ifp->if_broot_bytes;
+
+       /*
+        * Block mapping btrees do not support storing zero records; if this
+        * happens, the fork is being changed to FMT_EXTENTS.  Free the broot
+        * and get out.
+        */
+       if (new_numrecs == 0)
+               return xfs_broot_realloc(ifp, 0);
+
+       new_size = xfs_bmap_broot_space_calc(mp, new_numrecs);
+
+       /* Handle the nop case quietly. */
+       if (new_size == old_size)
+               return ifp->if_broot;
+
+       if (new_size > old_size) {
+               unsigned int    old_numrecs;
+
+               /*
+                * If there wasn't any memory allocated before, just
+                * allocate it now and get out.
+                */
+               if (old_size == 0)
+                       return xfs_broot_realloc(ifp, new_size);
+
+               /*
+                * If there is already an existing if_broot, then we need
+                * to realloc() it and shift the pointers to their new
+                * location.  The records don't change location because
+                * they are kept butted up against the btree block header.
+                */
+               old_numrecs = xfs_bmbt_maxrecs(mp, old_size, false);
+               xfs_broot_realloc(ifp, new_size);
+               op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
+                                                    old_size);
+               np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
+                                                    (int)new_size);
+               ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
+                       xfs_inode_fork_size(ip, whichfork));
+               memmove(np, op, old_numrecs * (uint)sizeof(xfs_fsblock_t));
+               return ifp->if_broot;
+       }
+
+       /*
+        * We're reducing, but not totally eliminating, numrecs.  In this case,
+        * we are shrinking the if_broot buffer, so it must already exist.
+        */
+       ASSERT(ifp->if_broot != NULL && old_size > 0 && new_size > 0);
+
+       /*
+        * Shrink the btree root by moving the bmbt pointers, since they are
+        * not butted up against the btree block header, then reallocating
+        * broot.
+        */
+       op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, old_size);
+       np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
+                                            (int)new_size);
+       memmove(np, op, new_numrecs * (uint)sizeof(xfs_fsblock_t));
+
+       xfs_broot_realloc(ifp, new_size);
+       ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
+              xfs_inode_fork_size(ip, whichfork));
+       return ifp->if_broot;
+}
+
+static struct xfs_btree_block *
+xfs_bmbt_broot_realloc(
+       struct xfs_btree_cur    *cur,
+       unsigned int            new_numrecs)
+{
+       return xfs_bmap_broot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork,
+                       new_numrecs);
+}
+
 const struct xfs_btree_ops xfs_bmbt_ops = {
        .name                   = "bmap",
        .type                   = XFS_BTREE_TYPE_INODE,
@@ -542,6 +645,7 @@ const struct xfs_btree_ops xfs_bmbt_ops = {
        .keys_inorder           = xfs_bmbt_keys_inorder,
        .recs_inorder           = xfs_bmbt_recs_inorder,
        .keys_contiguous        = xfs_bmbt_keys_contiguous,
+       .broot_realloc          = xfs_bmbt_broot_realloc,
 };
 
 /*
index 49a3bae3f6ecec331b8f5936dad3b922ba2805d6..b238d559ab036999ba10f1ef8702ecaca52840b2 100644 (file)
@@ -198,4 +198,7 @@ xfs_bmap_bmdr_space(struct xfs_btree_block *bb)
        return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs));
 }
 
+struct xfs_btree_block *xfs_bmap_broot_realloc(struct xfs_inode *ip,
+               int whichfork, unsigned int new_numrecs);
+
 #endif /* __XFS_BMAP_BTREE_H__ */
index 85f4f7b3e9813d303bcc15c1939f191adca2cf64..3d2bedc79fc270e3ee939449600ac8f12f61e3b8 100644 (file)
@@ -3159,7 +3159,7 @@ xfs_btree_new_iroot(
 
        xfs_btree_copy_ptrs(cur, pp, &nptr, 1);
 
-       xfs_iroot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork, 1);
+       cur->bc_ops->broot_realloc(cur, 1);
 
        xfs_btree_setbuf(cur, level, cbp);
 
@@ -3343,8 +3343,7 @@ xfs_btree_make_block_unfull(
 
                if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {
                        /* A root block that can be made bigger. */
-                       xfs_iroot_realloc(ip, cur->bc_ino.whichfork,
-                                       numrecs + 1);
+                       cur->bc_ops->broot_realloc(cur, numrecs + 1);
                        *stat = 1;
                } else {
                        /* A root block that needs replacing */
@@ -3756,8 +3755,7 @@ xfs_btree_kill_iroot(
        ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
 #endif
 
-       block = xfs_iroot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork,
-                       numrecs);
+       block = cur->bc_ops->broot_realloc(cur, numrecs);
 
        block->bb_numrecs = be16_to_cpu(numrecs);
        ASSERT(block->bb_numrecs == cblock->bb_numrecs);
@@ -3942,8 +3940,7 @@ xfs_btree_delrec(
         * nothing left to do.  numrecs was decremented above.
         */
        if (xfs_btree_at_iroot(cur, level)) {
-               xfs_iroot_realloc(cur->bc_ino.ip, cur->bc_ino.whichfork,
-                               numrecs);
+               cur->bc_ops->broot_realloc(cur, numrecs);
 
                error = xfs_btree_kill_iroot(cur);
                if (error)
index c5bff273cae255d94ef5715aeec64121187d0a68..8380ae0a64dd5e83addd02179a78b3f93f950fbd 100644 (file)
@@ -213,6 +213,22 @@ struct xfs_btree_ops {
                               const union xfs_btree_key *key1,
                               const union xfs_btree_key *key2,
                               const union xfs_btree_key *mask);
+
+       /*
+        * Reallocate the space for if_broot to fit the number of records.
+        * Move the records and pointers in if_broot to fit the new size.  When
+        * shrinking this will eliminate holes between the records and pointers
+        * created by the caller.  When growing this will create holes to be
+        * filled in by the caller.
+        *
+        * The caller must not request to add more records than would fit in
+        * the on-disk inode root.  If the if_broot is currently NULL, then if
+        * we are adding records, one will be allocated.  The caller must also
+        * not request that the number of records go below zero, although it
+        * can go to zero.
+        */
+       struct xfs_btree_block *(*broot_realloc)(struct xfs_btree_cur *cur,
+                               unsigned int new_numrecs);
 };
 
 /* btree geometry flags */
index baebcbc26eb29b8c6f45db1052ce81d722cd06fc..d6bbff85ffba8e15199117585e1e9c902934536a 100644 (file)
@@ -420,102 +420,6 @@ xfs_broot_realloc(
        return ifp->if_broot;
 }
 
-/*
- * Reallocate the space for if_broot based on the number of records.  Move the
- * records and pointers in if_broot to fit the new size.  When shrinking this
- * will eliminate holes between the records and pointers created by the caller.
- * When growing this will create holes to be filled in by the caller.
- *
- * The caller must not request to add more records than would fit in
- * the on-disk inode root.  If the if_broot is currently NULL, then
- * if we are adding records, one will be allocated.  The caller must also
- * not request that the number of records go below zero, although
- * it can go to zero.
- *
- * ip -- the inode whose if_broot area is changing
- * whichfork -- which inode fork to change
- * new_numrecs -- the new number of records requested for the if_broot array
- *
- * Returns the incore btree root block.
- */
-struct xfs_btree_block *
-xfs_iroot_realloc(
-       struct xfs_inode        *ip,
-       int                     whichfork,
-       unsigned int            new_numrecs)
-{
-       struct xfs_mount        *mp = ip->i_mount;
-       struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
-       char                    *np;
-       char                    *op;
-       unsigned int            new_size;
-       unsigned int            old_size = ifp->if_broot_bytes;
-
-       /*
-        * Block mapping btrees do not support storing zero records; if this
-        * happens, the fork is being changed to FMT_EXTENTS.  Free the broot
-        * and get out.
-        */
-       if (new_numrecs == 0)
-               return xfs_broot_realloc(ifp, 0);
-
-       new_size = xfs_bmap_broot_space_calc(mp, new_numrecs);
-
-       /* Handle the nop case quietly. */
-       if (new_size == old_size)
-               return ifp->if_broot;
-
-       if (new_size > old_size) {
-               unsigned int    old_numrecs;
-
-               /*
-                * If there wasn't any memory allocated before, just
-                * allocate it now and get out.
-                */
-               if (old_size == 0)
-                       return xfs_broot_realloc(ifp, new_size);
-
-               /*
-                * If there is already an existing if_broot, then we need
-                * to realloc() it and shift the pointers to their new
-                * location.  The records don't change location because
-                * they are kept butted up against the btree block header.
-                */
-               old_numrecs = xfs_bmbt_maxrecs(mp, old_size, false);
-               xfs_broot_realloc(ifp, new_size);
-               op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
-                                                    old_size);
-               np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
-                                                    (int)new_size);
-               ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
-                       xfs_inode_fork_size(ip, whichfork));
-               memmove(np, op, old_numrecs * (uint)sizeof(xfs_fsblock_t));
-               return ifp->if_broot;
-       }
-
-       /*
-        * We're reducing, but not totally eliminating, numrecs.  In this case,
-        * we are shrinking the if_broot buffer, so it must already exist.
-        */
-       ASSERT(ifp->if_broot != NULL && old_size > 0 && new_size > 0);
-
-       /*
-        * Shrink the btree root by moving the bmbt pointers, since they are
-        * not butted up against the btree block header, then reallocating
-        * broot.
-        */
-       op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, old_size);
-       np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1,
-                                            (int)new_size);
-       memmove(np, op, new_numrecs * (uint)sizeof(xfs_fsblock_t));
-
-       xfs_broot_realloc(ifp, new_size);
-       ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
-              xfs_inode_fork_size(ip, whichfork));
-       return ifp->if_broot;
-}
-
-
 /*
  * This is called when the amount of space needed for if_data
  * is increased or decreased.  The change in size is indicated by
index d05eb0bad864e13b6032ee3ca4efd66d7001ebb3..69ed0919d60b12b459aec89722b0c71e3254550a 100644 (file)
@@ -175,8 +175,6 @@ struct xfs_btree_block *xfs_broot_alloc(struct xfs_ifork *ifp,
 struct xfs_btree_block *xfs_broot_realloc(struct xfs_ifork *ifp,
                                size_t new_size);
 
-struct xfs_btree_block *xfs_iroot_realloc(struct xfs_inode *ip, int whichfork,
-                               unsigned int new_numrecs);
 int            xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
 int            xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
                                  int);