]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: switch attr remove to xfs_attri_set_iter
authorDave Chinner <dchinner@redhat.com>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
Source kernel commit: 4b9879b19cafa63ae02fef30f678b2179a648d45

Now that xfs_attri_set_iter() has initial states for removing
attributes, switch the pure attribute removal code over to using it.
This requires attrs being removed to always be marked as INCOMPLETE
before we start the removal due to the fact we look up the attr to
remove again in xfs_attr_node_remove_attr().

Note: this drops the fillstate/refillstate optimisations from
the remove path that avoid having to look up the path again after
setting the incomplete flag and removing remote attrs. Restoring
that optimisation to this path is future Dave's problem.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/defer_item.c
libxfs/xfs_attr.c
libxfs/xfs_attr.h

index 8030b8344c22d6f67ee2c623a60ce8aac74d00f8..3c864cf41c6fb591eac549fd6a4ef132b241fd97 100644 (file)
@@ -496,11 +496,9 @@ xfs_attr_finish_item(
        struct xfs_attr_item    *attr;
        int                     error;
        struct xfs_da_args      *args;
-       unsigned int            op;
 
        attr = container_of(item, struct xfs_attr_item, xattri_list);
        args = attr->xattri_da_args;
-       op = attr->xattri_op_flags & XFS_ATTR_OP_FLAGS_TYPE_MASK;
 
        /*
         * Always reset trans after EAGAIN cycle
@@ -513,18 +511,9 @@ xfs_attr_finish_item(
                goto out;
        }
 
-       switch (op) {
-       case XFS_ATTR_OP_FLAGS_SET:
-               error = xfs_attr_set_iter(attr);
-               break;
-       case XFS_ATTR_OP_FLAGS_REMOVE:
-               ASSERT(XFS_IFORK_Q(args->dp));
-               error = xfs_attr_remove_iter(attr);
-               break;
-       default:
-               error = -EFSCORRUPTED;
-               break;
-       }
+       error = xfs_attr_set_iter(attr);
+       if (!error && attr->xattri_dela_state != XFS_DAS_DONE)
+               error = -EAGAIN;
 out:
        if (error != -EAGAIN)
                kmem_free(attr);
index 6287e5aebb52e132b4f087091b537bdf6e889262..87d737237114c7395e36c8aea0489c49c4be670a 100644 (file)
@@ -496,13 +496,11 @@ int xfs_attr_node_removename_setup(
        ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
                XFS_ATTR_LEAF_MAGIC);
 
-       if (args->rmtblkno > 0) {
-               error = xfs_attr_leaf_mark_incomplete(args, *state);
-               if (error)
-                       goto out;
-
+       error = xfs_attr_leaf_mark_incomplete(args, *state);
+       if (error)
+               goto out;
+       if (args->rmtblkno > 0)
                error = xfs_attr_rmtval_invalidate(args);
-       }
 out:
        if (error)
                xfs_da_state_free(*state);
@@ -818,7 +816,7 @@ xfs_attr_defer_remove(
        if (error)
                return error;
 
-       new->xattri_dela_state = XFS_DAS_UNINIT;
+       new->xattri_dela_state = xfs_attr_init_remove_state(args);
        xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
        trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
 
@@ -1386,16 +1384,15 @@ xfs_attr_node_remove_attr(
 {
        struct xfs_da_args              *args = attr->xattri_da_args;
        struct xfs_da_state             *state = NULL;
-       struct xfs_mount                *mp = args->dp->i_mount;
        int                             retval = 0;
        int                             error = 0;
 
        /*
-        * Re-find the "old" attribute entry after any split ops. The INCOMPLETE
-        * flag means that we will find the "old" attr, not the "new" one.
+        * The attr we are removing has already been marked incomplete, so
+        * we need to set the filter appropriately to re-find the "old"
+        * attribute entry after any split ops.
         */
-       if (!xfs_has_larp(mp))
-               args->attr_filter |= XFS_ATTR_INCOMPLETE;
+       args->attr_filter |= XFS_ATTR_INCOMPLETE;
        state = xfs_da_state_alloc(args);
        state->inleaf = 0;
        error = xfs_da3_node_lookup_int(state, &retval);
index 988c2451683ad9c4db5c3b6626fc4b6dd4a7a9c9..41d70ad62cbf38f65443dd851676627274f2fcec 100644 (file)
@@ -602,6 +602,16 @@ xfs_attr_init_add_state(struct xfs_da_args *args)
        return XFS_DAS_NODE_ADD;
 }
 
+static inline enum xfs_delattr_state
+xfs_attr_init_remove_state(struct xfs_da_args *args)
+{
+       if (xfs_attr_is_shortform(args->dp))
+               return XFS_DAS_SF_REMOVE;
+       if (xfs_attr_is_leaf(args->dp))
+               return XFS_DAS_LEAF_REMOVE;
+       return XFS_DAS_NODE_REMOVE;
+}
+
 static inline enum xfs_delattr_state
 xfs_attr_init_replace_state(struct xfs_da_args *args)
 {