Skip to content

Commit 251b29c

Browse files
dgchinnerdchinner
authored andcommitted
xfs: consolidate leaf/node states in xfs_attr_set_iter
The operations performed from XFS_DAS_FOUND_LBLK through to XFS_DAS_RM_LBLK are now identical to XFS_DAS_FOUND_NBLK through to XFS_DAS_RM_NBLK. We can collapse these down into a single set of code. To do this, define the states that leaf and node run through as separate sets of sequential states. Then as we move to the next state, we can use increments rather than specific state assignments to move through the states. This means the state progression is set by the initial state that enters the series and we don't need to duplicate the code anymore. At the exit point of the series we need to select the correct leaf or node state, but that can also be done by state increment rather than assignment. 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>
1 parent 2157d16 commit 251b29c

2 files changed

Lines changed: 27 additions & 109 deletions

File tree

fs/xfs/libxfs/xfs_attr.c

Lines changed: 20 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ xfs_attr_set_iter(
393393
struct xfs_mount *mp = args->dp->i_mount;
394394

395395
/* State machine switch */
396+
next_state:
396397
switch (attr->xattri_dela_state) {
397398
case XFS_DAS_UNINIT:
398399
ASSERT(0);
@@ -405,6 +406,7 @@ xfs_attr_set_iter(
405406
return xfs_attr_node_addname(attr);
406407

407408
case XFS_DAS_FOUND_LBLK:
409+
case XFS_DAS_FOUND_NBLK:
408410
/*
409411
* Find space for remote blocks and fall into the allocation
410412
* state.
@@ -414,9 +416,10 @@ xfs_attr_set_iter(
414416
if (error)
415417
return error;
416418
}
417-
attr->xattri_dela_state = XFS_DAS_LEAF_ALLOC_RMT;
419+
attr->xattri_dela_state++;
418420
fallthrough;
419421
case XFS_DAS_LEAF_ALLOC_RMT:
422+
case XFS_DAS_NODE_ALLOC_RMT:
420423

421424
/*
422425
* If there was an out-of-line value, allocate the blocks we
@@ -465,16 +468,18 @@ xfs_attr_set_iter(
465468
return error;
466469
/*
467470
* Commit the flag value change and start the next trans
468-
* in series.
471+
* in series at FLIP_FLAG.
469472
*/
470-
attr->xattri_dela_state = XFS_DAS_FLIP_LFLAG;
473+
attr->xattri_dela_state++;
471474
trace_xfs_attr_set_iter_return(attr->xattri_dela_state,
472475
args->dp);
473476
return -EAGAIN;
474477
}
475478

479+
attr->xattri_dela_state++;
476480
fallthrough;
477481
case XFS_DAS_FLIP_LFLAG:
482+
case XFS_DAS_FLIP_NFLAG:
478483
/*
479484
* Dismantle the "old" attribute/value pair by removing a
480485
* "remote" value (if it exists).
@@ -484,10 +489,10 @@ xfs_attr_set_iter(
484489
if (error)
485490
return error;
486491

492+
attr->xattri_dela_state++;
487493
fallthrough;
488494
case XFS_DAS_RM_LBLK:
489-
/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
490-
attr->xattri_dela_state = XFS_DAS_RM_LBLK;
495+
case XFS_DAS_RM_NBLK:
491496
if (args->rmtblkno) {
492497
error = xfs_attr_rmtval_remove(attr);
493498
if (error == -EAGAIN)
@@ -502,7 +507,16 @@ xfs_attr_set_iter(
502507
return -EAGAIN;
503508
}
504509

505-
fallthrough;
510+
/*
511+
* This is the end of the shared leaf/node sequence. We need
512+
* to continue at the next state in the sequence, but we can't
513+
* easily just fall through. So we increment to the next state
514+
* and then jump back to switch statement to evaluate the next
515+
* state correctly.
516+
*/
517+
attr->xattri_dela_state++;
518+
goto next_state;
519+
506520
case XFS_DAS_RD_LEAF:
507521
/*
508522
* This is the last step for leaf format. Read the block with
@@ -523,106 +537,6 @@ xfs_attr_set_iter(
523537

524538
return error;
525539

526-
case XFS_DAS_FOUND_NBLK:
527-
/*
528-
* Find space for remote blocks and fall into the allocation
529-
* state.
530-
*/
531-
if (args->rmtblkno > 0) {
532-
error = xfs_attr_rmtval_find_space(attr);
533-
if (error)
534-
return error;
535-
}
536-
537-
attr->xattri_dela_state = XFS_DAS_NODE_ALLOC_RMT;
538-
fallthrough;
539-
case XFS_DAS_NODE_ALLOC_RMT:
540-
/*
541-
* If there was an out-of-line value, allocate the blocks we
542-
* identified for its storage and copy the value. This is done
543-
* after we create the attribute so that we don't overflow the
544-
* maximum size of a transaction and/or hit a deadlock.
545-
*/
546-
if (args->rmtblkno > 0) {
547-
if (attr->xattri_blkcnt > 0) {
548-
error = xfs_attr_rmtval_set_blk(attr);
549-
if (error)
550-
return error;
551-
trace_xfs_attr_set_iter_return(
552-
attr->xattri_dela_state, args->dp);
553-
return -EAGAIN;
554-
}
555-
556-
error = xfs_attr_rmtval_set_value(args);
557-
if (error)
558-
return error;
559-
}
560-
561-
/*
562-
* If this was not a rename, clear the incomplete flag and we're
563-
* done.
564-
*/
565-
if (!(args->op_flags & XFS_DA_OP_RENAME)) {
566-
if (args->rmtblkno > 0)
567-
error = xfs_attr3_leaf_clearflag(args);
568-
goto out;
569-
}
570-
571-
/*
572-
* If this is an atomic rename operation, we must "flip" the
573-
* incomplete flags on the "new" and "old" attribute/value pairs
574-
* so that one disappears and one appears atomically. Then we
575-
* must remove the "old" attribute/value pair.
576-
*
577-
* In a separate transaction, set the incomplete flag on the
578-
* "old" attr and clear the incomplete flag on the "new" attr.
579-
*/
580-
if (!xfs_has_larp(mp)) {
581-
error = xfs_attr3_leaf_flipflags(args);
582-
if (error)
583-
goto out;
584-
/*
585-
* Commit the flag value change and start the next trans
586-
* in series
587-
*/
588-
attr->xattri_dela_state = XFS_DAS_FLIP_NFLAG;
589-
trace_xfs_attr_set_iter_return(attr->xattri_dela_state,
590-
args->dp);
591-
return -EAGAIN;
592-
}
593-
594-
fallthrough;
595-
case XFS_DAS_FLIP_NFLAG:
596-
/*
597-
* Dismantle the "old" attribute/value pair by removing a
598-
* "remote" value (if it exists).
599-
*/
600-
xfs_attr_restore_rmt_blk(args);
601-
602-
error = xfs_attr_rmtval_invalidate(args);
603-
if (error)
604-
return error;
605-
606-
fallthrough;
607-
case XFS_DAS_RM_NBLK:
608-
/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
609-
attr->xattri_dela_state = XFS_DAS_RM_NBLK;
610-
if (args->rmtblkno) {
611-
error = xfs_attr_rmtval_remove(attr);
612-
if (error == -EAGAIN)
613-
trace_xfs_attr_set_iter_return(
614-
attr->xattri_dela_state, args->dp);
615-
616-
if (error)
617-
return error;
618-
619-
attr->xattri_dela_state = XFS_DAS_CLR_FLAG;
620-
trace_xfs_attr_set_iter_return(attr->xattri_dela_state,
621-
args->dp);
622-
return -EAGAIN;
623-
}
624-
625-
fallthrough;
626540
case XFS_DAS_CLR_FLAG:
627541
/*
628542
* The last state for node format. Look up the old attr and
@@ -634,7 +548,6 @@ xfs_attr_set_iter(
634548
ASSERT(0);
635549
break;
636550
}
637-
out:
638551
return error;
639552
}
640553

fs/xfs/libxfs/xfs_attr.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,16 +450,21 @@ enum xfs_delattr_state {
450450
XFS_DAS_RMTBLK, /* Removing remote blks */
451451
XFS_DAS_RM_NAME, /* Remove attr name */
452452
XFS_DAS_RM_SHRINK, /* We are shrinking the tree */
453+
454+
/* Leaf state set sequence */
453455
XFS_DAS_FOUND_LBLK, /* We found leaf blk for attr */
454456
XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */
455-
XFS_DAS_FOUND_NBLK, /* We found node blk for attr */
456-
XFS_DAS_NODE_ALLOC_RMT, /* We are allocating remote blocks */
457457
XFS_DAS_FLIP_LFLAG, /* Flipped leaf INCOMPLETE attr flag */
458458
XFS_DAS_RM_LBLK, /* A rename is removing leaf blocks */
459459
XFS_DAS_RD_LEAF, /* Read in the new leaf */
460+
461+
/* Node state set sequence, must match leaf state above */
462+
XFS_DAS_FOUND_NBLK, /* We found node blk for attr */
463+
XFS_DAS_NODE_ALLOC_RMT, /* We are allocating remote blocks */
460464
XFS_DAS_FLIP_NFLAG, /* Flipped node INCOMPLETE attr flag */
461465
XFS_DAS_RM_NBLK, /* A rename is removing node blocks */
462466
XFS_DAS_CLR_FLAG, /* Clear incomplete flag */
467+
463468
XFS_DAS_DONE, /* finished operation */
464469
};
465470

0 commit comments

Comments
 (0)