I factored the code a bit more, cleaning up the final leaf/node states to look the same from the perspective of the state machine. I then made sure that the state machine has a termination state - XFS_DAS_DONE - so taht callers can determine whether the operation is complete without requiring xfs_attr_set_iter() to return -EAGAIN to tell the caller it needs to keep iterating. This allows removal of most of the -EAGAIN returns and conditional logic in the xfs_attr_set_iter() implementation and leaf functions. This means that requirement of the deferop transaction rolling API (return -EAGAIN) is contained entirely within xfs_attri_finish_one() instead of bleeding through to xfs_attr_set_iter(). Overall, I find the state machine code much easier to read and follow because it largely separates the implementation of individual states from the execution of the state machine. The states are smaller and easier to understate, too. What I haven't done yet is update the big flowchart in xfs_attr.h. Much of it is now stale and it doesn't match the new states or progression through the states. I'm wondering if there's a better way to document the state machine than a comment that will get rapidly out of date, even though that comment was very helpful in working out how to re-write the state machine cleanly.... I plan to make the same structural mods to xfs_attr_remove_iter(), and then I can clean up xfs_attri_finish_one() and get rid of the XFS_TRANS_DIRTY in that code. The diffstat isn't too bad - it doesn't make the code smaller overall because I split a lot of stuff out into smaller functions, but it doesn't get bigger, either, and I think the result is much more readable and maintainable. fs/xfs/libxfs/xfs_attr.c | 586 ++++++++++++++++------------------- fs/xfs/libxfs/xfs_attr.h | 60 +++- fs/xfs/xfs_attr_item.c | 2 + fs/xfs/xfs_trace.h | 26 +- 4 files changed, 345 insertions(+), 329 deletions(-) The patchset passes fstests '-g attr' running in a loop when larp=0, but I haven't tested it with larp=1 yet - I've done zero larp=1 testing so far so I don't even know whether it works in the base 5.19 compose yet. I'll look at that when I finish the state machine updates.... Thoughts? Cheers, Dave.