@@ -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
@@ -358,6 +357,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
@@ -406,8 +431,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;
}
@@ -446,17 +470,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.
*/
@@ -480,9 +502,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;
}
@@ -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 *,