]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: clean up xfs_attr_node_hasname
authorDarrick J. Wong <djwong@kernel.org>
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: 4d0cdd2bb8f0bf1a30d361f14bafc428794551e0

The calling conventions of this function are a mess -- callers /can/
provide a pointer to a pointer to a state structure, but it's not
required, and as evidenced by the last two patches, the callers that do
weren't be careful enough about how to deal with an existing da state.

Push the allocation and freeing responsibilty to the callers, which
means that callers from the xattr node state machine steps now have the
visibility to allocate or free the da state structure as they please.
As a bonus, the node remove/add paths for larp-mode replaces can reset
the da state structure instead of freeing and immediately reallocating
it.

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

index 4995ff87a241e4a2d8d94634484970ce165b4a6e..e214e286ff682d065b391cabbd929580b17f0530 100644 (file)
@@ -59,8 +59,8 @@ STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
 static int xfs_attr_node_try_addname(struct xfs_attr_item *attr);
 STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_item *attr);
 STATIC int xfs_attr_node_remove_attr(struct xfs_attr_item *attr);
-STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
-                                struct xfs_da_state **state);
+STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
+               struct xfs_da_state *state);
 
 int
 xfs_inode_hasattr(
@@ -592,6 +592,19 @@ xfs_attr_leaf_mark_incomplete(
        return xfs_attr3_leaf_setflag(args);
 }
 
+/* Ensure the da state of an xattr deferred work item is ready to go. */
+static inline void
+xfs_attr_item_init_da_state(
+       struct xfs_attr_item    *attr)
+{
+       struct xfs_da_args      *args = attr->xattri_da_args;
+
+       if (!attr->xattri_da_state)
+               attr->xattri_da_state = xfs_da_state_alloc(args);
+       else
+               xfs_da_state_reset(attr->xattri_da_state, args);
+}
+
 /*
  * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
  * the blocks are valid.  Attr keys with remote blocks will be marked
@@ -605,7 +618,8 @@ int xfs_attr_node_removename_setup(
        struct xfs_da_state             *state;
        int                             error;
 
-       error = xfs_attr_node_hasname(args, &attr->xattri_da_state);
+       xfs_attr_item_init_da_state(attr);
+       error = xfs_attr_node_lookup(args, attr->xattri_da_state);
        if (error != -EEXIST)
                goto out;
        error = 0;
@@ -853,6 +867,7 @@ xfs_attr_lookup(
 {
        struct xfs_inode        *dp = args->dp;
        struct xfs_buf          *bp = NULL;
+       struct xfs_da_state     *state;
        int                     error;
 
        if (!xfs_inode_hasattr(dp))
@@ -870,7 +885,10 @@ xfs_attr_lookup(
                return error;
        }
 
-       return xfs_attr_node_hasname(args, NULL);
+       state = xfs_da_state_alloc(args);
+       error = xfs_attr_node_lookup(args, state);
+       xfs_da_state_free(state);
+       return error;
 }
 
 static int
@@ -1385,34 +1403,20 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
        return error;
 }
 
-/*
- * Return EEXIST if attr is found, or ENOATTR if not
- * statep: If not null is set to point at the found state.  Caller will
- *         be responsible for freeing the state in this case.
- */
+/* Return EEXIST if attr is found, or ENOATTR if not. */
 STATIC int
-xfs_attr_node_hasname(
+xfs_attr_node_lookup(
        struct xfs_da_args      *args,
-       struct xfs_da_state     **statep)
+       struct xfs_da_state     *state)
 {
-       struct xfs_da_state     *state;
        int                     retval, error;
 
-       state = xfs_da_state_alloc(args);
-       if (statep != NULL) {
-               ASSERT(*statep == NULL);
-               *statep = state;
-       }
-
        /*
         * Search to see if name exists, and get back a pointer to it.
         */
        error = xfs_da3_node_lookup_int(state, &retval);
        if (error)
-               retval = error;
-
-       if (!statep)
-               xfs_da_state_free(state);
+               return error;
 
        return retval;
 }
@@ -1428,15 +1432,12 @@ xfs_attr_node_addname_find_attr(
        struct xfs_da_args      *args = attr->xattri_da_args;
        int                     error;
 
-       if (attr->xattri_da_state)
-               xfs_da_state_free(attr->xattri_da_state);
-       attr->xattri_da_state = NULL;
-
        /*
         * Search to see if name already exists, and get back a pointer
         * to where it should go.
         */
-       error = xfs_attr_node_hasname(args, &attr->xattri_da_state);
+       xfs_attr_item_init_da_state(attr);
+       error = xfs_attr_node_lookup(args, attr->xattri_da_state);
        switch (error) {
        case -ENOATTR:
                if (args->op_flags & XFS_DA_OP_REPLACE)
@@ -1597,7 +1598,7 @@ STATIC int
 xfs_attr_node_get(
        struct xfs_da_args      *args)
 {
-       struct xfs_da_state     *state = NULL;
+       struct xfs_da_state     *state;
        struct xfs_da_state_blk *blk;
        int                     i;
        int                     error;
@@ -1607,7 +1608,8 @@ xfs_attr_node_get(
        /*
         * Search to see if name exists, and get back a pointer to it.
         */
-       error = xfs_attr_node_hasname(args, &state);
+       state = xfs_da_state_alloc(args);
+       error = xfs_attr_node_lookup(args, state);
        if (error != -EEXIST)
                goto out_release;
 
@@ -1626,8 +1628,7 @@ out_release:
                state->path.blk[i].bp = NULL;
        }
 
-       if (state)
-               xfs_da_state_free(state);
+       xfs_da_state_free(state);
        return error;
 }
 
index 7ecbc681272531dc8c467ea2fa3d0f6f25fdff2c..9dc22f2ff132ab89dfeba177a338a4717f5b2860 100644 (file)
@@ -113,6 +113,17 @@ xfs_da_state_free(xfs_da_state_t *state)
        kmem_cache_free(xfs_da_state_cache, state);
 }
 
+void
+xfs_da_state_reset(
+       struct xfs_da_state     *state,
+       struct xfs_da_args      *args)
+{
+       xfs_da_state_kill_altpath(state);
+       memset(state, 0, sizeof(struct xfs_da_state));
+       state->args = args;
+       state->mp = state->args->dp->i_mount;
+}
+
 static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
 {
        if (whichfork == XFS_DATA_FORK)
index ed2303e4d46a20ce9c2b588c48eb87116ae2e7bc..d33b7686a0b3aa0c1116ba24b9bf8d3d11fa873a 100644 (file)
@@ -225,6 +225,7 @@ enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
 
 struct xfs_da_state *xfs_da_state_alloc(struct xfs_da_args *args);
 void xfs_da_state_free(xfs_da_state_t *state);
+void xfs_da_state_reset(struct xfs_da_state *state, struct xfs_da_args *args);
 
 void   xfs_da3_node_hdr_from_disk(struct xfs_mount *mp,
                struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from);