Commit cd1549d6 authored by Allison Henderson's avatar Allison Henderson Committed by Dave Chinner

xfs: Add helper function xfs_attr_leaf_addname

This patch adds a helper function xfs_attr_leaf_addname.  While this
does help to break down xfs_attr_set_iter, it does also hoist out some
of the state management.  This patch has been moved to the end of the
clean up series for further discussion.
Suggested-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarAllison Henderson <allison.henderson@oracle.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChandan Babu R <chandanrlinux@gmail.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent d68c51e9
...@@ -286,44 +286,16 @@ xfs_attr_sf_addname( ...@@ -286,44 +286,16 @@ xfs_attr_sf_addname(
return -EAGAIN; return -EAGAIN;
} }
/* STATIC int
* Set the attribute specified in @args. xfs_attr_leaf_addname(
* This routine is meant to function as a delayed operation, and may return
* -EAGAIN when the transaction needs to be rolled. Calling functions will need
* to handle this, and recall the function until a successful error code is
* returned.
*/
int
xfs_attr_set_iter(
struct xfs_attr_item *attr) struct xfs_attr_item *attr)
{ {
struct xfs_da_args *args = attr->xattri_da_args; struct xfs_da_args *args = attr->xattri_da_args;
struct xfs_inode *dp = args->dp; struct xfs_inode *dp = args->dp;
struct xfs_buf *bp = NULL; int error;
int forkoff, error = 0;
struct xfs_mount *mp = args->dp->i_mount;
/* State machine switch */
switch (attr->xattri_dela_state) {
case XFS_DAS_UNINIT:
/*
* If the fork is shortform, attempt to add the attr. If there
* is no space, this converts to leaf format and returns
* -EAGAIN with the leaf buffer held across the roll. The caller
* will deal with a transaction roll error, but otherwise
* release the hold once we return with a clean transaction.
*/
if (xfs_attr_is_shortform(dp))
return xfs_attr_sf_addname(attr);
if (attr->xattri_leaf_bp != NULL) {
xfs_trans_bhold_release(args->trans,
attr->xattri_leaf_bp);
attr->xattri_leaf_bp = NULL;
}
if (xfs_attr_is_leaf(dp)) { if (xfs_attr_is_leaf(dp)) {
error = xfs_attr_leaf_try_add(args, error = xfs_attr_leaf_try_add(args, attr->xattri_leaf_bp);
attr->xattri_leaf_bp);
if (error == -ENOSPC) { if (error == -ENOSPC) {
error = xfs_attr3_leaf_to_node(args); error = xfs_attr3_leaf_to_node(args);
if (error) if (error)
...@@ -331,24 +303,23 @@ xfs_attr_set_iter( ...@@ -331,24 +303,23 @@ xfs_attr_set_iter(
/* /*
* Finish any deferred work items and roll the * Finish any deferred work items and roll the
* transaction once more. The goal here is to * transaction once more. The goal here is to call
* call node_addname with the inode and * node_addname with the inode and transaction in the
* transaction in the same state (inode locked * same state (inode locked and joined, transaction
* and joined, transaction clean) no matter how * clean) no matter how we got to this step.
* we got to this step.
* *
* At this point, we are still in * At this point, we are still in XFS_DAS_UNINIT, but
* XFS_DAS_UNINIT, but when we come back, we'll * when we come back, we'll be a node, so we'll fall
* be a node, so we'll fall down into the node * down into the node handling code below
* handling code below
*/ */
trace_xfs_attr_set_iter_return( trace_xfs_attr_set_iter_return(
attr->xattri_dela_state, args->dp); attr->xattri_dela_state, args->dp);
return -EAGAIN; return -EAGAIN;
} else if (error) {
return error;
} }
if (error)
return error;
attr->xattri_dela_state = XFS_DAS_FOUND_LBLK; attr->xattri_dela_state = XFS_DAS_FOUND_LBLK;
} else { } else {
error = xfs_attr_node_addname_find_attr(attr); error = xfs_attr_node_addname_find_attr(attr);
...@@ -360,8 +331,8 @@ xfs_attr_set_iter( ...@@ -360,8 +331,8 @@ xfs_attr_set_iter(
return error; return error;
/* /*
* If addname was successful, and we dont need to alloc * If addname was successful, and we dont need to alloc or
* or remove anymore blks, we're done. * remove anymore blks, we're done.
*/ */
if (!args->rmtblkno && if (!args->rmtblkno &&
!(args->op_flags & XFS_DA_OP_RENAME)) !(args->op_flags & XFS_DA_OP_RENAME))
...@@ -369,9 +340,48 @@ xfs_attr_set_iter( ...@@ -369,9 +340,48 @@ xfs_attr_set_iter(
attr->xattri_dela_state = XFS_DAS_FOUND_NBLK; attr->xattri_dela_state = XFS_DAS_FOUND_NBLK;
} }
trace_xfs_attr_set_iter_return(attr->xattri_dela_state,
args->dp); trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
return -EAGAIN; return -EAGAIN;
}
/*
* Set the attribute specified in @args.
* This routine is meant to function as a delayed operation, and may return
* -EAGAIN when the transaction needs to be rolled. Calling functions will need
* to handle this, and recall the function until a successful error code is
* returned.
*/
int
xfs_attr_set_iter(
struct xfs_attr_item *attr)
{
struct xfs_da_args *args = attr->xattri_da_args;
struct xfs_inode *dp = args->dp;
struct xfs_buf *bp = NULL;
int forkoff, error = 0;
struct xfs_mount *mp = args->dp->i_mount;
/* State machine switch */
switch (attr->xattri_dela_state) {
case XFS_DAS_UNINIT:
/*
* If the fork is shortform, attempt to add the attr. If there
* is no space, this converts to leaf format and returns
* -EAGAIN with the leaf buffer held across the roll. The caller
* will deal with a transaction roll error, but otherwise
* release the hold once we return with a clean transaction.
*/
if (xfs_attr_is_shortform(dp))
return xfs_attr_sf_addname(attr);
if (attr->xattri_leaf_bp != NULL) {
xfs_trans_bhold_release(args->trans,
attr->xattri_leaf_bp);
attr->xattri_leaf_bp = NULL;
}
return xfs_attr_leaf_addname(attr);
case XFS_DAS_FOUND_LBLK: case XFS_DAS_FOUND_LBLK:
/* /*
* If there was an out-of-line value, allocate the blocks we * If there was an out-of-line value, allocate the blocks we
......
...@@ -4150,6 +4150,7 @@ DEFINE_EVENT(xfs_das_state_class, name, \ ...@@ -4150,6 +4150,7 @@ DEFINE_EVENT(xfs_das_state_class, name, \
TP_ARGS(das, ip)) TP_ARGS(das, ip))
DEFINE_DAS_STATE_EVENT(xfs_attr_sf_addname_return); DEFINE_DAS_STATE_EVENT(xfs_attr_sf_addname_return);
DEFINE_DAS_STATE_EVENT(xfs_attr_set_iter_return); DEFINE_DAS_STATE_EVENT(xfs_attr_set_iter_return);
DEFINE_DAS_STATE_EVENT(xfs_attr_leaf_addname_return);
DEFINE_DAS_STATE_EVENT(xfs_attr_node_addname_return); DEFINE_DAS_STATE_EVENT(xfs_attr_node_addname_return);
DEFINE_DAS_STATE_EVENT(xfs_attr_remove_iter_return); DEFINE_DAS_STATE_EVENT(xfs_attr_remove_iter_return);
DEFINE_DAS_STATE_EVENT(xfs_attr_rmtval_remove_return); DEFINE_DAS_STATE_EVENT(xfs_attr_rmtval_remove_return);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment