]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: refactor the allocation and freeing of incore inode fork btree roots
authorDarrick J. Wong <djwong@kernel.org>
Tue, 7 Mar 2023 03:55:32 +0000 (19:55 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 22 Nov 2023 23:03:35 +0000 (15:03 -0800)
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>
libxfs/xfs_inode_fork.c
libxfs/xfs_inode_fork.h

index 6359d2ec14582a283c3e395c43fdd406e741e6af..05a87f512de3e5fda76eb874393fa3b30d6d7440 100644 (file)
@@ -205,8 +205,7 @@ xfs_iformat_btree(
                return -EFSCORRUPTED;
        }
 
-       ifp->if_broot_bytes = size;
-       ifp->if_broot = kmem_alloc(size, KM_NOFS);
+       xfs_iroot_alloc(ip, whichfork, size);
        ASSERT(ifp->if_broot != NULL);
        /*
         * Copy and convert from the on-disk structure
@@ -356,6 +355,32 @@ 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 = kmem_alloc(bytes, KM_NOFS);
+       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;
+       kmem_free(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
@@ -404,8 +429,7 @@ xfs_iroot_realloc(
                 */
                if (ifp->if_broot_bytes == 0) {
                        new_size = xfs_bmap_broot_space_calc(mp, rec_diff);
-                       ifp->if_broot = kmem_alloc(new_size, KM_NOFS);
-                       ifp->if_broot_bytes = (int)new_size;
+                       xfs_iroot_alloc(ip, whichfork, new_size);
                        return;
                }
 
@@ -444,17 +468,15 @@ xfs_iroot_realloc(
                new_size = xfs_bmap_broot_space_calc(mp, new_max);
        else
                new_size = 0;
-       if (new_size > 0) {
-               new_broot = kmem_alloc(new_size, KM_NOFS);
-               /*
-                * 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 = kmem_alloc(new_size, KM_NOFS);
+       memcpy(new_broot, ifp->if_broot, xfs_bmbt_block_len(ip->i_mount));
+
        /*
         * Only copy the records and pointers if there are any.
         */
@@ -478,9 +500,8 @@ xfs_iroot_realloc(
        kmem_free(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 ebeb925be09d9c420cf9d3d6a3d2c4eb13df324f..18ea2d27777a2749e0496e1895ec2409017c93d8 100644 (file)
@@ -172,6 +172,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 *,