]> www.infradead.org Git - users/hch/xfs.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)
committerChristoph Hellwig <hch@lst.de>
Sun, 22 Sep 2024 08:01:33 +0000 (10:01 +0200)
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>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap_btree.c
fs/xfs/libxfs/xfs_bmap_btree.h
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_inode_fork.h

index 40ba68d12befe5bcec4c27191f994a0ec2886343..bcc995589aa0d6a3fc4b2f575825272886c0bcb0 100644 (file)
@@ -615,7 +615,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);
@@ -659,7 +659,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.
@@ -745,7 +745,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 3464be771f95d809bc2b10fbd3bef8c657bfb01b..5b063ba0cb9ea1ab16c529bee1cdec92fd1afcc0 100644 (file)
@@ -516,6 +516,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,
@@ -543,6 +647,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 4cc63e499474889d3457015b734132095d2c2fdf..44e60287dc7d9b65c97ed2ac1ddfbc5a61176ffc 100644 (file)
@@ -3161,7 +3161,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);
 
@@ -3345,8 +3345,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 */
@@ -3741,8 +3740,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);
@@ -3927,8 +3925,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 5eacd7a77f2c1351578f55255cb2285fb66a4f20..db1ce93d98993023697113c2eccd8464586d8e18 100644 (file)
@@ -408,103 +408,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);