Commit 3f6e011e authored by Allison Collins's avatar Allison Collins Committed by Darrick J. Wong
Browse files

xfs: Add helper function xfs_attr_node_shrink



This patch adds a new helper function xfs_attr_node_shrink used to
shrink an attr name into an inode if it is small enough.  This helps to
modularize the greater calling function xfs_attr_node_removename.

Signed-off-by: default avatarAllison Collins <allison.henderson@oracle.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Acked-by: default avatarDave Chinner <dchinner@redhat.com>
parent d4034c46
Loading
Loading
Loading
Loading
+42 −26
Original line number Diff line number Diff line
@@ -1102,6 +1102,45 @@ out:
	return retval;
}

/*
 * Shrink an attribute from leaf to shortform
 */
STATIC int
xfs_attr_node_shrink(
	struct xfs_da_args	*args,
	struct xfs_da_state     *state)
{
	struct xfs_inode	*dp = args->dp;
	int			error, forkoff;
	struct xfs_buf		*bp;

	/*
	 * Have to get rid of the copy of this dabuf in the state.
	 */
	ASSERT(state->path.active == 1);
	ASSERT(state->path.blk[0].bp);
	state->path.blk[0].bp = NULL;

	error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
	if (error)
		return error;

	forkoff = xfs_attr_shortform_allfit(bp, dp);
	if (forkoff) {
		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
		/* bp is gone due to xfs_da_shrink_inode */
		if (error)
			return error;

		error = xfs_defer_finish(&args->trans);
		if (error)
			return error;
	} else
		xfs_trans_brelse(args->trans, bp);

	return 0;
}

/*
 * Remove a name from a B-tree attribute list.
 *
@@ -1115,8 +1154,7 @@ xfs_attr_node_removename(
{
	struct xfs_da_state	*state;
	struct xfs_da_state_blk	*blk;
	struct xfs_buf		*bp;
	int			retval, error, forkoff;
	int			retval, error;
	struct xfs_inode	*dp = args->dp;

	trace_xfs_attr_node_removename(args);
@@ -1201,30 +1239,8 @@ xfs_attr_node_removename(
	/*
	 * If the result is small enough, push it all into the inode.
	 */
	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
		/*
		 * Have to get rid of the copy of this dabuf in the state.
		 */
		ASSERT(state->path.active == 1);
		ASSERT(state->path.blk[0].bp);
		state->path.blk[0].bp = NULL;

		error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
		if (error)
			goto out;

		if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
			error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
			/* bp is gone due to xfs_da_shrink_inode */
			if (error)
				goto out;
			error = xfs_defer_finish(&args->trans);
			if (error)
				goto out;
		} else
			xfs_trans_brelse(args->trans, bp);
	}
	error = 0;
	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
		error = xfs_attr_node_shrink(args, state);

out:
	if (state)