xfs: introduce attr remove initial states into xfs_attr_set_iter
We need to merge the add and remove code paths to enable safe recovery of replace operations. Hoist the initial remove states from xfs_attr_remove_iter into xfs_attr_set_iter. We will make use of them in the next patches. 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>
This commit is contained in:
parent
4e3d96a57a
commit
e5d5596a2a
@ -450,6 +450,68 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
|
||||
* for later deletion of the entry.
|
||||
*/
|
||||
static int
|
||||
xfs_attr_leaf_mark_incomplete(
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_da_state *state)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Fill in disk block numbers in the state structure
|
||||
* so that we can get the buffers back after we commit
|
||||
* several transactions in the following calls.
|
||||
*/
|
||||
error = xfs_attr_fillstate(state);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Mark the attribute as INCOMPLETE
|
||||
*/
|
||||
return xfs_attr3_leaf_setflag(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
|
||||
* incomplete.
|
||||
*/
|
||||
static
|
||||
int xfs_attr_node_removename_setup(
|
||||
struct xfs_attr_item *attr)
|
||||
{
|
||||
struct xfs_da_args *args = attr->xattri_da_args;
|
||||
struct xfs_da_state **state = &attr->xattri_da_state;
|
||||
int error;
|
||||
|
||||
error = xfs_attr_node_hasname(args, state);
|
||||
if (error != -EEXIST)
|
||||
goto out;
|
||||
error = 0;
|
||||
|
||||
ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
|
||||
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_rmtval_invalidate(args);
|
||||
}
|
||||
out:
|
||||
if (error)
|
||||
xfs_da_state_free(*state);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the original attr we have just replaced. This is dependent on the
|
||||
* original lookup and insert placing the old attr in args->blkno/args->index
|
||||
@ -549,6 +611,21 @@ next_state:
|
||||
case XFS_DAS_NODE_ADD:
|
||||
return xfs_attr_node_addname(attr);
|
||||
|
||||
case XFS_DAS_SF_REMOVE:
|
||||
attr->xattri_dela_state = XFS_DAS_DONE;
|
||||
return xfs_attr_sf_removename(args);
|
||||
case XFS_DAS_LEAF_REMOVE:
|
||||
attr->xattri_dela_state = XFS_DAS_DONE;
|
||||
return xfs_attr_leaf_removename(args);
|
||||
case XFS_DAS_NODE_REMOVE:
|
||||
error = xfs_attr_node_removename_setup(attr);
|
||||
if (error)
|
||||
return error;
|
||||
attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
|
||||
if (args->rmtblkno == 0)
|
||||
attr->xattri_dela_state++;
|
||||
break;
|
||||
|
||||
case XFS_DAS_LEAF_SET_RMT:
|
||||
case XFS_DAS_NODE_SET_RMT:
|
||||
error = xfs_attr_rmtval_find_space(attr);
|
||||
@ -1348,68 +1425,6 @@ out:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
|
||||
* for later deletion of the entry.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_attr_leaf_mark_incomplete(
|
||||
struct xfs_da_args *args,
|
||||
struct xfs_da_state *state)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Fill in disk block numbers in the state structure
|
||||
* so that we can get the buffers back after we commit
|
||||
* several transactions in the following calls.
|
||||
*/
|
||||
error = xfs_attr_fillstate(state);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Mark the attribute as INCOMPLETE
|
||||
*/
|
||||
return xfs_attr3_leaf_setflag(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
|
||||
* incomplete.
|
||||
*/
|
||||
STATIC
|
||||
int xfs_attr_node_removename_setup(
|
||||
struct xfs_attr_item *attr)
|
||||
{
|
||||
struct xfs_da_args *args = attr->xattri_da_args;
|
||||
struct xfs_da_state **state = &attr->xattri_da_state;
|
||||
int error;
|
||||
|
||||
error = xfs_attr_node_hasname(args, state);
|
||||
if (error != -EEXIST)
|
||||
goto out;
|
||||
error = 0;
|
||||
|
||||
ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
|
||||
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_rmtval_invalidate(args);
|
||||
}
|
||||
out:
|
||||
if (error)
|
||||
xfs_da_state_free(*state);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_attr_node_removename(
|
||||
struct xfs_da_args *args,
|
||||
|
@ -451,6 +451,10 @@ enum xfs_delattr_state {
|
||||
XFS_DAS_RM_NAME, /* Remove attr name */
|
||||
XFS_DAS_RM_SHRINK, /* We are shrinking the tree */
|
||||
|
||||
XFS_DAS_SF_REMOVE, /* Initial shortform set iter state */
|
||||
XFS_DAS_LEAF_REMOVE, /* Initial leaf form set iter state */
|
||||
XFS_DAS_NODE_REMOVE, /* Initial node form set iter state */
|
||||
|
||||
/* Leaf state set/replace sequence */
|
||||
XFS_DAS_LEAF_SET_RMT, /* set a remote xattr from a leaf */
|
||||
XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */
|
||||
|
@ -4136,6 +4136,9 @@ TRACE_DEFINE_ENUM(XFS_DAS_NODE_ADD);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_RMTBLK);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_RM_NAME);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_RM_SHRINK);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_SF_REMOVE);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_REMOVE);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_NODE_REMOVE);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_SET_RMT);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_ALLOC_RMT);
|
||||
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_REPLACE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user