Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38bb7423 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Lachlan McIlroy
Browse files

[XFS] implement generic xfs_btree_updkey



From: Dave Chinner <dgc@sgi.com>

Note that there are many > 80 char lines introduced due to the
xfs_btree_key casts. But the places where this happens is throw-away code
once the whole btree code gets merged into a common implementation.

The same is true for the temporary xfs_alloc_log_keys define to the new
name. All old users will be gone after a few patches.

[hch: split out from bigger patch and minor adaptions]

SGI-PV: 985583

SGI-Modid: xfs-linux-melb:xfs-kern:32193a

Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarBill O'Donnell <billodo@sgi.com>
Signed-off-by: default avatarDavid Chinner <david@fromorbit.com>
parent fe033cc8
Loading
Loading
Loading
Loading
+5 −45
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *);
STATIC int xfs_alloc_rshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
		xfs_alloc_key_t *, xfs_btree_cur_t **, int *);
STATIC int xfs_alloc_updkey(xfs_btree_cur_t *, xfs_alloc_key_t *, int);

/*
 * Internal functions.
@@ -265,7 +264,7 @@ xfs_alloc_delrec(
	 * If we deleted the leftmost entry in the block, update the
	 * key values above us in the tree.
	 */
	if (ptr == 1 && (error = xfs_alloc_updkey(cur, lkp, level + 1)))
	if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)lkp, level + 1)))
		return error;
	/*
	 * If the number of records remaining in the block is at least
@@ -798,7 +797,7 @@ xfs_alloc_insrec(
	/*
	 * If we inserted at the start of a block, update the parents' keys.
	 */
	if (optr == 1 && (error = xfs_alloc_updkey(cur, &key, level + 1)))
	if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
		return error;
	/*
	 * Look to see if the longest extent in the allocation group
@@ -1068,7 +1067,7 @@ xfs_alloc_lshift(
	/*
	 * Update the parent key values of right.
	 */
	if ((error = xfs_alloc_updkey(cur, rkp, level + 1)))
	if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
		return error;
	/*
	 * Slide the cursor value left one.
@@ -1354,7 +1353,7 @@ xfs_alloc_rshift(
	i = xfs_btree_lastrec(tcur, level);
	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
	if ((error = xfs_btree_increment(tcur, level, &i)) ||
	    (error = xfs_alloc_updkey(tcur, rkp, level + 1)))
	    (error = xfs_btree_updkey(tcur, (union xfs_btree_key *)rkp, level + 1)))
		goto error0;
	xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
	*stat = 1;
@@ -1519,45 +1518,6 @@ xfs_alloc_split(
	return 0;
}

/*
 * Update keys at all levels from here to the root along the cursor's path.
 */
STATIC int				/* error */
xfs_alloc_updkey(
	xfs_btree_cur_t		*cur,	/* btree cursor */
	xfs_alloc_key_t		*keyp,	/* new key value to update to */
	int			level)	/* starting level for update */
{
	int			ptr;	/* index of key in block */

	/*
	 * Go up the tree from this level toward the root.
	 * At each level, update the key value to the value input.
	 * Stop when we reach a level where the cursor isn't pointing
	 * at the first entry in the block.
	 */
	for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
		xfs_alloc_block_t	*block;	/* btree block */
		xfs_buf_t		*bp;	/* buffer for block */
#ifdef DEBUG
		int			error;	/* error return value */
#endif
		xfs_alloc_key_t		*kp;	/* ptr to btree block keys */

		bp = cur->bc_bufs[level];
		block = XFS_BUF_TO_ALLOC_BLOCK(bp);
#ifdef DEBUG
		if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
			return error;
#endif
		ptr = cur->bc_ptrs[level];
		kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur);
		*kp = *keyp;
		xfs_alloc_log_keys(cur, bp, ptr, ptr);
	}
	return 0;
}

/*
 * Externally visible routines.
 */
@@ -1765,7 +1725,7 @@ xfs_alloc_update(

		key.ar_startblock = cpu_to_be32(bno);
		key.ar_blockcount = cpu_to_be32(len);
		if ((error = xfs_alloc_updkey(cur, &key, 1)))
		if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1)))
			return error;
	}
	return 0;
+5 −44
Original line number Diff line number Diff line
@@ -56,7 +56,6 @@ STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
		__uint64_t *, xfs_btree_cur_t **, int *);
STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);

#undef EXIT

