Commit 3a65ea76 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Carlos Maiolino
Browse files

xfs: remove xfs_attr_leaf_hasname



The calling convention of xfs_attr_leaf_hasname() is problematic, because
it returns a NULL buffer when xfs_attr3_leaf_read fails, a valid buffer
when xfs_attr3_leaf_lookup_int returns -ENOATTR or -EEXIST, and a
non-NULL buffer pointer for an already released buffer when
xfs_attr3_leaf_lookup_int fails with other error values.

Fix this by simply open coding xfs_attr_leaf_hasname in the callers, so
that the buffer release code is done by each caller of
xfs_attr3_leaf_read.

Cc: stable@vger.kernel.org # v5.19+
Fixes: 07120f1a ("xfs: Add xfs_has_attr and subroutines")
Reported-by: default avatarMark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarCarlos Maiolino <cem@kernel.org>
parent f39854a3
Loading
Loading
Loading
Loading
+24 −51
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
 */
STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);

/*
 * Internal routines when attribute list is more than one block.
@@ -979,11 +978,12 @@ xfs_attr_lookup(
		return error;

	if (xfs_attr_is_leaf(dp)) {
		error = xfs_attr_leaf_hasname(args, &bp);

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

		return error;
	}

@@ -1222,27 +1222,6 @@ xfs_attr_shortform_addname(
 * External routines when attribute list is one block
 *========================================================================*/

/*
 * Return EEXIST if attr is found, or ENOATTR if not
 */
STATIC int
xfs_attr_leaf_hasname(
	struct xfs_da_args	*args,
	struct xfs_buf		**bp)
{
	int                     error = 0;

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

	error = xfs_attr3_leaf_lookup_int(*bp, args);
	if (error != -ENOATTR && error != -EEXIST)
		xfs_trans_brelse(args->trans, *bp);

	return error;
}

/*
 * Remove a name from the leaf attribute list structure
 *
@@ -1253,25 +1232,22 @@ STATIC int
xfs_attr_leaf_removename(
	struct xfs_da_args	*args)
{
	struct xfs_inode	*dp;
	struct xfs_buf		*bp;
	struct xfs_inode	*dp = args->dp;
	int			error, forkoff;
	struct xfs_buf		*bp;

	trace_xfs_attr_leaf_removename(args);

	/*
	 * Remove the attribute.
	 */
	dp = args->dp;

	error = xfs_attr_leaf_hasname(args, &bp);
	if (error == -ENOATTR) {
	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
	if (error)
		return error;
	error = xfs_attr3_leaf_lookup_int(bp, args);
	if (error != -EEXIST) {
		xfs_trans_brelse(args->trans, bp);
		if (args->op_flags & XFS_DA_OP_RECOVERY)
		if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
			return 0;
		return error;
	} else if (error != -EEXIST)
		return error;
	}

	xfs_attr3_leaf_remove(bp, args);

@@ -1295,22 +1271,19 @@ xfs_attr_leaf_removename(
 * Returns 0 on successful retrieval, otherwise an error.
 */
STATIC int
xfs_attr_leaf_get(xfs_da_args_t *args)
xfs_attr_leaf_get(
	struct xfs_da_args	*args)
{
	struct xfs_buf		*bp;
	int			error;

	trace_xfs_attr_leaf_get(args);

	error = xfs_attr_leaf_hasname(args, &bp);

	if (error == -ENOATTR)  {
		xfs_trans_brelse(args->trans, bp);
		return error;
	} else if (error != -EEXIST)
	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
	if (error)
		return error;


	error = xfs_attr3_leaf_lookup_int(bp, args);
	if (error == -EEXIST)
		error = xfs_attr3_leaf_getvalue(bp, args);
	xfs_trans_brelse(args->trans, bp);
	return error;