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: 07120f1abd ("xfs: Add xfs_has_attr and subroutines")
Reported-by: Mark Tinguely <mark.tinguely@oracle.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Christoph Hellwig 2026-01-09 16:17:40 +01:00 committed by Carlos Maiolino
parent f39854a3fb
commit 3a65ea768b

View File

@ -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)
xfs_trans_brelse(args->trans, 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,23 +1271,20 @@ 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;
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);
error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
if (error)
return error;
} else if (error != -EEXIST)
return error;
error = xfs_attr3_leaf_getvalue(bp, args);
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;
}