Skip to content

Commit e5d5596

Browse files
Dave Chinnerdchinner
authored andcommitted
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 <[email protected]> Reviewed-by: Allison Henderson<[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Dave Chinner <[email protected]>
1 parent 4e3d96a commit e5d5596

File tree

3 files changed

+84
-62
lines changed

3 files changed

+84
-62
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,68 @@ xfs_attr_rmtval_alloc(
450450
return error;
451451
}
452452

453+
/*
454+
* Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
455+
* for later deletion of the entry.
456+
*/
457+
static int
458+
xfs_attr_leaf_mark_incomplete(
459+
struct xfs_da_args *args,
460+
struct xfs_da_state *state)
461+
{
462+
int error;
463+
464+
/*
465+
* Fill in disk block numbers in the state structure
466+
* so that we can get the buffers back after we commit
467+
* several transactions in the following calls.
468+
*/
469+
error = xfs_attr_fillstate(state);
470+
if (error)
471+
return error;
472+
473+
/*
474+
* Mark the attribute as INCOMPLETE
475+
*/
476+
return xfs_attr3_leaf_setflag(args);
477+
}
478+
479+
/*
480+
* Initial setup for xfs_attr_node_removename. Make sure the attr is there and
481+
* the blocks are valid. Attr keys with remote blocks will be marked
482+
* incomplete.
483+
*/
484+
static
485+
int xfs_attr_node_removename_setup(
486+
struct xfs_attr_item *attr)
487+
{
488+
struct xfs_da_args *args = attr->xattri_da_args;
489+
struct xfs_da_state **state = &attr->xattri_da_state;
490+
int error;
491+
492+
error = xfs_attr_node_hasname(args, state);
493+
if (error != -EEXIST)
494+
goto out;
495+
error = 0;
496+
497+
ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
498+
ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
499+
XFS_ATTR_LEAF_MAGIC);
500+
501+
if (args->rmtblkno > 0) {
502+
error = xfs_attr_leaf_mark_incomplete(args, *state);
503+
if (error)
504+
goto out;
505+
506+
error = xfs_attr_rmtval_invalidate(args);
507+
}
508+
out:
509+
if (error)
510+
xfs_da_state_free(*state);
511+
512+
return error;
513+
}
514+
453515
/*
454516
* Remove the original attr we have just replaced. This is dependent on the
455517
* original lookup and insert placing the old attr in args->blkno/args->index
@@ -549,6 +611,21 @@ xfs_attr_set_iter(
549611
case XFS_DAS_NODE_ADD:
550612
return xfs_attr_node_addname(attr);
551613

614+
case XFS_DAS_SF_REMOVE:
615+
attr->xattri_dela_state = XFS_DAS_DONE;
616+
return xfs_attr_sf_removename(args);
617+
case XFS_DAS_LEAF_REMOVE:
618+
attr->xattri_dela_state = XFS_DAS_DONE;
619+
return xfs_attr_leaf_removename(args);
620+
case XFS_DAS_NODE_REMOVE:
621+
error = xfs_attr_node_removename_setup(attr);
622+
if (error)
623+
return error;
624+
attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
625+
if (args->rmtblkno == 0)
626+
attr->xattri_dela_state++;
627+
break;
628+
552629
case XFS_DAS_LEAF_SET_RMT:
553630
case XFS_DAS_NODE_SET_RMT:
554631
error = xfs_attr_rmtval_find_space(attr);
@@ -1348,68 +1425,6 @@ xfs_attr_node_remove_attr(
13481425
}
13491426

13501427

1351-
/*
1352-
* Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
1353-
* for later deletion of the entry.
1354-
*/
1355-
STATIC int
1356-
xfs_attr_leaf_mark_incomplete(
1357-
struct xfs_da_args *args,
1358-
struct xfs_da_state *state)
1359-
{
1360-
int error;
1361-
1362-
/*
1363-
* Fill in disk block numbers in the state structure
1364-
* so that we can get the buffers back after we commit
1365-
* several transactions in the following calls.
1366-
*/
1367-
error = xfs_attr_fillstate(state);
1368-
if (error)
1369-
return error;
1370-
1371-
/*
1372-
* Mark the attribute as INCOMPLETE
1373-
*/
1374-
return xfs_attr3_leaf_setflag(args);
1375-
}
1376-
1377-
/*
1378-
* Initial setup for xfs_attr_node_removename. Make sure the attr is there and
1379-
* the blocks are valid. Attr keys with remote blocks will be marked
1380-
* incomplete.
1381-
*/
1382-
STATIC
1383-
int xfs_attr_node_removename_setup(
1384-
struct xfs_attr_item *attr)
1385-
{
1386-
struct xfs_da_args *args = attr->xattri_da_args;
1387-
struct xfs_da_state **state = &attr->xattri_da_state;
1388-
int error;
1389-
1390-
error = xfs_attr_node_hasname(args, state);
1391-
if (error != -EEXIST)
1392-
goto out;
1393-
error = 0;
1394-
1395-
ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
1396-
ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
1397-
XFS_ATTR_LEAF_MAGIC);
1398-
1399-
if (args->rmtblkno > 0) {
1400-
error = xfs_attr_leaf_mark_incomplete(args, *state);
1401-
if (error)
1402-
goto out;
1403-
1404-
error = xfs_attr_rmtval_invalidate(args);
1405-
}
1406-
out:
1407-
if (error)
1408-
xfs_da_state_free(*state);
1409-
1410-
return error;
1411-
}
1412-
14131428
STATIC int
14141429
xfs_attr_node_removename(
14151430
struct xfs_da_args *args,

fs/xfs/libxfs/xfs_attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ enum xfs_delattr_state {
451451
XFS_DAS_RM_NAME, /* Remove attr name */
452452
XFS_DAS_RM_SHRINK, /* We are shrinking the tree */
453453

454+
XFS_DAS_SF_REMOVE, /* Initial shortform set iter state */
455+
XFS_DAS_LEAF_REMOVE, /* Initial leaf form set iter state */
456+
XFS_DAS_NODE_REMOVE, /* Initial node form set iter state */
457+
454458
/* Leaf state set/replace sequence */
455459
XFS_DAS_LEAF_SET_RMT, /* set a remote xattr from a leaf */
456460
XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */

fs/xfs/xfs_trace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4136,6 +4136,9 @@ TRACE_DEFINE_ENUM(XFS_DAS_NODE_ADD);
41364136
TRACE_DEFINE_ENUM(XFS_DAS_RMTBLK);
41374137
TRACE_DEFINE_ENUM(XFS_DAS_RM_NAME);
41384138
TRACE_DEFINE_ENUM(XFS_DAS_RM_SHRINK);
4139+
TRACE_DEFINE_ENUM(XFS_DAS_SF_REMOVE);
4140+
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_REMOVE);
4141+
TRACE_DEFINE_ENUM(XFS_DAS_NODE_REMOVE);
41394142
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_SET_RMT);
41404143
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_ALLOC_RMT);
41414144
TRACE_DEFINE_ENUM(XFS_DAS_LEAF_REPLACE);

0 commit comments

Comments
 (0)