@@ -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
0 commit comments