]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: make xfs_iroot_realloc a bmap btree function
authorDarrick J. Wong <djwong@kernel.org>
Fri, 30 Aug 2024 00:42:23 +0000 (17:42 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 9 Oct 2024 23:29:16 +0000 (16:29 -0700)
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>
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 c6cff9658d21a4e5832e06926039a381d1064fc6..582952fdeee1a658d68ecafe0d7250946965b41f 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, ifp, 0);
+       xfs_bmap_broot_realloc(ip, ifp, 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, ifp, 1);
+       block = xfs_bmap_broot_realloc(ip, ifp, 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, ifp, 0);
+       xfs_bmap_broot_realloc(ip, ifp, 0);
        ifp->if_format = XFS_DINODE_FMT_EXTENTS;
        ASSERT(ifp->if_broot == NULL);
        xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
index 62e79d8fc49784e44f0eec27ef8a74f16470e1b3..46536e80f348303d8f6b682ce3e0d5bac1d6c14f 100644 (file)
@@ -515,6 +515,110 @@ 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
+ * ifp -- 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,
+       struct xfs_ifork        *ifp,
+       unsigned int            new_numrecs)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       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) {
+               xfs_broot_free(ifp);
+               return NULL;
+       }
+
+       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, xfs_ifork_which(ip, ifp)));
+               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, xfs_ifork_which(ip, ifp)));
+       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, xfs_btree_ifork_ptr(cur),
+                       new_numrecs);
+}
+
 const struct xfs_btree_ops xfs_bmbt_ops = {
        .name                   = "bmap",
        .type                   = XFS_BTREE_TYPE_INODE,
@@ -542,6 +646,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..18b35c779045ec37abbf3c110b8eda09c2ede267 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,
+               struct xfs_ifork *ifp, unsigned int new_numrecs);
+
 #endif /* __XFS_BMAP_BTREE_H__ */
index 6864ac5d4800e2ff7b633f0d16c7ff82ee588ad6..1e303156524f8e47d9826ffed8106a39e3200c7a 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, xfs_btree_ifork_ptr(cur), 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, xfs_btree_ifork_ptr(cur),
-                                       numrecs + 1);
+                       cur->bc_ops->broot_realloc(cur, numrecs + 1);
                        *stat = 1;
                } else {
                        /* A root block that needs replacing */
@@ -3739,8 +3738,7 @@ xfs_btree_kill_iroot(
        ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
 #endif
 
-       block = xfs_iroot_realloc(cur->bc_ino.ip, xfs_btree_ifork_ptr(cur),
-                       numrecs);
+       block = cur->bc_ops->broot_realloc(cur, numrecs);
 
        block->bb_numrecs = be16_to_cpu(numrecs);
        ASSERT(block->bb_numrecs == cblock->bb_numrecs);
@@ -3925,8 +3923,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, xfs_btree_ifork_ptr(cur),
-                               numrecs);
+               cur->bc_ops->broot_realloc(cur, numrecs);
 
                error = xfs_btree_kill_iroot(cur);
                if (error)
index 3b739459ebb0f4c51630533c152e24b9d64699f0..b3bae649726e1c07532456088e6459508f4d3f6f 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 ef6ee29ab8cb59eb8e20559f8084f0141e4c7c83..d9c37c07048f89c99bfd8b3a972f4632289c8e7f 100644 (file)
@@ -406,103 +406,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
- * ifp -- 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,
-       struct xfs_ifork        *ifp,
-       unsigned int            new_numrecs)
-{
-       struct xfs_mount        *mp = ip->i_mount;
-       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) {
-               xfs_broot_free(ifp);
-               return NULL;
-       }
-
-       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, xfs_ifork_which(ip, ifp)));
-               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, xfs_ifork_which(ip, ifp)));
-       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 5fb33773de8fc2c2867b166ff295798482b357e8..9426f945193bab88733ca4db4ef3b386341ffe32 100644 (file)
@@ -185,9 +185,6 @@ xfs_broot_free(struct xfs_ifork *ifp)
        __xfs_broot_realloc(ifp, 0, 0);
 }
 
-struct xfs_btree_block *xfs_iroot_realloc(struct xfs_inode *ip,
-                               struct xfs_ifork *ifp,
-                               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);