From 6f5865eb86c35401f12f62db38dd9bad1a985cbd Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 15 Aug 2024 11:48:30 -0700 Subject: [PATCH] xfs: refactor the allocation and freeing of incore inode fork btree roots 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 --- fs/xfs/libxfs/xfs_inode_fork.c | 57 +++++++++++++++++++++++----------- fs/xfs/libxfs/xfs_inode_fork.h | 3 ++ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 35ea6642d969..435ccb2496cc 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -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; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 2373d12fd474..3f228a00b67d 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -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 *, -- 2.50.1