]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: remove xfs_attr_leaf_hasname
authorChristoph Hellwig <hch@lst.de>
Sun, 22 Feb 2026 22:41:07 +0000 (14:41 -0800)
committerAndrey Albershteyn <aalbersh@kernel.org>
Wed, 8 Apr 2026 19:39:56 +0000 (21:39 +0200)
Source kernel commit: 3a65ea768b8094e4699e72f9ab420eb9e0f3f568

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.

Fixes: 07120f1abdff ("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>
libxfs/xfs_attr.c

index 72b701f1b6dcae52f6ba38b4d9f01ddaf016e88b..baf617cfeabe00a9b7ac6ba9c75b6150450668da 100644 (file)
@@ -49,7 +49,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.
@@ -978,11 +977,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;
        }
 
@@ -1221,27 +1221,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
  *
@@ -1252,25 +1231,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);
 
@@ -1294,23 +1270,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);
-               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_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;
 }