Skip to content

Commit e7f358d

Browse files
Dave Chinnerdchinner
authored andcommitted
xfs: use XFS_DA_OP flags in deferred attr ops
We currently store the high level attr operation in args->attr_flags. This field contains what the VFS is telling us to do, but don't necessarily match what we are doing in the low level modification state machine. e.g. XATTR_REPLACE implies both XFS_DA_OP_ADDNAME and XFS_DA_OP_RENAME because it is doing both a remove and adding a new attr. However, deep in the individual state machine operations, we check errors against this high level VFS op flags, not the low level XFS_DA_OP flags. Indeed, we don't even have a low level flag for a REMOVE operation, so the only way we know we are doing a remove is the complete absence of XATTR_REPLACE, XATTR_CREATE, XFS_DA_OP_ADDNAME and XFS_DA_OP_RENAME. And because there are other flags in these fields, this is a pain to check if we need to. As the XFS_DA_OP flags are only needed once the deferred operations are set up, set these flags appropriately when we set the initial operation state. We also introduce a XFS_DA_OP_REMOVE flag to make it easy to know that we are doing a remove operation. With these, we can remove the use of XATTR_REPLACE and XATTR_CREATE in low level lookup operations, and manipulate the low level flags according to the low level context that is operating. e.g. log recovery does not have a VFS xattr operation state to copy into args->attr_flags, and the low level state machine ops we do for recovery do not match the high level VFS operations that were in progress when the system failed... Signed-off-by: Dave Chinner <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Allison Henderson <[email protected]> Signed-off-by: Dave Chinner <[email protected]>
1 parent 59782a2 commit e7f358d

File tree

4 files changed

+84
-67
lines changed

4 files changed

