mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
xfs: clean up xfs_attr_node_hasname
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>
This commit is contained in:
parent
2fe3ffcf55
commit
4d0cdd2bb8
3 changed files with 44 additions and 31 deletions
|
@ -61,8 +61,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(
|
||||
|
@ -594,6 +594,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
|
||||
|
@ -607,7 +620,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;
|
||||
|
@ -855,6 +869,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))
|
||||
|
@ -872,7 +887,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
|
||||
|
@ -1387,34 +1405,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;
|
||||
}
|
||||
|
@ -1430,15 +1434,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)
|
||||
|
@ -1599,7 +1600,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;
|
||||
|
@ -1609,7 +1610,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;
|
||||
|
||||
|
@ -1628,8 +1630,7 @@ xfs_attr_node_get(
|
|||
state->path.blk[i].bp = NULL;
|
||||
}
|
||||
|
||||
if (state)
|
||||
xfs_da_state_free(state);
|
||||
xfs_da_state_free(state);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue