From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_inode_fork.c | 53 ++++++++++++++++++++++++++++------------ fs/xfs/libxfs/xfs_inode_fork.h | 3 ++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 9d53df7ce49d..0f220f100069 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -207,8 +207,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 @@ -344,6 +343,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 @@ -392,8 +417,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; } @@ -432,17 +456,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. */ @@ -466,9 +488,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; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index c201d8ad5957..f4379e2df616 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -171,6 +171,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 *,