+84
-67
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ xfs_attr_leaf_addname(
466466
*/
467467
if (args->rmtblkno)
468468
attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
469-
else if (args->op_flags & XFS_DA_OP_RENAME)
469+
else if (args->op_flags & XFS_DA_OP_REPLACE)
470470
xfs_attr_dela_state_set_replace(attr, XFS_DAS_LEAF_REPLACE);
471471
else
472472
attr->xattri_dela_state = XFS_DAS_DONE;
@@ -511,7 +511,7 @@ xfs_attr_node_addname(
511511

512512
if (args->rmtblkno)
513513
attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
514-
else if (args->op_flags & XFS_DA_OP_RENAME)
514+
else if (args->op_flags & XFS_DA_OP_REPLACE)
515515
xfs_attr_dela_state_set_replace(attr, XFS_DAS_NODE_REPLACE);
516516
else
517517
attr->xattri_dela_state = XFS_DAS_DONE;
@@ -547,7 +547,7 @@ xfs_attr_rmtval_alloc(
547547
return error;
548548

549549
/* If this is not a rename, clear the incomplete flag and we're done. */
550-
if (!(args->op_flags & XFS_DA_OP_RENAME)) {
550+
if (!(args->op_flags & XFS_DA_OP_REPLACE)) {
551551
error = xfs_attr3_leaf_clearflag(args);
552552
attr->xattri_dela_state = XFS_DAS_DONE;
553553
} else {
@@ -966,8 +966,6 @@ xfs_attr_set(
966966

967967
if (args->value) {
968968
XFS_STATS_INC(mp, xs_attr_set);
969-
970-
args->op_flags |= XFS_DA_OP_ADDNAME;
971969
args->total = xfs_attr_calc_size(args, &local);
972970

973971
/*
@@ -1125,28 +1123,41 @@ static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
11251123
* Add a name to the shortform attribute list structure
11261124
* This is the external routine.
11271125
*/
1128-
STATIC int
1129-
xfs_attr_shortform_addname(xfs_da_args_t *args)
1126+
static int
1127+
xfs_attr_shortform_addname(
1128+
struct xfs_da_args *args)
11301129
{
1131-
int newsize, forkoff, retval;
1130+
int newsize, forkoff;
1131+
int error;
11321132

11331133
trace_xfs_attr_sf_addname(args);
11341134

1135-
retval = xfs_attr_shortform_lookup(args);
1136-
if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
1137-
return retval;
1138-
if (retval == -EEXIST) {
1139-
if (args->attr_flags & XATTR_CREATE)
1140-
return retval;
1141-
retval = xfs_attr_sf_removename(args);
1142-
if (retval)
1143-
return retval;
1135+
error = xfs_attr_shortform_lookup(args);
1136+
switch (error) {
1137+
case -ENOATTR:
1138+
if (args->op_flags & XFS_DA_OP_REPLACE)
1139+
return error;
1140+
break;
1141+
case -EEXIST:
1142+
if (!(args->op_flags & XFS_DA_OP_REPLACE))
1143+
return error;
1144+
1145+
error = xfs_attr_sf_removename(args);
1146+
if (error)
1147+
return error;
1148+
11441149
/*
1145-
* Since we have removed the old attr, clear ATTR_REPLACE so
1146-
* that the leaf format add routine won't trip over the attr
1147-
* not being around.
1150+
* Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1151+
* so that the new attr doesn't fit in shortform format, the
1152+
* leaf format add routine won't trip over the attr not being
1153+
* around.
11481154
*/
1149-
args->attr_flags &= ~XATTR_REPLACE;
1155+
args->op_flags &= ~XFS_DA_OP_REPLACE;
1156+
break;
1157+
case 0:
1158+
break;
1159+
default:
1160+
return error;
11501161
}
11511162

11521163
if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
@@ -1169,8 +1180,8 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
11691180
* External routines when attribute list is one block
11701181
*========================================================================*/
11711182

1172-
/* Store info about a remote block */
1173-
STATIC void
1183+
/* Save the current remote block info and clear the current pointers. */
1184+
static void
11741185
xfs_attr_save_rmt_blk(
11751186
struct xfs_da_args *args)
11761187
{
@@ -1179,10 +1190,13 @@ xfs_attr_save_rmt_blk(
11791190
args->rmtblkno2 = args->rmtblkno;
11801191
args->rmtblkcnt2 = args->rmtblkcnt;
11811192
args->rmtvaluelen2 = args->rmtvaluelen;
1193+
args->rmtblkno = 0;
1194+
args->rmtblkcnt = 0;
1195+
args->rmtvaluelen = 0;
11821196
}
11831197

11841198
/* Set stored info about a remote block */
1185-
STATIC void
1199+
static void
11861200
xfs_attr_restore_rmt_blk(
11871201
struct xfs_da_args *args)
11881202
{
@@ -1228,28 +1242,27 @@ xfs_attr_leaf_try_add(
12281242
* Look up the xattr name to set the insertion point for the new xattr.
12291243
*/
12301244
error = xfs_attr3_leaf_lookup_int(bp, args);
1231-
if (error != -ENOATTR && error != -EEXIST)
1232-
goto out_brelse;
1233-
if (error == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
1234-
goto out_brelse;
1235-
if (error == -EEXIST) {
1236-
if (args->attr_flags & XATTR_CREATE)
1245+
switch (error) {
1246+
case -ENOATTR:
1247+
if (args->op_flags & XFS_DA_OP_REPLACE)
1248+
goto out_brelse;
1249+
break;
1250+
case -EEXIST:
1251+
if (!(args->op_flags & XFS_DA_OP_REPLACE))
12371252
goto out_brelse;
12381253

12391254
trace_xfs_attr_leaf_replace(args);
1240-
1241-
/* save the attribute state for later removal*/
1242-
args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */
1243-
xfs_attr_save_rmt_blk(args);
1244-
12451255
/*
1246-
* clear the remote attr state now that it is saved so that the
1247-
* values reflect the state of the attribute we are about to
1256+
* Save the existing remote attr state so that the current
1257+
* values reflect the state of the new attribute we are about to
12481258
* add, not the attribute we just found and will remove later.
12491259
*/
1250-
args->rmtblkno = 0;
1251-
args->rmtblkcnt = 0;
1252-
args->rmtvaluelen = 0;
1260+
xfs_attr_save_rmt_blk(args);
1261+
break;
1262+
case 0:
1263+
break;
1264+
default:
1265+
goto out_brelse;
12531266
}
12541267

12551268
return xfs_attr3_leaf_add(bp, args);
@@ -1388,46 +1401,45 @@ xfs_attr_node_hasname(
13881401

13891402
STATIC int
13901403
xfs_attr_node_addname_find_attr(
1391-
struct xfs_attr_item *attr)
1404+
struct xfs_attr_item *attr)
13921405
{
1393-
struct xfs_da_args *args = attr->xattri_da_args;
1394-
int retval;
1406+
struct xfs_da_args *args = attr->xattri_da_args;
1407+
int error;
13951408

13961409
/*
13971410
* Search to see if name already exists, and get back a pointer
13981411
* to where it should go.
13991412
*/
1400-
retval = xfs_attr_node_hasname(args, &attr->xattri_da_state);
1401-
if (retval != -ENOATTR && retval != -EEXIST)
1402-
goto error;
1403-
1404-
if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
1405-
goto error;
1406-
if (retval == -EEXIST) {
1407-
if (args->attr_flags & XATTR_CREATE)
1413+
error = xfs_attr_node_hasname(args, &attr->xattri_da_state);
1414+
switch (error) {
1415+
case -ENOATTR:
1416+
if (args->op_flags & XFS_DA_OP_REPLACE)
1417+
goto error;
1418+
break;
1419+
case -EEXIST:
1420+
if (!(args->op_flags & XFS_DA_OP_REPLACE))
14081421
goto error;
14091422

1410-
trace_xfs_attr_node_replace(args);
1411-
1412-
/* save the attribute state for later removal*/
1413-
args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */
1414-
xfs_attr_save_rmt_blk(args);
14151423

1424+
trace_xfs_attr_node_replace(args);
14161425
/*
1417-
* clear the remote attr state now that it is saved so that the
1418-
* values reflect the state of the attribute we are about to
1426+
* Save the existing remote attr state so that the current
1427+
* values reflect the state of the new attribute we are about to
14191428
* add, not the attribute we just found and will remove later.
14201429
*/
1421-
args->rmtblkno = 0;
1422-
args->rmtblkcnt = 0;
1423-
args->rmtvaluelen = 0;
1430+
xfs_attr_save_rmt_blk(args);
1431+
break;
1432+
case 0:
1433+
break;
1434+
default:
1435+
goto error;
14241436
}
14251437

14261438
return 0;
14271439
error:
14281440
if (attr->xattri_da_state)
14291441
xfs_da_state_free(attr->xattri_da_state);
1430-
return retval;
1442+
return error;
14311443
}
14321444

14331445
/*

fs/xfs/libxfs/xfs_attr.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,6 @@ xfs_attr_is_shortform(
584584
static inline enum xfs_delattr_state
585585
xfs_attr_init_add_state(struct xfs_da_args *args)
586586
{
587-
588587
/*
589588
* When called from the completion of a attr remove to determine the
590589
* next state, the attribute fork may be null. This can occur only occur
@@ -595,6 +594,8 @@ xfs_attr_init_add_state(struct xfs_da_args *args)
595594
*/
596595
if (!args->dp->i_afp)
597596
return XFS_DAS_DONE;
597+
598+
args->op_flags |= XFS_DA_OP_ADDNAME;
598599
if (xfs_attr_is_shortform(args->dp))
599600
return XFS_DAS_SF_ADD;
600601
if (xfs_attr_is_leaf(args->dp))
@@ -605,6 +606,7 @@ xfs_attr_init_add_state(struct xfs_da_args *args)
605606
static inline enum xfs_delattr_state
606607
xfs_attr_init_remove_state(struct xfs_da_args *args)
607608
{
609+
args->op_flags |= XFS_DA_OP_REMOVE;
608610
if (xfs_attr_is_shortform(args->dp))
609611
return XFS_DAS_SF_REMOVE;
610612
if (xfs_attr_is_leaf(args->dp))
@@ -615,6 +617,7 @@ xfs_attr_init_remove_state(struct xfs_da_args *args)
615617
static inline enum xfs_delattr_state
616618
xfs_attr_init_replace_state(struct xfs_da_args *args)
617619
{
620+
args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
618621
return xfs_attr_init_add_state(args);
619622
}
620623

fs/xfs/libxfs/xfs_attr_leaf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ xfs_attr3_leaf_add_work(
14921492
entry->flags = args->attr_filter;
14931493
if (tmp)
14941494
entry->flags |= XFS_ATTR_LOCAL;
1495-
if (args->op_flags & XFS_DA_OP_RENAME) {
1495+
if (args->op_flags & XFS_DA_OP_REPLACE) {
14961496
if (!xfs_has_larp(mp))
14971497
entry->flags |= XFS_ATTR_INCOMPLETE;
14981498
if ((args->blkno2 == args->blkno) &&

fs/xfs/libxfs/xfs_da_btree.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,21 @@ typedef struct xfs_da_args {
8585
* Operation flags:
8686
*/
8787
#define XFS_DA_OP_JUSTCHECK (1u << 0) /* check for ok with no space */
88-
#define XFS_DA_OP_RENAME (1u << 1) /* this is an atomic rename op */
88+
#define XFS_DA_OP_REPLACE (1u << 1) /* this is an atomic replace op */
8989
#define XFS_DA_OP_ADDNAME (1u << 2) /* this is an add operation */
9090
#define XFS_DA_OP_OKNOENT (1u << 3) /* lookup op, ENOENT ok, else die */
9191
#define XFS_DA_OP_CILOOKUP (1u << 4) /* lookup returns CI name if found */
9292
#define XFS_DA_OP_NOTIME (1u << 5) /* don't update inode timestamps */
93+
#define XFS_DA_OP_REMOVE (1u << 6) /* this is a remove operation */
9394

9495
#define XFS_DA_OP_FLAGS \
9596
{ XFS_DA_OP_JUSTCHECK, "JUSTCHECK" }, \
96-
{ XFS_DA_OP_RENAME, "RENAME" }, \
97+
{ XFS_DA_OP_REPLACE, "REPLACE" }, \
9798
{ XFS_DA_OP_ADDNAME, "ADDNAME" }, \
9899
{ XFS_DA_OP_OKNOENT, "OKNOENT" }, \
99100
{ XFS_DA_OP_CILOOKUP, "CILOOKUP" }, \
100-
{ XFS_DA_OP_NOTIME, "NOTIME" }
101+
{ XFS_DA_OP_NOTIME, "NOTIME" }, \
102+
{ XFS_DA_OP_REMOVE, "REMOVE" }
101103

102104
/*
103105
* Storage for holding state during Btree searches and split/join ops.

0 commit comments

Comments
 (0)