@@ -211,7 +210,7 @@ xfs_bmbt_delrec(
		*stat = 1;
		return 0;
	}
	if (ptr == 1 && (error = xfs_bmbt_updkey(cur, kp, level + 1))) {
	if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) {
		XFS_BMBT_TRACE_CURSOR(cur, ERROR);
		goto error0;
	}
@@ -635,7 +634,7 @@ xfs_bmbt_insrec(
				kp + ptr);
	}
#endif
	if (optr == 1 && (error = xfs_bmbt_updkey(cur, &key, level + 1))) {
	if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1))) {
		XFS_BMBT_TRACE_CURSOR(cur, ERROR);
		return error;
	}
@@ -935,7 +934,7 @@ xfs_bmbt_lshift(
		key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
		rkp = &key;
	}
	if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
	if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1))) {
		XFS_BMBT_TRACE_CURSOR(cur, ERROR);
		return error;
	}
@@ -1067,7 +1066,7 @@ xfs_bmbt_rshift(
		goto error1;
	}
	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
	if ((error = xfs_bmbt_updkey(tcur, rkp, level + 1))) {
	if ((error = xfs_btree_updkey(tcur, (union xfs_btree_key *)rkp, level + 1))) {
		XFS_BMBT_TRACE_CURSOR(tcur, ERROR);
		goto error1;
	}
@@ -1276,44 +1275,6 @@ xfs_bmbt_split(
	return 0;
}


/*
 * Update keys for the record.
 */
STATIC int
xfs_bmbt_updkey(
	xfs_btree_cur_t		*cur,
	xfs_bmbt_key_t		*keyp,	/* on-disk format */
	int			level)
{
	xfs_bmbt_block_t	*block;
	xfs_buf_t		*bp;
#ifdef DEBUG
	int			error;
#endif
	xfs_bmbt_key_t		*kp;
	int			ptr;

	ASSERT(level >= 1);
	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
	XFS_BMBT_TRACE_ARGIK(cur, level, keyp);
	for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
		block = xfs_bmbt_get_block(cur, level, &bp);
#ifdef DEBUG
		if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
			XFS_BMBT_TRACE_CURSOR(cur, ERROR);
			return error;
		}
#endif
		ptr = cur->bc_ptrs[level];
		kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
		*kp = *keyp;
		xfs_bmbt_log_keys(cur, bp, ptr, ptr);
	}
	XFS_BMBT_TRACE_CURSOR(cur, EXIT);
	return 0;
}

/*
 * Convert on-disk form of btree root to in-memory form.
 */
@@ -2039,7 +2000,7 @@ xfs_bmbt_update(
		return 0;
	}
	key.br_startoff = cpu_to_be64(off);
	if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
	if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1))) {
		XFS_BMBT_TRACE_CURSOR(cur, ERROR);
		return error;
	}
+87 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_btree.h"
#include "xfs_btree_trace.h"
#include "xfs_ialloc.h"
@@ -1064,6 +1065,45 @@ xfs_btree_read_buf_block(
	return error;
}

/*
 * Copy keys from one btree block to another.
 */
STATIC void
xfs_btree_copy_keys(
	struct xfs_btree_cur	*cur,
	union xfs_btree_key	*dst_key,
	union xfs_btree_key	*src_key,
	int			numkeys)
{
	ASSERT(numkeys >= 0);
	memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len);
}

/*
 * Log key values from the btree block.
 */
STATIC void
xfs_btree_log_keys(
	struct xfs_btree_cur	*cur,
	struct xfs_buf		*bp,
	int			first,
	int			last)
{
	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
	XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);

	if (bp) {
		xfs_trans_log_buf(cur->bc_tp, bp,
				  xfs_btree_key_offset(cur, first),
				  xfs_btree_key_offset(cur, last + 1) - 1);
	} else {
		xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
				xfs_ilog_fbroot(cur->bc_private.b.whichfork));
	}

	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
}

/*
 * Increment cursor by one record at the level.
 * For nonzero levels the leaf-ward information is untouched.
@@ -1489,3 +1529,50 @@ error0:
	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
	return error;
}

/*
 * Update keys at all levels from here to the root along the cursor's path.
 */
