]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: refactor the allocation and freeing of incore inode fork btree roots
authorDarrick J. Wong <djwong@kernel.org>
Thu, 15 Aug 2024 18:48:30 +0000 (11:48 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 16 Aug 2024 21:54:19 +0000 (14:54 -0700)
Refactor the code that allocates and freese the incore inode fork btree
roots.  This will help us disentangle some of the weird logic when we're
creating and tearing down inode-based btrees.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_inode_fork.h

index 35ea6642d969fc962dc23d6fa29a187cd36e240f..435ccb2496ccdf55fbec601fa7473f8b09cc35a4 100644 (file)
@@ -211,9 +211,7 @@ xfs_iformat_btree(
                return -EFSCORRUPTED;
        }
 
-       ifp->if_broot_bytes = size;
-       ifp->if_broot = kmalloc(size,
-                               GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+       xfs_iroot_alloc(ip, whichfork, size);
        ASSERT(ifp->if_broot != NULL);
        /*
         * Copy and convert from the on-disk structure
@@ -362,6 +360,33 @@ xfs_iformat_attr_fork(
        return error;
 }
 
+/* Allocate a new incore ifork btree root. */
+void
+xfs_iroot_alloc(
+       struct xfs_inode        *ip,
+       int                     whichfork,
+       size_t                  bytes)
+{
+       struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
+
+       ifp->if_broot = kmalloc(bytes,
+                       GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+       ifp->if_broot_bytes = bytes;
+}
+
+/* Free all the memory and state associated with an incore ifork btree root. */
+void
+xfs_iroot_free(
+       struct xfs_inode        *ip,
+       int                     whichfork)
+{
+       struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
+
+       ifp->if_broot_bytes = 0;
+       kfree(ifp->if_broot);
+       ifp->if_broot = NULL;
+}
+
 /*
  * Reallocate the space for if_broot based on the number of records
  * being added or deleted as indicated in rec_diff.  Move the records
@@ -410,9 +435,7 @@ xfs_iroot_realloc(
                 */
                if (ifp->if_broot_bytes == 0) {
                        new_size = xfs_bmap_broot_space_calc(mp, rec_diff);
-                       ifp->if_broot = kmalloc(new_size,
-                                               GFP_KERNEL | __GFP_NOFAIL);
-                       ifp->if_broot_bytes = (int)new_size;
+                       xfs_iroot_alloc(ip, whichfork, new_size);
                        return;
                }
 
@@ -451,17 +474,16 @@ xfs_iroot_realloc(
                new_size = xfs_bmap_broot_space_calc(mp, new_max);
        else
                new_size = 0;
-       if (new_size > 0) {
-               new_broot = kmalloc(new_size, GFP_KERNEL | __GFP_NOFAIL);
-               /*
-                * First copy over the btree block header.
-                */
-               memcpy(new_broot, ifp->if_broot,
-                       xfs_bmbt_block_len(ip->i_mount));
-       } else {
-               new_broot = NULL;
+       if (new_size == 0) {
+               xfs_iroot_free(ip, whichfork);
+               return;
        }
 
+       /* First copy over the btree block header. */
+       new_broot = kmalloc(new_size,
+                       GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
+       memcpy(new_broot, ifp->if_broot, xfs_bmbt_block_len(ip->i_mount));
+
        /*
         * Only copy the records and pointers if there are any.
         */
@@ -485,9 +507,8 @@ xfs_iroot_realloc(
        kfree(ifp->if_broot);
        ifp->if_broot = new_broot;
        ifp->if_broot_bytes = (int)new_size;
-       if (ifp->if_broot)
-               ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
-                       xfs_inode_fork_size(ip, whichfork));
+       ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
+               xfs_inode_fork_size(ip, whichfork));
        return;
 }
 
index 2373d12fd474f0cc4f8227a038a554649f580ee7..3f228a00b67ddf667c24805b6cab4bead31dda6d 100644 (file)
@@ -170,6 +170,9 @@ void                xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *,
 void           xfs_idestroy_fork(struct xfs_ifork *ifp);
 void *         xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff,
                                int whichfork);
+void           xfs_iroot_alloc(struct xfs_inode *ip, int whichfork,
+                               size_t bytes);
+void           xfs_iroot_free(struct xfs_inode *ip, int whichfork);
 void           xfs_iroot_realloc(struct xfs_inode *, int, int);
 int            xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
 int            xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,