]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: fix xfs_init_attr_trans not handling explicit operation codes
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:22:57 +0000 (16:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:05 +0000 (17:01 -0700)
Source kernel commit: 06c37c719d22339ad09b93735923e9b1a9794871

When we were converting the attr code to use an explicit operation code
instead of keying off of attr->value being null, we forgot to change the
code that initializes the transaction reservation.  Split the function
into two helpers that handle the !remove and remove cases, then fix both
callsites to handle this correctly.

Fixes: c27411d4c640 ("xfs: make attr removal an explicit operation")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_attr.c
libxfs/xfs_attr.h

index 9d32aa406571b857773de32b8c7291ccc758e21c..9e1cce5776b3dfbe3e317d396bf34efe78196000 100644 (file)
@@ -328,26 +328,20 @@ xfs_attr_calc_size(
        return nblks;
 }
 
-/* Initialize transaction reservation for attr operations */
-void
-xfs_init_attr_trans(
-       struct xfs_da_args      *args,
-       struct xfs_trans_res    *tres,
-       unsigned int            *total)
+/* Initialize transaction reservation for an xattr set/replace/upsert */
+inline struct xfs_trans_res
+xfs_attr_set_resv(
+       const struct xfs_da_args        *args)
 {
-       struct xfs_mount        *mp = args->dp->i_mount;
-
-       if (args->value) {
-               tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
-                                M_RES(mp)->tr_attrsetrt.tr_logres *
-                                args->total;
-               tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
-               tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
-               *total = args->total;
-       } else {
-               *tres = M_RES(mp)->tr_attrrm;
-               *total = XFS_ATTRRM_SPACE_RES(mp);
-       }
+       struct xfs_mount                *mp = args->dp->i_mount;
+       struct xfs_trans_res            ret = {
+               .tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
+                           M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
+               .tr_logcount            = XFS_ATTRSET_LOG_COUNT,
+               .tr_logflags            = XFS_TRANS_PERM_LOG_RES,
+       };
+
+       return ret;
 }
 
 /*
@@ -1005,7 +999,7 @@ xfs_attr_set(
        struct xfs_trans_res    tres;
        int                     error, local;
        int                     rmt_blks = 0;
-       unsigned int            total;
+       unsigned int            total = 0;
 
        ASSERT(!args->trans);
 
@@ -1032,10 +1026,15 @@ xfs_attr_set(
 
                if (!local)
                        rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
+
+               tres = xfs_attr_set_resv(args);
+               total = args->total;
                break;
        case XFS_ATTRUPDATE_REMOVE:
                XFS_STATS_INC(mp, xs_attr_remove);
                rmt_blks = xfs_attr3_max_rmt_blocks(mp);
+               tres = M_RES(mp)->tr_attrrm;
+               total = XFS_ATTRRM_SPACE_RES(mp);
                break;
        }
 
@@ -1043,7 +1042,6 @@ xfs_attr_set(
         * Root fork attributes can use reserved data blocks for this
         * operation if necessary
         */
-       xfs_init_attr_trans(args, &tres, &total);
        error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
        if (error)
                return error;
index 088cb7b301680ca024d58cf2ca8d7bbdc5a4ef8d..0e51d0723f9aa36c1519f6ad2c1881489a26dd8a 100644 (file)
@@ -565,8 +565,7 @@ bool xfs_attr_check_namespace(unsigned int attr_flags);
 bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
                size_t length);
 int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
-void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
-                        unsigned int *total);
+struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
 
 /*
  * Check to see if the attr should be upgraded from non-existent or shortform to