int
xfs_btree_updkey(
	struct xfs_btree_cur	*cur,
	union xfs_btree_key	*keyp,
	int			level)
{
	struct xfs_btree_block	*block;
	struct xfs_buf		*bp;
	union xfs_btree_key	*kp;
	int			ptr;

	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
	XFS_BTREE_TRACE_ARGIK(cur, level, keyp);

	ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1);

	/*
	 * Go up the tree from this level toward the root.
	 * At each level, update the key value to the value input.
	 * Stop when we reach a level where the cursor isn't pointing
	 * at the first entry in the block.
	 */
	for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
#ifdef DEBUG
		int		error;
#endif
		block = xfs_btree_get_block(cur, level, &bp);
#ifdef DEBUG
		error = xfs_btree_check_block(cur, block, level, bp);
		if (error) {
			XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
			return error;
		}
#endif
		ptr = cur->bc_ptrs[level];
		kp = xfs_btree_key_addr(cur, ptr, block);
		xfs_btree_copy_keys(cur, kp, keyp, 1);
		xfs_btree_log_keys(cur, bp, ptr, ptr);
	}

	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -518,6 +518,7 @@ xfs_btree_setbuf(
int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
int xfs_btree_updkey(struct xfs_btree_cur *, union xfs_btree_key *, int);

/*
 * Helpers.
+5 −45
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
STATIC int xfs_inobt_rshift(xfs_btree_cur_t *, int, int *);
STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
		xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
STATIC int xfs_inobt_updkey(xfs_btree_cur_t *, xfs_inobt_key_t *, int);

/*
 * Single level of the xfs_inobt_delete record deletion routine.
@@ -214,7 +213,7 @@ xfs_inobt_delrec(
	 * If we deleted the leftmost entry in the block, update the
	 * key values above us in the tree.
	 */
	if (ptr == 1 && (error = xfs_inobt_updkey(cur, kp, level + 1)))
	if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1)))
		return error;
	/*
	 * If the number of records remaining in the block is at least
@@ -723,7 +722,7 @@ xfs_inobt_insrec(
	/*
	 * If we inserted at the start of a block, update the parents' keys.
	 */
	if (optr == 1 && (error = xfs_inobt_updkey(cur, &key, level + 1)))
	if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
		return error;
	/*
	 * Return the new block number, if any.
@@ -960,7 +959,7 @@ xfs_inobt_lshift(
	/*
	 * Update the parent key values of right.
	 */
	if ((error = xfs_inobt_updkey(cur, rkp, level + 1)))
	if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
		return error;
	/*
	 * Slide the cursor value left one.
@@ -1238,7 +1237,7 @@ xfs_inobt_rshift(
		return error;
	xfs_btree_lastrec(tcur, level);
	if ((error = xfs_btree_increment(tcur, level, &i)) ||
	    (error = xfs_inobt_updkey(tcur, rkp, level + 1))) {
	    (error = xfs_btree_updkey(tcur, (union xfs_btree_key *)rkp, level + 1))) {
		xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
		return error;
	}
@@ -1406,45 +1405,6 @@ xfs_inobt_split(
	return 0;
}

/*
 * Update keys at all levels from here to the root along the cursor's path.
 */
STATIC int				/* error */
xfs_inobt_updkey(
	xfs_btree_cur_t		*cur,	/* btree cursor */
	xfs_inobt_key_t		*keyp,	/* new key value to update to */
	int			level)	/* starting level for update */
{
	int			ptr;	/* index of key in block */

	/*
	 * Go up the tree from this level toward the root.
	 * At each level, update the key value to the value input.
	 * Stop when we reach a level where the cursor isn't pointing
	 * at the first entry in the block.
	 */
	for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
		xfs_buf_t		*bp;	/* buffer for block */
		xfs_inobt_block_t	*block;	/* btree block */
#ifdef DEBUG
		int			error;	/* error return value */
#endif
		xfs_inobt_key_t		*kp;	/* ptr to btree block keys */

		bp = cur->bc_bufs[level];
		block = XFS_BUF_TO_INOBT_BLOCK(bp);
#ifdef DEBUG
		if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
			return error;
#endif
		ptr = cur->bc_ptrs[level];
		kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
		*kp = *keyp;
		xfs_inobt_log_keys(cur, bp, ptr, ptr);
	}
	return 0;
}

/*
 * Externally visible routines.
 */
@@ -1637,7 +1597,7 @@ xfs_inobt_update(
		xfs_inobt_key_t	key;	/* key containing [ino] */

		key.ir_startino = cpu_to_be32(ino);
		if ((error = xfs_inobt_updkey(cur, &key, 1)))
		if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1)))
			return error;
	}
	return 0;