mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-13 01:32:18 -04:00
xfs: hoist the node iroot update code out of xfs_btree_kill_iroot
In preparation for allowing records in an inode btree root, hoist the code that copies keyptrs from an existing node child into the root block to a separate function. Remove some unnecessary conditionals and clean up a few function calls in the new function. Note that this change reorders the ->free_block call with respect to the change in bc_nlevels to make it easier to support inode root leaf blocks in the next patch. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
@@ -3726,6 +3726,60 @@ xfs_btree_insert(
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the keyptrs from a child node block to the root block.
|
||||
*
|
||||
* Since the keyptr size does not change, all we have to do is increase the
|
||||
* tree height, copy the keyptrs to the new internal node (cblock), shrink
|
||||
* the root, and copy the pointers there.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_btree_demote_node_child(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *cblock,
|
||||
int level,
|
||||
int numrecs)
|
||||
{
|
||||
struct xfs_btree_block *block;
|
||||
union xfs_btree_key *ckp;
|
||||
union xfs_btree_key *kp;
|
||||
union xfs_btree_ptr *cpp;
|
||||
union xfs_btree_ptr *pp;
|
||||
int i;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Adjust the root btree node size and the record count to match the
|
||||
* doomed child so that we can copy the keyptrs ahead of changing the
|
||||
* tree shape.
|
||||
*/
|
||||
block = cur->bc_ops->broot_realloc(cur, numrecs);
|
||||
|
||||
xfs_btree_set_numrecs(block, numrecs);
|
||||
ASSERT(block->bb_numrecs == cblock->bb_numrecs);
|
||||
|
||||
/* Copy keys from the doomed block. */
|
||||
kp = xfs_btree_key_addr(cur, 1, block);
|
||||
ckp = xfs_btree_key_addr(cur, 1, cblock);
|
||||
xfs_btree_copy_keys(cur, kp, ckp, numrecs);
|
||||
|
||||
/* Copy pointers from the doomed block. */
|
||||
pp = xfs_btree_ptr_addr(cur, 1, block);
|
||||
cpp = xfs_btree_ptr_addr(cur, 1, cblock);
|
||||
for (i = 0; i < numrecs; i++) {
|
||||
error = xfs_btree_debug_check_ptr(cur, cpp, i, level - 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
xfs_btree_copy_ptrs(cur, pp, cpp, numrecs);
|
||||
|
||||
/* Decrease tree height, adjusting the root block level to match. */
|
||||
cur->bc_levels[level - 1].bp = NULL;
|
||||
be16_add_cpu(&block->bb_level, -1);
|
||||
cur->bc_nlevels--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to merge a non-leaf block back into the inode root.
|
||||
*
|
||||
@@ -3741,10 +3795,6 @@ xfs_btree_kill_iroot(
|
||||
struct xfs_inode *ip = cur->bc_ino.ip;
|
||||
struct xfs_btree_block *block;
|
||||
struct xfs_btree_block *cblock;
|
||||
union xfs_btree_key *kp;
|
||||
union xfs_btree_key *ckp;
|
||||
union xfs_btree_ptr *pp;
|
||||
union xfs_btree_ptr *cpp;
|
||||
struct xfs_buf *cbp;
|
||||
int level;
|
||||
int numrecs;
|
||||
@@ -3752,7 +3802,6 @@ xfs_btree_kill_iroot(
|
||||
#ifdef DEBUG
|
||||
union xfs_btree_ptr ptr;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
ASSERT(cur->bc_ops->type == XFS_BTREE_TYPE_INODE);
|
||||
ASSERT(cur->bc_nlevels > 1);
|
||||
@@ -3792,35 +3841,16 @@ xfs_btree_kill_iroot(
|
||||
ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
|
||||
#endif
|
||||
|
||||
block = cur->bc_ops->broot_realloc(cur, numrecs);
|
||||
|
||||
block->bb_numrecs = be16_to_cpu(numrecs);
|
||||
ASSERT(block->bb_numrecs == cblock->bb_numrecs);
|
||||
|
||||
kp = xfs_btree_key_addr(cur, 1, block);
|
||||
ckp = xfs_btree_key_addr(cur, 1, cblock);
|
||||
xfs_btree_copy_keys(cur, kp, ckp, numrecs);
|
||||
|
||||
pp = xfs_btree_ptr_addr(cur, 1, block);
|
||||
cpp = xfs_btree_ptr_addr(cur, 1, cblock);
|
||||
|
||||
for (i = 0; i < numrecs; i++) {
|
||||
error = xfs_btree_debug_check_ptr(cur, cpp, i, level - 1);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
xfs_btree_copy_ptrs(cur, pp, cpp, numrecs);
|
||||
error = xfs_btree_demote_node_child(cur, cblock, level, numrecs);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_btree_free_block(cur, cbp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
cur->bc_levels[level - 1].bp = NULL;
|
||||
be16_add_cpu(&block->bb_level, -1);
|
||||
xfs_trans_log_inode(cur->bc_tp, ip,
|
||||
XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork));
|
||||
cur->bc_nlevels--;
|
||||
out0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user