All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v19 00/14] Delay Ready Attributes
@ 2021-05-25 19:54 Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 01/14] xfs: Reverse apply 72b97ea40d Allison Henderson
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

Hi all,

This set is a subset of a larger series for Dealyed Attributes. Which is a
subset of a yet larger series for parent pointers. Delayed attributes allow
attribute operations (set and remove) to be logged and committed in the same
way that other delayed operations do. This allows more complex operations (like
parent pointers) to be broken up into multiple smaller transactions. To do
this, the existing attr operations must be modified to operate as a delayed
operation.  This means that they cannot roll, commit, or finish transactions.
Instead, they return -EAGAIN to allow the calling function to handle the
transaction.  In this series, we focus on only the delayed attribute portion.
We will introduce parent pointers in a later set.

The set as a whole is a bit much to digest at once, so I usually send out the
smaller sub series to reduce reviewer burn out.  But the entire extended series
is visible through the included github links.

Updates since v18:  Very minor nits, and also some additional clean up patches
near the end.  Patches 3 and 4 from the previous set have been merged, but
otherwise the same.

xfs: Add helper xfs_attr_set_fmt
  REMOVED

xfs: Hoist xfs_attr_set_shortform
  REMOVED

xfs: Refactor xfs_attr_set_shortform
  NEW
  This is a combination of the above two patches
  Did some white space clean up, but all other functional changes are the same
  RVB's retained

xfs: Separate xfs_attr_node_addname and xfs_attr_node_addname_clear_incomplete
  Indentation nits

xfs: Add delay ready attr remove routines
  Flow chart and comment typo nits

xfs: Add delay ready attr set routines
  Flow chart typo fix
  Indentation fix in xfs_attr_rmtval_set_blk

xfs: Remove xfs_attr_rmtval_set
  NEW

xfs: Clean up xfs_attr_node_addname_clear_incomplete
  NEW

xfs: Remove default ASSERT in xfs_attr_set_iter
  NEW

xfs: Make attr name schemes consistent
  NEW

EXTENDED SET
xfs: Add helper function xfs_attr_leaf_addname
  NEW

This series can be viewed on github here:
https://github.com/allisonhenderson/xfs_work/tree/delay_ready_attrs_v19

As well as the extended delayed attribute and parent pointer series:
https://github.com/allisonhenderson/xfs_work/tree/delay_ready_attrs_v19_extended

And the test cases:
https://github.com/allisonhenderson/xfs_work/tree/pptr_xfstestsv3
In order to run the test cases, you will need have the corresponding xfsprogs

changes as well.  Which can be found here:
https://github.com/allisonhenderson/xfs_work/tree/delay_ready_attrs_xfsprogs_v19
https://github.com/allisonhenderson/xfs_work/tree/delay_ready_attrs_xfsprogs_v19_extended

To run the xfs attributes tests run:
check -g attr

To run as delayed attributes run:
export MOUNT_OPTIONS="-o delattr"
check -g attr

To run parent pointer tests:
check -g parent

I've also made the corresponding updates to the user space side as well, and ported anything
they need to seat correctly.

Questions, comment and feedback appreciated! 

Thanks all!
Allison

Allison Henderson (14):
  xfs: Reverse apply 72b97ea40d
  xfs: Add xfs_attr_node_remove_name
  xfs: Refactor xfs_attr_set_shortform
  xfs: Separate xfs_attr_node_addname and
    xfs_attr_node_addname_clear_incomplete
  xfs: Add helper xfs_attr_node_addname_find_attr
  xfs: Hoist xfs_attr_node_addname
  xfs: Hoist xfs_attr_leaf_addname
  xfs: Hoist node transaction handling
  xfs: Add delay ready attr remove routines
  xfs: Add delay ready attr set routines
  xfs: Remove xfs_attr_rmtval_set
  xfs: Clean up xfs_attr_node_addname_clear_incomplete
  xfs: Remove default ASSERT in xfs_attr_set_iter
  xfs: Make attr name schemes consistent

 fs/xfs/libxfs/xfs_attr.c        | 899 ++++++++++++++++++++++++----------------
 fs/xfs/libxfs/xfs_attr.h        | 403 ++++++++++++++++++
 fs/xfs/libxfs/xfs_attr_leaf.c   |   4 +-
 fs/xfs/libxfs/xfs_attr_leaf.h   |   2 +-
 fs/xfs/libxfs/xfs_attr_remote.c | 163 +++-----
 fs/xfs/libxfs/xfs_attr_remote.h |   8 +-
 fs/xfs/xfs_attr_inactive.c      |   2 +-
 fs/xfs/xfs_trace.h              |   2 -
 8 files changed, 1018 insertions(+), 465 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v19 01/14] xfs: Reverse apply 72b97ea40d
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 02/14] xfs: Add xfs_attr_node_remove_name Allison Henderson
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

Originally we added this patch to help modularize the attr code in
preparation for delayed attributes and the state machine it requires.
However, later reviews found that this slightly alters the transaction
handling as the helper function is ambiguous as to whether the
transaction is diry or clean.  This may cause a dirty transaction to be
included in the next roll, where previously it had not.  To preserve the
existing code flow, we reverse apply this commit.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_attr.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 96146f4..190b46d 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -1214,24 +1214,6 @@ int xfs_attr_node_removename_setup(
 	return 0;
 }
 
-STATIC int
-xfs_attr_node_remove_rmt(
-	struct xfs_da_args	*args,
-	struct xfs_da_state	*state)
-{
-	int			error = 0;
-
-	error = xfs_attr_rmtval_remove(args);
-	if (error)
-		return error;
-
-	/*
-	 * Refill the state structure with buffers, the prior calls released our
-	 * buffers.
-	 */
-	return xfs_attr_refillstate(state);
-}
-
 /*
  * Remove a name from a B-tree attribute list.
  *
@@ -1260,7 +1242,15 @@ xfs_attr_node_removename(
 	 * overflow the maximum size of a transaction and/or hit a deadlock.
 	 */
 	if (args->rmtblkno > 0) {
-		error = xfs_attr_node_remove_rmt(args, state);
+		error = xfs_attr_rmtval_remove(args);
+		if (error)
+			goto out;
+
+		/*
+		 * Refill the state structure with buffers, the prior calls
+		 * released our buffers.
+		 */
+		error = xfs_attr_refillstate(state);
 		if (error)
 			goto out;
 	}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 02/14] xfs: Add xfs_attr_node_remove_name
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 01/14] xfs: Reverse apply 72b97ea40d Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 03/14] xfs: Refactor xfs_attr_set_shortform Allison Henderson
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch pulls a new helper function xfs_attr_node_remove_name out
of xfs_attr_node_remove_step.  This helps to modularize
xfs_attr_node_remove_step which will help make the delayed attribute
code easier to follow

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
---
 fs/xfs/libxfs/xfs_attr.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 190b46d..8a08d5b 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -1214,6 +1214,25 @@ int xfs_attr_node_removename_setup(
 	return 0;
 }
 
+STATIC int
+xfs_attr_node_remove_name(
+	struct xfs_da_args	*args,
+	struct xfs_da_state	*state)
+{
+	struct xfs_da_state_blk	*blk;
+	int			retval;
+
+	/*
+	 * Remove the name and update the hashvals in the tree.
+	 */
+	blk = &state->path.blk[state->path.active-1];
+	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
+	retval = xfs_attr3_leaf_remove(blk->bp, args);
+	xfs_da3_fixhashpath(state, &state->path);
+
+	return retval;
+}
+
 /*
  * Remove a name from a B-tree attribute list.
  *
@@ -1226,7 +1245,6 @@ xfs_attr_node_removename(
 	struct xfs_da_args	*args)
 {
 	struct xfs_da_state	*state;
-	struct xfs_da_state_blk	*blk;
 	int			retval, error;
 	struct xfs_inode	*dp = args->dp;
 
@@ -1254,14 +1272,7 @@ xfs_attr_node_removename(
 		if (error)
 			goto out;
 	}
-
-	/*
-	 * Remove the name and update the hashvals in the tree.
-	 */
-	blk = &state->path.blk[ state->path.active-1 ];
-	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
-	retval = xfs_attr3_leaf_remove(blk->bp, args);
-	xfs_da3_fixhashpath(state, &state->path);
+	retval = xfs_attr_node_remove_name(args, state);
 
 	/*
 	 * Check to see if the tree needs to be collapsed.
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 03/14] xfs: Refactor xfs_attr_set_shortform
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 01/14] xfs: Reverse apply 72b97ea40d Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 02/14] xfs: Add xfs_attr_node_remove_name Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 04/14] xfs: Separate xfs_attr_node_addname and xfs_attr_node_addname_clear_incomplete Allison Henderson
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch is actually the combination of patches from the previous
version (v18).  Initially patch 3 hoisted xfs_attr_set_shortform, and
the next added the helper xfs_attr_set_fmt. xfs_attr_set_fmt is similar
the old xfs_attr_set_shortform. It returns 0 when the attr has been set
and no further action is needed. It returns -EAGAIN when shortform has
been transformed to leaf, and the calling function should proceed the
set the attr in leaf form.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
---
 fs/xfs/libxfs/xfs_attr.c | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 8a08d5b..0ec1547 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -236,16 +236,11 @@ xfs_attr_is_shortform(
 		ip->i_afp->if_nextents == 0);
 }
 
-/*
- * Attempts to set an attr in shortform, or converts short form to leaf form if
- * there is not enough room.  If the attr is set, the transaction is committed
- * and set to NULL.
- */
 STATIC int
-xfs_attr_set_shortform(
-	struct xfs_da_args	*args,
-	struct xfs_buf		**leaf_bp)
+xfs_attr_set_fmt(
+	struct xfs_da_args	*args)
 {
+	struct xfs_buf          *leaf_bp = NULL;
 	struct xfs_inode	*dp = args->dp;
 	int			error, error2 = 0;
 
@@ -258,29 +253,29 @@ xfs_attr_set_shortform(
 		args->trans = NULL;
 		return error ? error : error2;
 	}
+
 	/*
 	 * It won't fit in the shortform, transform to a leaf block.  GROT:
 	 * another possible req'mt for a double-split btree op.
 	 */
-	error = xfs_attr_shortform_to_leaf(args, leaf_bp);
+	error = xfs_attr_shortform_to_leaf(args, &leaf_bp);
 	if (error)
 		return error;
 
 	/*
 	 * Prevent the leaf buffer from being unlocked so that a concurrent AIL
 	 * push cannot grab the half-baked leaf buffer and run into problems
-	 * with the write verifier. Once we're done rolling the transaction we
-	 * can release the hold and add the attr to the leaf.
+	 * with the write verifier.
 	 */
-	xfs_trans_bhold(args->trans, *leaf_bp);
+	xfs_trans_bhold(args->trans, leaf_bp);
 	error = xfs_defer_finish(&args->trans);
-	xfs_trans_bhold_release(args->trans, *leaf_bp);
+	xfs_trans_bhold_release(args->trans, leaf_bp);
 	if (error) {
-		xfs_trans_brelse(args->trans, *leaf_bp);
+		xfs_trans_brelse(args->trans, leaf_bp);
 		return error;
 	}
 
-	return 0;
+	return -EAGAIN;
 }
 
 /*
@@ -291,8 +286,7 @@ xfs_attr_set_args(
 	struct xfs_da_args	*args)
 {
 	struct xfs_inode	*dp = args->dp;
-	struct xfs_buf          *leaf_bp = NULL;
-	int			error = 0;
+	int			error;
 
 	/*
 	 * If the attribute list is already in leaf format, jump straight to
@@ -301,15 +295,8 @@ xfs_attr_set_args(
 	 * again.
 	 */
 	if (xfs_attr_is_shortform(dp)) {
-
-		/*
-		 * If the attr was successfully set in shortform, the
-		 * transaction is committed and set to NULL.  Otherwise, is it
-		 * converted from shortform to leaf, and the transaction is
-		 * retained.
-		 */
-		error = xfs_attr_set_shortform(args, &leaf_bp);
-		if (error || !args->trans)
+		error = xfs_attr_set_fmt(args);
+		if (error != -EAGAIN)
 			return error;
 	}
 
@@ -344,8 +331,7 @@ xfs_attr_set_args(
 			return error;
 	}
 
-	error = xfs_attr_node_addname(args);
-	return error;
+	return xfs_attr_node_addname(args);
 }
 
 /*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 04/14] xfs: Separate xfs_attr_node_addname and xfs_attr_node_addname_clear_incomplete
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (2 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 03/14] xfs: Refactor xfs_attr_set_shortform Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 05/14] xfs: Add helper xfs_attr_node_addname_find_attr Allison Henderson
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch separate xfs_attr_node_addname into two functions.  This will
help to make it easier to hoist parts of xfs_attr_node_addname that need
state management

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_attr.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 0ec1547..ad44d77 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -54,6 +54,7 @@ STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
 STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
+STATIC int xfs_attr_node_addname_clear_incomplete(struct xfs_da_args *args);
 STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
 				 struct xfs_da_state **state);
 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
@@ -1073,6 +1074,28 @@ xfs_attr_node_addname(
 			return error;
 	}
 
+	error = xfs_attr_node_addname_clear_incomplete(args);
+	if (error)
+		goto out;
+	retval = 0;
+out:
+	if (state)
+		xfs_da_state_free(state);
+	if (error)
+		return error;
+	return retval;
+}
+
+
+STATIC int
+xfs_attr_node_addname_clear_incomplete(
+	struct xfs_da_args		*args)
+{
+	struct xfs_da_state		*state = NULL;
+	struct xfs_da_state_blk		*blk;
+	int				retval = 0;
+	int				error = 0;
+
 	/*
 	 * Re-find the "old" attribute entry after any split ops. The INCOMPLETE
 	 * flag means that we will find the "old" attr, not the "new" one.
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 05/14] xfs: Add helper xfs_attr_node_addname_find_attr
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (3 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 04/14] xfs: Separate xfs_attr_node_addname and xfs_attr_node_addname_clear_incomplete Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 06/14] xfs: Hoist xfs_attr_node_addname Allison Henderson
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch separates the first half of xfs_attr_node_addname into a
helper function xfs_attr_node_addname_find_attr.  It also replaces the
restart goto with an EAGAIN return code driven by a loop in the calling
function.  This looks odd now, but will clean up nicly once we introduce
the state machine.  It will also enable hoisting the last state out of
xfs_attr_node_addname with out having to plumb in a "done" parameter to
know if we need to move to the next state or not.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
---
 fs/xfs/libxfs/xfs_attr.c | 87 ++++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 33 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index ad44d77..5f56b05 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -52,7 +52,10 @@ STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
  * Internal routines when attribute list is more than one block.
  */
 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
-STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
+STATIC int xfs_attr_node_addname(struct xfs_da_args *args,
+				 struct xfs_da_state *state);
+STATIC int xfs_attr_node_addname_find_attr(struct xfs_da_args *args,
+				 struct xfs_da_state **state);
 STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_node_addname_clear_incomplete(struct xfs_da_args *args);
 STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
@@ -287,6 +290,7 @@ xfs_attr_set_args(
 	struct xfs_da_args	*args)
 {
 	struct xfs_inode	*dp = args->dp;
+	struct xfs_da_state     *state;
 	int			error;
 
 	/*
@@ -332,7 +336,14 @@ xfs_attr_set_args(
 			return error;
 	}
 
-	return xfs_attr_node_addname(args);
+	do {
+		error = xfs_attr_node_addname_find_attr(args, &state);
+		if (error)
+			return error;
+		error = xfs_attr_node_addname(args, state);
+	} while (error == -EAGAIN);
+
+	return error;
 }
 
 /*
@@ -896,48 +907,26 @@ xfs_attr_node_hasname(
  * External routines when attribute list size > geo->blksize
  *========================================================================*/
 
-/*
- * Add a name to a Btree-format attribute list.
- *
- * This will involve walking down the Btree, and may involve splitting
- * leaf nodes and even splitting intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
- *
- * "Remote" attribute values confuse the issue and atomic rename operations
- * add a whole extra layer of confusion on top of that.
- */
 STATIC int
-xfs_attr_node_addname(
-	struct xfs_da_args	*args)
+xfs_attr_node_addname_find_attr(
+	struct xfs_da_args	*args,
+	struct xfs_da_state     **state)
 {
-	struct xfs_da_state	*state;
-	struct xfs_da_state_blk	*blk;
-	struct xfs_inode	*dp;
-	int			retval, error;
-
-	trace_xfs_attr_node_addname(args);
+	int			retval;
 
 	/*
-	 * Fill in bucket of arguments/results/context to carry around.
-	 */
-	dp = args->dp;
-restart:
-	/*
 	 * Search to see if name already exists, and get back a pointer
 	 * to where it should go.
 	 */
-	error = 0;
-	retval = xfs_attr_node_hasname(args, &state);
+	retval = xfs_attr_node_hasname(args, state);
 	if (retval != -ENOATTR && retval != -EEXIST)
-		goto out;
+		goto error;
 
-	blk = &state->path.blk[ state->path.active-1 ];
-	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
 	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
-		goto out;
+		goto error;
 	if (retval == -EEXIST) {
 		if (args->attr_flags & XATTR_CREATE)
-			goto out;
+			goto error;
 
 		trace_xfs_attr_node_replace(args);
 
@@ -955,6 +944,38 @@ xfs_attr_node_addname(
 		args->rmtvaluelen = 0;
 	}
 
+	return 0;
+error:
+	if (*state)
+		xfs_da_state_free(*state);
+	return retval;
+}
+
+/*
+ * Add a name to a Btree-format attribute list.
+ *
+ * This will involve walking down the Btree, and may involve splitting
+ * leaf nodes and even splitting intermediate nodes up to and including
+ * the root node (a special case of an intermediate node).
+ *
+ * "Remote" attribute values confuse the issue and atomic rename operations
+ * add a whole extra layer of confusion on top of that.
+ */
+STATIC int
+xfs_attr_node_addname(
+	struct xfs_da_args	*args,
+	struct xfs_da_state	*state)
+{
+	struct xfs_da_state_blk	*blk;
+	struct xfs_inode	*dp;
+	int			retval, error;
+
+	trace_xfs_attr_node_addname(args);
+
+	dp = args->dp;
+	blk = &state->path.blk[state->path.active-1];
+	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
+
 	retval = xfs_attr3_leaf_add(blk->bp, state->args);
 	if (retval == -ENOSPC) {
 		if (state->path.active == 1) {
@@ -980,7 +1001,7 @@ xfs_attr_node_addname(
 			if (error)
 				goto out;
 
-			goto restart;
+			return -EAGAIN;
 		}
 
 		/*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 06/14] xfs: Hoist xfs_attr_node_addname
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (4 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 05/14] xfs: Add helper xfs_attr_node_addname_find_attr Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 07/14] xfs: Hoist xfs_attr_leaf_addname Allison Henderson
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch hoists the later half of xfs_attr_node_addname into
the calling function.  We do this because it is this area that
will need the most state management, and we want to keep such
code in the same scope as much as possible

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
---
 fs/xfs/libxfs/xfs_attr.c | 159 ++++++++++++++++++++++-------------------------
 1 file changed, 75 insertions(+), 84 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 5f56b05..b35c742 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -52,6 +52,7 @@ STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
  * Internal routines when attribute list is more than one block.
  */
 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
+STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
 STATIC int xfs_attr_node_addname(struct xfs_da_args *args,
 				 struct xfs_da_state *state);
 STATIC int xfs_attr_node_addname_find_attr(struct xfs_da_args *args,
@@ -290,8 +291,8 @@ xfs_attr_set_args(
 	struct xfs_da_args	*args)
 {
 	struct xfs_inode	*dp = args->dp;
-	struct xfs_da_state     *state;
-	int			error;
+	struct xfs_da_state     *state = NULL;
+	int			error = 0;
 
 	/*
 	 * If the attribute list is already in leaf format, jump straight to
@@ -342,7 +343,75 @@ xfs_attr_set_args(
 			return error;
 		error = xfs_attr_node_addname(args, state);
 	} while (error == -EAGAIN);
+	if (error)
+		return error;
 
+	/*
+	 * Commit the leaf addition or btree split and start the next
+	 * trans in the chain.
+	 */
+	error = xfs_trans_roll_inode(&args->trans, dp);
+	if (error)
+		goto out;
+
+	/*
+	 * If there was an out-of-line value, allocate the blocks we
+	 * identified for its storage and copy the value.  This is done
+	 * after we create the attribute so that we don't overflow the
+	 * maximum size of a transaction and/or hit a deadlock.
+	 */
+	if (args->rmtblkno > 0) {
+		error = xfs_attr_rmtval_set(args);
+		if (error)
+			return error;
+	}
+
+	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
+		/*
+		 * Added a "remote" value, just clear the incomplete flag.
+		 */
+		if (args->rmtblkno > 0)
+			error = xfs_attr3_leaf_clearflag(args);
+		goto out;
+	}
+
+	/*
+	 * If this is an atomic rename operation, we must "flip" the incomplete
+	 * flags on the "new" and "old" attribute/value pairs so that one
+	 * disappears and one appears atomically.  Then we must remove the "old"
+	 * attribute/value pair.
+	 *
+	 * In a separate transaction, set the incomplete flag on the "old" attr
+	 * and clear the incomplete flag on the "new" attr.
+	 */
+	error = xfs_attr3_leaf_flipflags(args);
+	if (error)
+		goto out;
+	/*
+	 * Commit the flag value change and start the next trans in series
+	 */
+	error = xfs_trans_roll_inode(&args->trans, args->dp);
+	if (error)
+		goto out;
+
+	/*
+	 * Dismantle the "old" attribute/value pair by removing a "remote" value
+	 * (if it exists).
+	 */
+	xfs_attr_restore_rmt_blk(args);
+
+	if (args->rmtblkno) {
+		error = xfs_attr_rmtval_invalidate(args);
+		if (error)
+			return error;
+
+		error = xfs_attr_rmtval_remove(args);
+		if (error)
+			return error;
+	}
+
+	error = xfs_attr_node_addname_clear_incomplete(args);
+out:
 	return error;
 }
 
@@ -968,7 +1037,7 @@ xfs_attr_node_addname(
 {
 	struct xfs_da_state_blk	*blk;
 	struct xfs_inode	*dp;
-	int			retval, error;
+	int			error;
 
 	trace_xfs_attr_node_addname(args);
 
@@ -976,8 +1045,8 @@ xfs_attr_node_addname(
 	blk = &state->path.blk[state->path.active-1];
 	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
 
-	retval = xfs_attr3_leaf_add(blk->bp, state->args);
-	if (retval == -ENOSPC) {
+	error = xfs_attr3_leaf_add(blk->bp, state->args);
+	if (error == -ENOSPC) {
 		if (state->path.active == 1) {
 			/*
 			 * Its really a single leaf node, but it had
@@ -1023,88 +1092,10 @@ xfs_attr_node_addname(
 		xfs_da3_fixhashpath(state, &state->path);
 	}
 
-	/*
-	 * Kill the state structure, we're done with it and need to
-	 * allow the buffers to come back later.
-	 */
-	xfs_da_state_free(state);
-	state = NULL;
-
-	/*
-	 * Commit the leaf addition or btree split and start the next
-	 * trans in the chain.
-	 */
-	error = xfs_trans_roll_inode(&args->trans, dp);
-	if (error)
-		goto out;
-
-	/*
-	 * If there was an out-of-line value, allocate the blocks we
-	 * identified for its storage and copy the value.  This is done
-	 * after we create the attribute so that we don't overflow the
-	 * maximum size of a transaction and/or hit a deadlock.
-	 */
-	if (args->rmtblkno > 0) {
-		error = xfs_attr_rmtval_set(args);
-		if (error)
-			return error;
-	}
-
-	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
-		/*
-		 * Added a "remote" value, just clear the incomplete flag.
-		 */
-		if (args->rmtblkno > 0)
-			error = xfs_attr3_leaf_clearflag(args);
-		retval = error;
-		goto out;
-	}
-
-	/*
-	 * If this is an atomic rename operation, we must "flip" the incomplete
-	 * flags on the "new" and "old" attribute/value pairs so that one
-	 * disappears and one appears atomically.  Then we must remove the "old"
-	 * attribute/value pair.
-	 *
-	 * In a separate transaction, set the incomplete flag on the "old" attr
-	 * and clear the incomplete flag on the "new" attr.
-	 */
-	error = xfs_attr3_leaf_flipflags(args);
-	if (error)
-		goto out;
-	/*
-	 * Commit the flag value change and start the next trans in series
-	 */
-	error = xfs_trans_roll_inode(&args->trans, args->dp);
-	if (error)
-		goto out;
-
-	/*
-	 * Dismantle the "old" attribute/value pair by removing a "remote" value
-	 * (if it exists).
-	 */
-	xfs_attr_restore_rmt_blk(args);
-
-	if (args->rmtblkno) {
-		error = xfs_attr_rmtval_invalidate(args);
-		if (error)
-			return error;
-
-		error = xfs_attr_rmtval_remove(args);
-		if (error)
-			return error;
-	}
-
-	error = xfs_attr_node_addname_clear_incomplete(args);
-	if (error)
-		goto out;
-	retval = 0;
 out:
 	if (state)
 		xfs_da_state_free(state);
-	if (error)
-		return error;
-	return retval;
+	return error;
 }
 
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 07/14] xfs: Hoist xfs_attr_leaf_addname
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (5 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 06/14] xfs: Hoist xfs_attr_node_addname Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 08/14] xfs: Hoist node transaction handling Allison Henderson
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch hoists xfs_attr_leaf_addname into the calling function.  The
goal being to get all the code that will require state management into
the same scope. This isn't particularly aesthetic right away, but it is a
preliminary step to merging in the state machine code.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
---
 fs/xfs/libxfs/xfs_attr.c | 209 ++++++++++++++++++++++-------------------------
 fs/xfs/xfs_trace.h       |   1 -
 2 files changed, 96 insertions(+), 114 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index b35c742..4bbf34c 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -44,9 +44,9 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
  * Internal routines when attribute list is one block.
  */
 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
-STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
+STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args, struct xfs_buf *bp);
 
 /*
  * Internal routines when attribute list is more than one block.
@@ -291,8 +291,9 @@ xfs_attr_set_args(
 	struct xfs_da_args	*args)
 {
 	struct xfs_inode	*dp = args->dp;
+	struct xfs_buf		*bp = NULL;
 	struct xfs_da_state     *state = NULL;
-	int			error = 0;
+	int			forkoff, error = 0;
 
 	/*
 	 * If the attribute list is already in leaf format, jump straight to
@@ -307,10 +308,101 @@ xfs_attr_set_args(
 	}
 
 	if (xfs_attr_is_leaf(dp)) {
-		error = xfs_attr_leaf_addname(args);
-		if (error != -ENOSPC)
+		error = xfs_attr_leaf_try_add(args, bp);
+		if (error == -ENOSPC)
+			goto node;
+		else if (error)
+			return error;
+
+		/*
+		 * Commit the transaction that added the attr name so that
+		 * later routines can manage their own transactions.
+		 */
+		error = xfs_trans_roll_inode(&args->trans, dp);
+		if (error)
+			return error;
+
+		/*
+		 * If there was an out-of-line value, allocate the blocks we
+		 * identified for its storage and copy the value.  This is done
+		 * after we create the attribute so that we don't overflow the
+		 * maximum size of a transaction and/or hit a deadlock.
+		 */
+		if (args->rmtblkno > 0) {
+			error = xfs_attr_rmtval_set(args);
+			if (error)
+				return error;
+		}
+
+		if (!(args->op_flags & XFS_DA_OP_RENAME)) {
+			/*
+			 * Added a "remote" value, just clear the incomplete
+			 *flag.
+			 */
+			if (args->rmtblkno > 0)
+				error = xfs_attr3_leaf_clearflag(args);
+
+			return error;
+		}
+
+		/*
+		 * If this is an atomic rename operation, we must "flip" the
+		 * incomplete flags on the "new" and "old" attribute/value pairs
+		 * so that one disappears and one appears atomically.  Then we
+		 * must remove the "old" attribute/value pair.
+		 *
+		 * In a separate transaction, set the incomplete flag on the
+		 * "old" attr and clear the incomplete flag on the "new" attr.
+		 */
+
+		error = xfs_attr3_leaf_flipflags(args);
+		if (error)
+			return error;
+		/*
+		 * Commit the flag value change and start the next trans in
+		 * series.
+		 */
+		error = xfs_trans_roll_inode(&args->trans, args->dp);
+		if (error)
+			return error;
+
+		/*
+		 * Dismantle the "old" attribute/value pair by removing a
+		 * "remote" value (if it exists).
+		 */
+		xfs_attr_restore_rmt_blk(args);
+
+		if (args->rmtblkno) {
+			error = xfs_attr_rmtval_invalidate(args);
+			if (error)
+				return error;
+
+			error = xfs_attr_rmtval_remove(args);
+			if (error)
+				return error;
+		}
+
+		/*
+		 * Read in the block containing the "old" attr, then remove the
+		 * "old" attr from that block (neat, huh!)
+		 */
+		error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
+					   &bp);
+		if (error)
 			return error;
 
+		xfs_attr3_leaf_remove(bp, args);
+
+		/*
+		 * If the result is small enough, shrink it all into the inode.
+		 */
+		forkoff = xfs_attr_shortform_allfit(bp, dp);
+		if (forkoff)
+			error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
+			/* bp is gone due to xfs_da_shrink_inode */
+
+		return error;
+node:
 		/*
 		 * Promote the attribute list to the Btree format.
 		 */
@@ -737,115 +829,6 @@ xfs_attr_leaf_try_add(
 	return retval;
 }
 
-
-/*
- * Add a name to the leaf attribute list structure
- *
- * This leaf block cannot have a "remote" value, we only call this routine
- * if bmap_one_block() says there is only one block (ie: no remote blks).
- */
-STATIC int
-xfs_attr_leaf_addname(
-	struct xfs_da_args	*args)
-{
-	int			error, forkoff;
-	struct xfs_buf		*bp = NULL;
-	struct xfs_inode	*dp = args->dp;
-
-	trace_xfs_attr_leaf_addname(args);
-
-	error = xfs_attr_leaf_try_add(args, bp);
-	if (error)
-		return error;
-
-	/*
-	 * Commit the transaction that added the attr name so that
-	 * later routines can manage their own transactions.
-	 */
-	error = xfs_trans_roll_inode(&args->trans, dp);
-	if (error)
-		return error;
-
-	/*
-	 * If there was an out-of-line value, allocate the blocks we
-	 * identified for its storage and copy the value.  This is done
-	 * after we create the attribute so that we don't overflow the
-	 * maximum size of a transaction and/or hit a deadlock.
-	 */
-	if (args->rmtblkno > 0) {
-		error = xfs_attr_rmtval_set(args);
-		if (error)
-			return error;
-	}
-
-	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
-		/*
-		 * Added a "remote" value, just clear the incomplete flag.
-		 */
-		if (args->rmtblkno > 0)
-			error = xfs_attr3_leaf_clearflag(args);
-
-		return error;
-	}
-
-	/*
-	 * If this is an atomic rename operation, we must "flip" the incomplete
-	 * flags on the "new" and "old" attribute/value pairs so that one
-	 * disappears and one appears atomically.  Then we must remove the "old"
-	 * attribute/value pair.
-	 *
-	 * In a separate transaction, set the incomplete flag on the "old" attr
-	 * and clear the incomplete flag on the "new" attr.
-	 */
-
-	error = xfs_attr3_leaf_flipflags(args);
-	if (error)
-		return error;
-	/*
-	 * Commit the flag value change and start the next trans in series.
-	 */
-	error = xfs_trans_roll_inode(&args->trans, args->dp);
-	if (error)
-		return error;
-
-	/*
-	 * Dismantle the "old" attribute/value pair by removing a "remote" value
-	 * (if it exists).
-	 */
-	xfs_attr_restore_rmt_blk(args);
-
-	if (args->rmtblkno) {
-		error = xfs_attr_rmtval_invalidate(args);
-		if (error)
-			return error;
-
-		error = xfs_attr_rmtval_remove(args);
-		if (error)
-			return error;
-	}
-
-	/*
-	 * Read in the block containing the "old" attr, then remove the "old"
-	 * attr from that block (neat, huh!)
-	 */
-	error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
-				   &bp);
-	if (error)
-		return error;
-
-	xfs_attr3_leaf_remove(bp, args);
-
-	/*
-	 * If the result is small enough, shrink it all into the inode.
-	 */
-	forkoff = xfs_attr_shortform_allfit(bp, dp);
-	if (forkoff)
-		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
-		/* bp is gone due to xfs_da_shrink_inode */
-
-	return error;
-}
-
 /*
  * Return EEXIST if attr is found, or ENOATTR if not
  */
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 808ae33..3c1c830 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -1914,7 +1914,6 @@ DEFINE_ATTR_EVENT(xfs_attr_leaf_add);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_add_old);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_add_new);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_add_work);
-DEFINE_ATTR_EVENT(xfs_attr_leaf_addname);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_create);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_compact);
 DEFINE_ATTR_EVENT(xfs_attr_leaf_get);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 08/14] xfs: Hoist node transaction handling
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (6 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 07/14] xfs: Hoist xfs_attr_leaf_addname Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:54 ` [PATCH v19 09/14] xfs: Add delay ready attr remove routines Allison Henderson
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch basically hoists the node transaction handling around the
leaf code we just hoisted.  This will helps setup this area for the
state machine since the goto is easily replaced with a state since it
ends with a transaction roll.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
---
 fs/xfs/libxfs/xfs_attr.c | 55 +++++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 4bbf34c..812dd1a 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -309,10 +309,36 @@ xfs_attr_set_args(
 
 	if (xfs_attr_is_leaf(dp)) {
 		error = xfs_attr_leaf_try_add(args, bp);
-		if (error == -ENOSPC)
+		if (error == -ENOSPC) {
+			/*
+			 * Promote the attribute list to the Btree format.
+			 */
+			error = xfs_attr3_leaf_to_node(args);
+			if (error)
+				return error;
+
+			/*
+			 * Finish any deferred work items and roll the transaction once
+			 * more.  The goal here is to call node_addname with the inode
+			 * and transaction in the same state (inode locked and joined,
+			 * transaction clean) no matter how we got to this step.
+			 */
+			error = xfs_defer_finish(&args->trans);
+			if (error)
+				return error;
+
+			/*
+			 * Commit the current trans (including the inode) and
+			 * start a new one.
+			 */
+			error = xfs_trans_roll_inode(&args->trans, dp);
+			if (error)
+				return error;
+
 			goto node;
-		else if (error)
+		} else if (error) {
 			return error;
+		}
 
 		/*
 		 * Commit the transaction that added the attr name so that
@@ -402,32 +428,9 @@ xfs_attr_set_args(
 			/* bp is gone due to xfs_da_shrink_inode */
 
 		return error;
+	}
 node:
-		/*
-		 * Promote the attribute list to the Btree format.
-		 */
-		error = xfs_attr3_leaf_to_node(args);
-		if (error)
-			return error;
-
-		/*
-		 * Finish any deferred work items and roll the transaction once
-		 * more.  The goal here is to call node_addname with the inode
-		 * and transaction in the same state (inode locked and joined,
-		 * transaction clean) no matter how we got to this step.
-		 */
-		error = xfs_defer_finish(&args->trans);
-		if (error)
-			return error;
 
-		/*
-		 * Commit the current trans (including the inode) and
-		 * start a new one.
-		 */
-		error = xfs_trans_roll_inode(&args->trans, dp);
-		if (error)
-			return error;
-	}
 
 	do {
 		error = xfs_attr_node_addname_find_attr(args, &state);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 09/14] xfs: Add delay ready attr remove routines
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (7 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 08/14] xfs: Hoist node transaction handling Allison Henderson
@ 2021-05-25 19:54 ` Allison Henderson
  2021-05-25 19:55 ` [PATCH v19 10/14] xfs: Add delay ready attr set routines Allison Henderson
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:54 UTC (permalink / raw)
  To: linux-xfs

This patch modifies the attr remove routines to be delay ready. This
means they no longer roll or commit transactions, but instead return
-EAGAIN to have the calling routine roll and refresh the transaction. In
this series, xfs_attr_remove_args is merged with
xfs_attr_node_removename become a new function, xfs_attr_remove_iter.
This new version uses a sort of state machine like switch to keep track
of where it was when EAGAIN was returned. A new version of
xfs_attr_remove_args consists of a simple loop to refresh the
transaction until the operation is completed. A new XFS_DAC_DEFER_FINISH
flag is used to finish the transaction where ever the existing code used
to.

Calls to xfs_attr_rmtval_remove are replaced with the delay ready
version __xfs_attr_rmtval_remove. We will rename
__xfs_attr_rmtval_remove back to xfs_attr_rmtval_remove when we are
done.

xfs_attr_rmtval_remove itself is still in use by the set routines (used
during a rename).  For reasons of preserving existing function, we
modify xfs_attr_rmtval_remove to call xfs_defer_finish when the flag is
set.  Similar to how xfs_attr_remove_args does here.  Once we transition
the set routines to be delay ready, xfs_attr_rmtval_remove is no longer
used and will be removed.

This patch also adds a new struct xfs_delattr_context, which we will use
to keep track of the current state of an attribute operation. The new
xfs_delattr_state enum is used to track various operations that are in
progress so that we know not to repeat them, and resume where we left
off before EAGAIN was returned to cycle out the transaction. Other
members take the place of local variables that need to retain their
values across multiple function calls.  See xfs_attr.h for a more
detailed diagram of the states.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_attr.c        | 213 ++++++++++++++++++++++++++++------------
 fs/xfs/libxfs/xfs_attr.h        | 131 ++++++++++++++++++++++++
 fs/xfs/libxfs/xfs_attr_leaf.c   |   2 +-
 fs/xfs/libxfs/xfs_attr_remote.c |  49 +++++----
 fs/xfs/libxfs/xfs_attr_remote.h |   2 +-
 fs/xfs/xfs_attr_inactive.c      |   2 +-
 6 files changed, 314 insertions(+), 85 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 812dd1a..088f622 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -57,7 +57,6 @@ STATIC int xfs_attr_node_addname(struct xfs_da_args *args,
 				 struct xfs_da_state *state);
 STATIC int xfs_attr_node_addname_find_attr(struct xfs_da_args *args,
 				 struct xfs_da_state **state);
-STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_node_addname_clear_incomplete(struct xfs_da_args *args);
 STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
 				 struct xfs_da_state **state);
@@ -241,6 +240,31 @@ xfs_attr_is_shortform(
 		ip->i_afp->if_nextents == 0);
 }
 
+/*
+ * Checks to see if a delayed attribute transaction should be rolled.  If so,
+ * transaction is finished or rolled as needed.
+ */
+int
+xfs_attr_trans_roll(
+	struct xfs_delattr_context	*dac)
+{
+	struct xfs_da_args		*args = dac->da_args;
+	int				error;
+
+	if (dac->flags & XFS_DAC_DEFER_FINISH) {
+		/*
+		 * The caller wants us to finish all the deferred ops so that we
+		 * avoid pinning the log tail with a large number of deferred
+		 * ops.
+		 */
+		dac->flags &= ~XFS_DAC_DEFER_FINISH;
+		error = xfs_defer_finish(&args->trans);
+	} else
+		error = xfs_trans_roll_inode(&args->trans, args->dp);
+
+	return error;
+}
+
 STATIC int
 xfs_attr_set_fmt(
 	struct xfs_da_args	*args)
@@ -544,16 +568,25 @@ xfs_has_attr(
  */
 int
 xfs_attr_remove_args(
-	struct xfs_da_args      *args)
+	struct xfs_da_args	*args)
 {
-	if (!xfs_inode_hasattr(args->dp))
-		return -ENOATTR;
+	int				error;
+	struct xfs_delattr_context	dac = {
+		.da_args	= args,
+	};
 
-	if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
-		return xfs_attr_shortform_remove(args);
-	if (xfs_attr_is_leaf(args->dp))
-		return xfs_attr_leaf_removename(args);
-	return xfs_attr_node_removename(args);
+	do {
+		error = xfs_attr_remove_iter(&dac);
+		if (error != -EAGAIN)
+			break;
+
+		error = xfs_attr_trans_roll(&dac);
+		if (error)
+			return error;
+
+	} while (true);
+
+	return error;
 }
 
 /*
@@ -1197,14 +1230,16 @@ xfs_attr_leaf_mark_incomplete(
  */
 STATIC
 int xfs_attr_node_removename_setup(
-	struct xfs_da_args	*args,
-	struct xfs_da_state	**state)
+	struct xfs_delattr_context	*dac)
 {
-	int			error;
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_da_state		**state = &dac->da_state;
+	int				error;
 
 	error = xfs_attr_node_hasname(args, state);
 	if (error != -EEXIST)
 		return error;
+	error = 0;
 
 	ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
 	ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
@@ -1213,12 +1248,15 @@ int xfs_attr_node_removename_setup(
 	if (args->rmtblkno > 0) {
 		error = xfs_attr_leaf_mark_incomplete(args, *state);
 		if (error)
-			return error;
+			goto out;
 
-		return xfs_attr_rmtval_invalidate(args);
+		error = xfs_attr_rmtval_invalidate(args);
 	}
+out:
+	if (error)
+		xfs_da_state_free(*state);
 
-	return 0;
+	return error;
 }
 
 STATIC int
@@ -1241,70 +1279,123 @@ xfs_attr_node_remove_name(
 }
 
 /*
- * Remove a name from a B-tree attribute list.
+ * Remove the attribute specified in @args.
  *
  * This will involve walking down the Btree, and may involve joining
  * leaf nodes and even joining intermediate nodes up to and including
  * the root node (a special case of an intermediate node).
+ *
+ * This routine is meant to function as either an in-line or delayed operation,
+ * and may return -EAGAIN when the transaction needs to be rolled.  Calling
+ * functions will need to handle this, and call the function until a
+ * successful error code is returned.
  */
-STATIC int
-xfs_attr_node_removename(
-	struct xfs_da_args	*args)
+int
+xfs_attr_remove_iter(
+	struct xfs_delattr_context	*dac)
 {
-	struct xfs_da_state	*state;
-	int			retval, error;
-	struct xfs_inode	*dp = args->dp;
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_da_state		*state = dac->da_state;
+	int				retval, error;
+	struct xfs_inode		*dp = args->dp;
 
 	trace_xfs_attr_node_removename(args);
 
-	error = xfs_attr_node_removename_setup(args, &state);
-	if (error)
-		goto out;
+	switch (dac->dela_state) {
+	case XFS_DAS_UNINIT:
+		if (!xfs_inode_hasattr(dp))
+			return -ENOATTR;
 
-	/*
-	 * If there is an out-of-line value, de-allocate the blocks.
-	 * This is done before we remove the attribute so that we don't
-	 * overflow the maximum size of a transaction and/or hit a deadlock.
-	 */
-	if (args->rmtblkno > 0) {
-		error = xfs_attr_rmtval_remove(args);
-		if (error)
-			goto out;
+		/*
+		 * Shortform or leaf formats don't require transaction rolls and
+		 * thus state transitions. Call the right helper and return.
+		 */
+		if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
+			return xfs_attr_shortform_remove(args);
+
+		if (xfs_attr_is_leaf(dp))
+			return xfs_attr_leaf_removename(args);
 
 		/*
-		 * Refill the state structure with buffers, the prior calls
-		 * released our buffers.
+		 * Node format may require transaction rolls. Set up the
+		 * state context and fall into the state machine.
 		 */
-		error = xfs_attr_refillstate(state);
-		if (error)
-			goto out;
-	}
-	retval = xfs_attr_node_remove_name(args, state);
+		if (!dac->da_state) {
+			error = xfs_attr_node_removename_setup(dac);
+			if (error)
+				return error;
+			state = dac->da_state;
+		}
+
+		/* fallthrough */
+	case XFS_DAS_RMTBLK:
+		dac->dela_state = XFS_DAS_RMTBLK;
 
-	/*
-	 * Check to see if the tree needs to be collapsed.
-	 */
-	if (retval && (state->path.active > 1)) {
-		error = xfs_da3_join(state);
-		if (error)
-			goto out;
-		error = xfs_defer_finish(&args->trans);
-		if (error)
-			goto out;
 		/*
-		 * Commit the Btree join operation and start a new trans.
+		 * If there is an out-of-line value, de-allocate the blocks.
+		 * This is done before we remove the attribute so that we don't
+		 * overflow the maximum size of a transaction and/or hit a
+		 * deadlock.
 		 */
-		error = xfs_trans_roll_inode(&args->trans, dp);
-		if (error)
-			goto out;
-	}
+		if (args->rmtblkno > 0) {
+			/*
+			 * May return -EAGAIN. Roll and repeat until all remote
+			 * blocks are removed.
+			 */
+			error = __xfs_attr_rmtval_remove(dac);
+			if (error == -EAGAIN)
+				return error;
+			else if (error)
+				goto out;
 
-	/*
-	 * If the result is small enough, push it all into the inode.
-	 */
-	if (xfs_attr_is_leaf(dp))
-		error = xfs_attr_node_shrink(args, state);
+			/*
+			 * Refill the state structure with buffers (the prior
+			 * calls released our buffers) and close out this
+			 * transaction before proceeding.
+			 */
+			ASSERT(args->rmtblkno == 0);
+			error = xfs_attr_refillstate(state);
+			if (error)
+				goto out;
+			dac->dela_state = XFS_DAS_RM_NAME;
+			dac->flags |= XFS_DAC_DEFER_FINISH;
+			return -EAGAIN;
+		}
+
+		/* fallthrough */
+	case XFS_DAS_RM_NAME:
+		retval = xfs_attr_node_remove_name(args, state);
 
+		/*
+		 * Check to see if the tree needs to be collapsed. If so, roll
+		 * the transacton and fall into the shrink state.
+		 */
+		if (retval && (state->path.active > 1)) {
+			error = xfs_da3_join(state);
+			if (error)
+				goto out;
+
+			dac->flags |= XFS_DAC_DEFER_FINISH;
+			dac->dela_state = XFS_DAS_RM_SHRINK;
+			return -EAGAIN;
+		}
+
+		/* fallthrough */
+	case XFS_DAS_RM_SHRINK:
+		/*
+		 * If the result is small enough, push it all into the inode.
+		 * This is our final state so it's safe to return a dirty
+		 * transaction.
+		 */
+		if (xfs_attr_is_leaf(dp))
+			error = xfs_attr_node_shrink(args, state);
+		ASSERT(error != -EAGAIN);
+		break;
+	default:
+		ASSERT(0);
+		error = -EINVAL;
+		goto out;
+	}
 out:
 	if (state)
 		xfs_da_state_free(state);
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 2b1f619..1267ea8 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -74,6 +74,133 @@ struct xfs_attr_list_context {
 };
 
 
+/*
+ * ========================================================================
+ * Structure used to pass context around among the delayed routines.
+ * ========================================================================
+ */
+
+/*
+ * Below is a state machine diagram for attr remove operations. The  XFS_DAS_*
+ * states indicate places where the function would return -EAGAIN, and then
+ * immediately resume from after being called by the calling function. States
+ * marked as a "subroutine state" indicate that they belong to a subroutine, and
+ * so the calling function needs to pass them back to that subroutine to allow
+ * it to finish where it left off. But they otherwise do not have a role in the
+ * calling function other than just passing through.
+ *
+ * xfs_attr_remove_iter()
+ *              │
+ *              v
+ *        have attr to remove? ──n──> done
+ *              │
+ *              y
+ *              │
+ *              v
+ *        are we short form? ──y──> xfs_attr_shortform_remove ──> done
+ *              │
+ *              n
+ *              │
+ *              V
+ *        are we leaf form? ──y──> xfs_attr_leaf_removename ──> done
+ *              │
+ *              n
+ *              │
+ *              V
+ *   ┌── need to setup state?
+ *   │          │
+ *   n          y
+ *   │          │
+ *   │          v
+ *   │ find attr and get state
+ *   │ attr has remote blks? ──n─┐
+ *   │          │                v
+ *   │          │         find and invalidate
+ *   │          y         the remote blocks.
+ *   │          │         mark attr incomplete
+ *   │          ├────────────────┘
+ *   └──────────┤
+ *              │
+ *              v
+ *   Have remote blks to remove? ───y─────┐
+ *              │        ^          remove the blks
+ *              │        │                │
+ *              │        │                v
+ *              │  XFS_DAS_RMTBLK <─n── done?
+ *              │  re-enter with          │
+ *              │  one less blk to        y
+ *              │      remove             │
+ *              │                         V
+ *              │                  refill the state
+ *              n                         │
+ *              │                         v
+ *              │                   XFS_DAS_RM_NAME
+ *              │                         │
+ *              ├─────────────────────────┘
+ *              │
+ *              v
+ *       remove leaf and
+ *       update hash with
+ *   xfs_attr_node_remove_cleanup
+ *              │
+ *              v
+ *           need to
+ *        shrink tree? ─n─┐
+ *              │         │
+ *              y         │
+ *              │         │
+ *              v         │
+ *          join leaf     │
+ *              │         │
+ *              v         │
+ *      XFS_DAS_RM_SHRINK │
+ *              │         │
+ *              v         │
+ *       do the shrink    │
+ *              │         │
+ *              v         │
+ *          free state <──┘
+ *              │
+ *              v
+ *            done
+ *
+ */
+
+/*
+ * Enum values for xfs_delattr_context.da_state
+ *
+ * These values are used by delayed attribute operations to keep track  of where
+ * they were before they returned -EAGAIN.  A return code of -EAGAIN signals the
+ * calling function to roll the transaction, and then call the subroutine to
+ * finish the operation.  The enum is then used by the subroutine to jump back
+ * to where it was and resume executing where it left off.
+ */
+enum xfs_delattr_state {
+	XFS_DAS_UNINIT		= 0,  /* No state has been set yet */
+	XFS_DAS_RMTBLK,		      /* Removing remote blks */
+	XFS_DAS_RM_NAME,	      /* Remove attr name */
+	XFS_DAS_RM_SHRINK,	      /* We are shrinking the tree */
+};
+
+/*
+ * Defines for xfs_delattr_context.flags
+ */
+#define XFS_DAC_DEFER_FINISH		0x01 /* finish the transaction */
+
+/*
+ * Context used for keeping track of delayed attribute operations
+ */
+struct xfs_delattr_context {
+	struct xfs_da_args      *da_args;
+
+	/* Used in xfs_attr_node_removename to roll through removing blocks */
+	struct xfs_da_state     *da_state;
+
+	/* Used to keep track of current state of delayed operation */
+	unsigned int            flags;
+	enum xfs_delattr_state  dela_state;
+};
+
 /*========================================================================
  * Function prototypes for the kernel.
  *========================================================================*/
@@ -92,6 +219,10 @@ int xfs_attr_set(struct xfs_da_args *args);
 int xfs_attr_set_args(struct xfs_da_args *args);
 int xfs_has_attr(struct xfs_da_args *args);
 int xfs_attr_remove_args(struct xfs_da_args *args);
+int xfs_attr_remove_iter(struct xfs_delattr_context *dac);
+int xfs_attr_trans_roll(struct xfs_delattr_context *dac);
 bool xfs_attr_namecheck(const void *name, size_t length);
+void xfs_delattr_context_init(struct xfs_delattr_context *dac,
+			      struct xfs_da_args *args);
 
 #endif	/* __XFS_ATTR_H__ */
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 556184b..d97de20 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -19,8 +19,8 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_bmap.h"
 #include "xfs_attr_sf.h"
-#include "xfs_attr_remote.h"
 #include "xfs_attr.h"
+#include "xfs_attr_remote.h"
 #include "xfs_attr_leaf.h"
 #include "xfs_error.h"
 #include "xfs_trace.h"
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index 48d8e9c..ada8254 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -674,10 +674,12 @@ xfs_attr_rmtval_invalidate(
  */
 int
 xfs_attr_rmtval_remove(
-	struct xfs_da_args      *args)
+	struct xfs_da_args		*args)
 {
-	int			error;
-	int			retval;
+	int				error;
+	struct xfs_delattr_context	dac  = {
+		.da_args	= args,
+	};
 
 	trace_xfs_attr_rmtval_remove(args);
 
@@ -685,31 +687,30 @@ xfs_attr_rmtval_remove(
 	 * Keep de-allocating extents until the remote-value region is gone.
 	 */
 	do {
-		retval = __xfs_attr_rmtval_remove(args);
-		if (retval && retval != -EAGAIN)
-			return retval;
+		error = __xfs_attr_rmtval_remove(&dac);
+		if (error && error != -EAGAIN)
+			break;
 
-		/*
-		 * Close out trans and start the next one in the chain.
-		 */
-		error = xfs_trans_roll_inode(&args->trans, args->dp);
+		error = xfs_attr_trans_roll(&dac);
 		if (error)
 			return error;
-	} while (retval == -EAGAIN);
+	} while (true);
 
-	return 0;
+	return error;
 }
 
 /*
  * Remove the value associated with an attribute by deleting the out-of-line
- * buffer that it is stored on. Returns EAGAIN for the caller to refresh the
- * transaction and re-call the function
+ * buffer that it is stored on. Returns -EAGAIN for the caller to refresh the
+ * transaction and re-call the function.  Callers should keep calling this
+ * routine until it returns something other than -EAGAIN.
  */
 int
 __xfs_attr_rmtval_remove(
-	struct xfs_da_args	*args)
+	struct xfs_delattr_context	*dac)
 {
-	int			error, done;
+	struct xfs_da_args		*args = dac->da_args;
+	int				error, done;
 
 	/*
 	 * Unmap value blocks for this attr.
@@ -719,12 +720,18 @@ __xfs_attr_rmtval_remove(
 	if (error)
 		return error;
 
-	error = xfs_defer_finish(&args->trans);
-	if (error)
-		return error;
-
-	if (!done)
+	/*
+	 * We don't need an explicit state here to pick up where we left off. We
+	 * can figure it out using the !done return code. The actual value of
+	 * attr->xattri_dela_state may be some value reminiscent of the calling
+	 * function, but it's value is irrelevant with in the context of this
+	 * function. Once we are done here, the next state is set as needed by
+	 * the parent
+	 */
+	if (!done) {
+		dac->flags |= XFS_DAC_DEFER_FINISH;
 		return -EAGAIN;
+	}
 
 	return error;
 }
diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h
index 9eee615..002fd30 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.h
+++ b/fs/xfs/libxfs/xfs_attr_remote.h
@@ -14,5 +14,5 @@ int xfs_attr_rmtval_remove(struct xfs_da_args *args);
 int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
 		xfs_buf_flags_t incore_flags);
 int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);
-int __xfs_attr_rmtval_remove(struct xfs_da_args *args);
+int __xfs_attr_rmtval_remove(struct xfs_delattr_context *dac);
 #endif /* __XFS_ATTR_REMOTE_H__ */
diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c
index bfad669..aaa7e66 100644
--- a/fs/xfs/xfs_attr_inactive.c
+++ b/fs/xfs/xfs_attr_inactive.c
@@ -15,10 +15,10 @@
 #include "xfs_da_format.h"
 #include "xfs_da_btree.h"
 #include "xfs_inode.h"
+#include "xfs_attr.h"
 #include "xfs_attr_remote.h"
 #include "xfs_trans.h"
 #include "xfs_bmap.h"
-#include "xfs_attr.h"
 #include "xfs_attr_leaf.h"
 #include "xfs_quota.h"
 #include "xfs_dir2.h"
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 10/14] xfs: Add delay ready attr set routines
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (8 preceding siblings ...)
  2021-05-25 19:54 ` [PATCH v19 09/14] xfs: Add delay ready attr remove routines Allison Henderson
@ 2021-05-25 19:55 ` Allison Henderson
  2021-05-25 19:55 ` [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set Allison Henderson
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:55 UTC (permalink / raw)
  To: linux-xfs

This patch modifies the attr set routines to be delay ready. This means
they no longer roll or commit transactions, but instead return -EAGAIN
to have the calling routine roll and refresh the transaction.  In this
series, xfs_attr_set_args has become xfs_attr_set_iter, which uses a
state machine like switch to keep track of where it was when EAGAIN was
returned. See xfs_attr.h for a more detailed diagram of the states.

Two new helper functions have been added: xfs_attr_rmtval_find_space and
xfs_attr_rmtval_set_blk.  They provide a subset of logic similar to
xfs_attr_rmtval_set, but they store the current block in the delay attr
context to allow the caller to roll the transaction between allocations.
This helps to simplify and consolidate code used by
xfs_attr_leaf_addname and xfs_attr_node_addname. xfs_attr_set_args has
now become a simple loop to refresh the transaction until the operation
is completed.  Lastly, xfs_attr_rmtval_remove is no longer used, and is
removed.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
---
 fs/xfs/libxfs/xfs_attr.c        | 450 ++++++++++++++++++++++++----------------
 fs/xfs/libxfs/xfs_attr.h        | 274 +++++++++++++++++++++++-
 fs/xfs/libxfs/xfs_attr_remote.c | 100 ++++++---
 fs/xfs/libxfs/xfs_attr_remote.h |   5 +-
 fs/xfs/xfs_trace.h              |   1 -
 5 files changed, 610 insertions(+), 220 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 088f622..f7b0e79 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -53,15 +53,16 @@ STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args, struct xfs_buf *bp);
  */
 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
 STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
-STATIC int xfs_attr_node_addname(struct xfs_da_args *args,
-				 struct xfs_da_state *state);
-STATIC int xfs_attr_node_addname_find_attr(struct xfs_da_args *args,
-				 struct xfs_da_state **state);
-STATIC int xfs_attr_node_addname_clear_incomplete(struct xfs_da_args *args);
+STATIC int xfs_attr_node_addname(struct xfs_delattr_context *dac);
+STATIC int xfs_attr_node_addname_find_attr(struct xfs_delattr_context *dac);
+STATIC int xfs_attr_node_addname_clear_incomplete(
+				struct xfs_delattr_context *dac);
 STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
 				 struct xfs_da_state **state);
 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
+STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
+			     struct xfs_buf **leaf_bp);
 
 int
 xfs_inode_hasattr(
@@ -244,7 +245,7 @@ xfs_attr_is_shortform(
  * Checks to see if a delayed attribute transaction should be rolled.  If so,
  * transaction is finished or rolled as needed.
  */
-int
+STATIC int
 xfs_attr_trans_roll(
 	struct xfs_delattr_context	*dac)
 {
@@ -265,29 +266,58 @@ xfs_attr_trans_roll(
 	return error;
 }
 
+/*
+ * Set the attribute specified in @args.
+ */
+int
+xfs_attr_set_args(
+	struct xfs_da_args		*args)
+{
+	struct xfs_buf			*leaf_bp = NULL;
+	int				error = 0;
+	struct xfs_delattr_context	dac = {
+		.da_args	= args,
+	};
+
+	do {
+		error = xfs_attr_set_iter(&dac, &leaf_bp);
+		if (error != -EAGAIN)
+			break;
+
+		error = xfs_attr_trans_roll(&dac);
+		if (error) {
+			if (leaf_bp)
+				xfs_trans_brelse(args->trans, leaf_bp);
+			return error;
+		}
+	} while (true);
+
+	return error;
+}
+
 STATIC int
 xfs_attr_set_fmt(
-	struct xfs_da_args	*args)
+	struct xfs_delattr_context	*dac,
+	struct xfs_buf			**leaf_bp)
 {
-	struct xfs_buf          *leaf_bp = NULL;
-	struct xfs_inode	*dp = args->dp;
-	int			error, error2 = 0;
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_inode		*dp = args->dp;
+	int				error = 0;
 
 	/*
 	 * Try to add the attr to the attribute list in the inode.
 	 */
 	error = xfs_attr_try_sf_addname(dp, args);
-	if (error != -ENOSPC) {
-		error2 = xfs_trans_commit(args->trans);
-		args->trans = NULL;
-		return error ? error : error2;
-	}
+
+	/* Should only be 0, -EEXIST or -ENOSPC */
+	if (error != -ENOSPC)
+		return error;
 
 	/*
 	 * It won't fit in the shortform, transform to a leaf block.  GROT:
 	 * another possible req'mt for a double-split btree op.
 	 */
-	error = xfs_attr_shortform_to_leaf(args, &leaf_bp);
+	error = xfs_attr_shortform_to_leaf(args, leaf_bp);
 	if (error)
 		return error;
 
@@ -296,102 +326,130 @@ xfs_attr_set_fmt(
 	 * push cannot grab the half-baked leaf buffer and run into problems
 	 * with the write verifier.
 	 */
-	xfs_trans_bhold(args->trans, leaf_bp);
-	error = xfs_defer_finish(&args->trans);
-	xfs_trans_bhold_release(args->trans, leaf_bp);
-	if (error) {
-		xfs_trans_brelse(args->trans, leaf_bp);
-		return error;
-	}
+	xfs_trans_bhold(args->trans, *leaf_bp);
 
+	/*
+	 * We're still in XFS_DAS_UNINIT state here.  We've converted
+	 * the attr fork to leaf format and will restart with the leaf
+	 * add.
+	 */
+	dac->flags |= XFS_DAC_DEFER_FINISH;
 	return -EAGAIN;
 }
 
 /*
  * Set the attribute specified in @args.
+ * This routine is meant to function as a delayed operation, and may return
+ * -EAGAIN when the transaction needs to be rolled.  Calling functions will need
+ * to handle this, and recall the function until a successful error code is
+ * returned.
  */
 int
-xfs_attr_set_args(
-	struct xfs_da_args	*args)
+xfs_attr_set_iter(
+	struct xfs_delattr_context	*dac,
+	struct xfs_buf			**leaf_bp)
 {
-	struct xfs_inode	*dp = args->dp;
-	struct xfs_buf		*bp = NULL;
-	struct xfs_da_state     *state = NULL;
-	int			forkoff, error = 0;
+	struct xfs_da_args              *args = dac->da_args;
+	struct xfs_inode		*dp = args->dp;
+	struct xfs_buf			*bp = NULL;
+	int				forkoff, error = 0;
 
-	/*
-	 * If the attribute list is already in leaf format, jump straight to
-	 * leaf handling.  Otherwise, try to add the attribute to the shortform
-	 * list; if there's no room then convert the list to leaf format and try
-	 * again.
-	 */
-	if (xfs_attr_is_shortform(dp)) {
-		error = xfs_attr_set_fmt(args);
-		if (error != -EAGAIN)
-			return error;
-	}
+	/* State machine switch */
+	switch (dac->dela_state) {
+	case XFS_DAS_UNINIT:
+		/*
+		 * If the fork is shortform, attempt to add the attr. If there
+		 * is no space, this converts to leaf format and returns
+		 * -EAGAIN with the leaf buffer held across the roll. The caller
+		 * will deal with a transaction roll error, but otherwise
+		 * release the hold once we return with a clean transaction.
+		 */
+		if (xfs_attr_is_shortform(dp))
+			return xfs_attr_set_fmt(dac, leaf_bp);
+		if (*leaf_bp != NULL) {
+			xfs_trans_bhold_release(args->trans, *leaf_bp);
+			*leaf_bp = NULL;
+		}
 
-	if (xfs_attr_is_leaf(dp)) {
-		error = xfs_attr_leaf_try_add(args, bp);
-		if (error == -ENOSPC) {
-			/*
-			 * Promote the attribute list to the Btree format.
-			 */
-			error = xfs_attr3_leaf_to_node(args);
-			if (error)
+		if (xfs_attr_is_leaf(dp)) {
+			error = xfs_attr_leaf_try_add(args, *leaf_bp);
+			if (error == -ENOSPC) {
+				error = xfs_attr3_leaf_to_node(args);
+				if (error)
+					return error;
+
+				/*
+				 * Finish any deferred work items and roll the
+				 * transaction once more.  The goal here is to
+				 * call node_addname with the inode and
+				 * transaction in the same state (inode locked
+				 * and joined, transaction clean) no matter how
+				 * we got to this step.
+				 *
+				 * At this point, we are still in
+				 * XFS_DAS_UNINIT, but when we come back, we'll
+				 * be a node, so we'll fall down into the node
+				 * handling code below
+				 */
+				dac->flags |= XFS_DAC_DEFER_FINISH;
+				return -EAGAIN;
+			} else if (error) {
 				return error;
+			}
 
-			/*
-			 * Finish any deferred work items and roll the transaction once
-			 * more.  The goal here is to call node_addname with the inode
-			 * and transaction in the same state (inode locked and joined,
-			 * transaction clean) no matter how we got to this step.
-			 */
-			error = xfs_defer_finish(&args->trans);
+			dac->dela_state = XFS_DAS_FOUND_LBLK;
+		} else {
+			error = xfs_attr_node_addname_find_attr(dac);
 			if (error)
 				return error;
 
-			/*
-			 * Commit the current trans (including the inode) and
-			 * start a new one.
-			 */
-			error = xfs_trans_roll_inode(&args->trans, dp);
+			error = xfs_attr_node_addname(dac);
 			if (error)
 				return error;
 
-			goto node;
-		} else if (error) {
-			return error;
+			dac->dela_state = XFS_DAS_FOUND_NBLK;
 		}
-
-		/*
-		 * Commit the transaction that added the attr name so that
-		 * later routines can manage their own transactions.
-		 */
-		error = xfs_trans_roll_inode(&args->trans, dp);
-		if (error)
-			return error;
-
+		return -EAGAIN;
+	case XFS_DAS_FOUND_LBLK:
 		/*
 		 * If there was an out-of-line value, allocate the blocks we
 		 * identified for its storage and copy the value.  This is done
 		 * after we create the attribute so that we don't overflow the
 		 * maximum size of a transaction and/or hit a deadlock.
 		 */
-		if (args->rmtblkno > 0) {
-			error = xfs_attr_rmtval_set(args);
+
+		/* Open coded xfs_attr_rmtval_set without trans handling */
+		if ((dac->flags & XFS_DAC_LEAF_ADDNAME_INIT) == 0) {
+			dac->flags |= XFS_DAC_LEAF_ADDNAME_INIT;
+			if (args->rmtblkno > 0) {
+				error = xfs_attr_rmtval_find_space(dac);
+				if (error)
+					return error;
+			}
+		}
+
+		/*
+		 * Repeat allocating remote blocks for the attr value until
+		 * blkcnt drops to zero.
+		 */
+		if (dac->blkcnt > 0) {
+			error = xfs_attr_rmtval_set_blk(dac);
 			if (error)
 				return error;
+			return -EAGAIN;
 		}
 
+		error = xfs_attr_rmtval_set_value(args);
+		if (error)
+			return error;
+
+		/*
+		 * If this is not a rename, clear the incomplete flag and we're
+		 * done.
+		 */
 		if (!(args->op_flags & XFS_DA_OP_RENAME)) {
-			/*
-			 * Added a "remote" value, just clear the incomplete
-			 *flag.
-			 */
 			if (args->rmtblkno > 0)
 				error = xfs_attr3_leaf_clearflag(args);
-
 			return error;
 		}
 
@@ -404,7 +462,6 @@ xfs_attr_set_args(
 		 * In a separate transaction, set the incomplete flag on the
 		 * "old" attr and clear the incomplete flag on the "new" attr.
 		 */
-
 		error = xfs_attr3_leaf_flipflags(args);
 		if (error)
 			return error;
@@ -412,29 +469,37 @@ xfs_attr_set_args(
 		 * Commit the flag value change and start the next trans in
 		 * series.
 		 */
-		error = xfs_trans_roll_inode(&args->trans, args->dp);
-		if (error)
-			return error;
-
+		dac->dela_state = XFS_DAS_FLIP_LFLAG;
+		return -EAGAIN;
+	case XFS_DAS_FLIP_LFLAG:
 		/*
 		 * Dismantle the "old" attribute/value pair by removing a
 		 * "remote" value (if it exists).
 		 */
 		xfs_attr_restore_rmt_blk(args);
+		error = xfs_attr_rmtval_invalidate(args);
+		if (error)
+			return error;
 
+		/* fallthrough */
+	case XFS_DAS_RM_LBLK:
+		/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
+		dac->dela_state = XFS_DAS_RM_LBLK;
 		if (args->rmtblkno) {
-			error = xfs_attr_rmtval_invalidate(args);
+			error = __xfs_attr_rmtval_remove(dac);
 			if (error)
 				return error;
 
-			error = xfs_attr_rmtval_remove(args);
-			if (error)
-				return error;
+			dac->dela_state = XFS_DAS_RD_LEAF;
+			return -EAGAIN;
 		}
 
+		/* fallthrough */
+	case XFS_DAS_RD_LEAF:
 		/*
-		 * Read in the block containing the "old" attr, then remove the
-		 * "old" attr from that block (neat, huh!)
+		 * This is the last step for leaf format. Read the block with
+		 * the old attr, remove the old attr, check for shortform
+		 * conversion and return.
 		 */
 		error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
 					   &bp);
@@ -443,97 +508,116 @@ xfs_attr_set_args(
 
 		xfs_attr3_leaf_remove(bp, args);
 
-		/*
-		 * If the result is small enough, shrink it all into the inode.
-		 */
 		forkoff = xfs_attr_shortform_allfit(bp, dp);
 		if (forkoff)
 			error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
 			/* bp is gone due to xfs_da_shrink_inode */
 
 		return error;
-	}
-node:
 
+	case XFS_DAS_FOUND_NBLK:
+		/*
+		 * Find space for remote blocks and fall into the allocation
+		 * state.
+		 */
+		if (args->rmtblkno > 0) {
+			error = xfs_attr_rmtval_find_space(dac);
+			if (error)
+				return error;
+		}
 
-	do {
-		error = xfs_attr_node_addname_find_attr(args, &state);
-		if (error)
-			return error;
-		error = xfs_attr_node_addname(args, state);
-	} while (error == -EAGAIN);
-	if (error)
-		return error;
+		/* fallthrough */
+	case XFS_DAS_ALLOC_NODE:
+		/*
+		 * If there was an out-of-line value, allocate the blocks we
+		 * identified for its storage and copy the value.  This is done
+		 * after we create the attribute so that we don't overflow the
+		 * maximum size of a transaction and/or hit a deadlock.
+		 */
+		dac->dela_state = XFS_DAS_ALLOC_NODE;
+		if (args->rmtblkno > 0) {
+			if (dac->blkcnt > 0) {
+				error = xfs_attr_rmtval_set_blk(dac);
+				if (error)
+					return error;
+				return -EAGAIN;
+			}
+
+			error = xfs_attr_rmtval_set_value(args);
+			if (error)
+				return error;
+		}
 
-	/*
-	 * Commit the leaf addition or btree split and start the next
-	 * trans in the chain.
-	 */
-	error = xfs_trans_roll_inode(&args->trans, dp);
-	if (error)
-		goto out;
+		/*
+		 * If this was not a rename, clear the incomplete flag and we're
+		 * done.
+		 */
+		if (!(args->op_flags & XFS_DA_OP_RENAME)) {
+			if (args->rmtblkno > 0)
+				error = xfs_attr3_leaf_clearflag(args);
+			goto out;
+		}
 
-	/*
-	 * If there was an out-of-line value, allocate the blocks we
-	 * identified for its storage and copy the value.  This is done
-	 * after we create the attribute so that we don't overflow the
-	 * maximum size of a transaction and/or hit a deadlock.
-	 */
-	if (args->rmtblkno > 0) {
-		error = xfs_attr_rmtval_set(args);
+		/*
+		 * If this is an atomic rename operation, we must "flip" the
+		 * incomplete flags on the "new" and "old" attribute/value pairs
+		 * so that one disappears and one appears atomically.  Then we
+		 * must remove the "old" attribute/value pair.
+		 *
+		 * In a separate transaction, set the incomplete flag on the
+		 * "old" attr and clear the incomplete flag on the "new" attr.
+		 */
+		error = xfs_attr3_leaf_flipflags(args);
 		if (error)
-			return error;
-	}
-
-	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
+			goto out;
 		/*
-		 * Added a "remote" value, just clear the incomplete flag.
+		 * Commit the flag value change and start the next trans in
+		 * series
 		 */
-		if (args->rmtblkno > 0)
-			error = xfs_attr3_leaf_clearflag(args);
-		goto out;
-	}
-
-	/*
-	 * If this is an atomic rename operation, we must "flip" the incomplete
-	 * flags on the "new" and "old" attribute/value pairs so that one
-	 * disappears and one appears atomically.  Then we must remove the "old"
-	 * attribute/value pair.
-	 *
-	 * In a separate transaction, set the incomplete flag on the "old" attr
-	 * and clear the incomplete flag on the "new" attr.
-	 */
-	error = xfs_attr3_leaf_flipflags(args);
-	if (error)
-		goto out;
-	/*
-	 * Commit the flag value change and start the next trans in series
-	 */
-	error = xfs_trans_roll_inode(&args->trans, args->dp);
-	if (error)
-		goto out;
+		dac->dela_state = XFS_DAS_FLIP_NFLAG;
+		return -EAGAIN;
 
-	/*
-	 * Dismantle the "old" attribute/value pair by removing a "remote" value
-	 * (if it exists).
-	 */
-	xfs_attr_restore_rmt_blk(args);
+	case XFS_DAS_FLIP_NFLAG:
+		/*
+		 * Dismantle the "old" attribute/value pair by removing a
+		 * "remote" value (if it exists).
+		 */
+		xfs_attr_restore_rmt_blk(args);
 
-	if (args->rmtblkno) {
 		error = xfs_attr_rmtval_invalidate(args);
 		if (error)
 			return error;
 
-		error = xfs_attr_rmtval_remove(args);
-		if (error)
-			return error;
-	}
+		/* fallthrough */
+	case XFS_DAS_RM_NBLK:
+		/* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
+		dac->dela_state = XFS_DAS_RM_NBLK;
+		if (args->rmtblkno) {
+			error = __xfs_attr_rmtval_remove(dac);
+			if (error)
+				return error;
+
+			dac->dela_state = XFS_DAS_CLR_FLAG;
+			return -EAGAIN;
+		}
 
-	error = xfs_attr_node_addname_clear_incomplete(args);
+		/* fallthrough */
+	case XFS_DAS_CLR_FLAG:
+		/*
+		 * The last state for node format. Look up the old attr and
+		 * remove it.
+		 */
+		error = xfs_attr_node_addname_clear_incomplete(dac);
+		break;
+	default:
+		ASSERT(dac->dela_state != XFS_DAS_RM_SHRINK);
+		break;
+	}
 out:
 	return error;
 }
 
+
 /*
  * Return EEXIST if attr is found, or ENOATTR if not
  */
@@ -997,18 +1081,18 @@ xfs_attr_node_hasname(
 
 STATIC int
 xfs_attr_node_addname_find_attr(
-	struct xfs_da_args	*args,
-	struct xfs_da_state     **state)
+	struct xfs_delattr_context	*dac)
 {
-	int			retval;
+	struct xfs_da_args		*args = dac->da_args;
+	int				retval;
 
 	/*
 	 * Search to see if name already exists, and get back a pointer
 	 * to where it should go.
 	 */
-	retval = xfs_attr_node_hasname(args, state);
+	retval = xfs_attr_node_hasname(args, &dac->da_state);
 	if (retval != -ENOATTR && retval != -EEXIST)
-		goto error;
+		return retval;
 
 	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
 		goto error;
@@ -1034,8 +1118,8 @@ xfs_attr_node_addname_find_attr(
 
 	return 0;
 error:
-	if (*state)
-		xfs_da_state_free(*state);
+	if (dac->da_state)
+		xfs_da_state_free(dac->da_state);
 	return retval;
 }
 
@@ -1048,19 +1132,23 @@ xfs_attr_node_addname_find_attr(
  *
  * "Remote" attribute values confuse the issue and atomic rename operations
  * add a whole extra layer of confusion on top of that.
+ *
+ * This routine is meant to function as a delayed operation, and may return
+ * -EAGAIN when the transaction needs to be rolled.  Calling functions will need
+ * to handle this, and recall the function until a successful error code is
+ *returned.
  */
 STATIC int
 xfs_attr_node_addname(
-	struct xfs_da_args	*args,
-	struct xfs_da_state	*state)
+	struct xfs_delattr_context	*dac)
 {
-	struct xfs_da_state_blk	*blk;
-	struct xfs_inode	*dp;
-	int			error;
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_da_state		*state = dac->da_state;
+	struct xfs_da_state_blk		*blk;
+	int				error;
 
 	trace_xfs_attr_node_addname(args);
 
-	dp = args->dp;
 	blk = &state->path.blk[state->path.active-1];
 	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
 
@@ -1077,18 +1165,15 @@ xfs_attr_node_addname(
 			error = xfs_attr3_leaf_to_node(args);
 			if (error)
 				goto out;
-			error = xfs_defer_finish(&args->trans);
-			if (error)
-				goto out;
 
 			/*
-			 * Commit the node conversion and start the next
-			 * trans in the chain.
+			 * Now that we have converted the leaf to a node, we can
+			 * roll the transaction, and try xfs_attr3_leaf_add
+			 * again on re-entry.  No need to set dela_state to do
+			 * this. dela_state is still unset by this function at
+			 * this point.
 			 */
-			error = xfs_trans_roll_inode(&args->trans, dp);
-			if (error)
-				goto out;
-
+			dac->flags |= XFS_DAC_DEFER_FINISH;
 			return -EAGAIN;
 		}
 
@@ -1101,9 +1186,7 @@ xfs_attr_node_addname(
 		error = xfs_da3_split(state);
 		if (error)
 			goto out;
-		error = xfs_defer_finish(&args->trans);
-		if (error)
-			goto out;
+		dac->flags |= XFS_DAC_DEFER_FINISH;
 	} else {
 		/*
 		 * Addition succeeded, update Btree hashvals.
@@ -1120,8 +1203,9 @@ xfs_attr_node_addname(
 
 STATIC int
 xfs_attr_node_addname_clear_incomplete(
-	struct xfs_da_args		*args)
+	struct xfs_delattr_context	*dac)
 {
+	struct xfs_da_args		*args = dac->da_args;
 	struct xfs_da_state		*state = NULL;
 	struct xfs_da_state_blk		*blk;
 	int				retval = 0;
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 1267ea8..8de5d1d 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -164,6 +164,264 @@ struct xfs_attr_list_context {
  *              v
  *            done
  *
+ *
+ * Below is a state machine diagram for attr set operations.
+ *
+ * It seems the challenge with understanding this system comes from trying to
+ * absorb the state machine all at once, when really one should only be looking
+ * at it with in the context of a single function. Once a state sensitive
+ * function is called, the idea is that it "takes ownership" of the
+ * state machine. It isn't concerned with the states that may have belonged to
+ * it's calling parent. Only the states relevant to itself or any other
+ * subroutines there in. Once a calling function hands off the state machine to
+ * a subroutine, it needs to respect the simple rule that it doesn't "own" the
+ * state machine anymore, and it's the responsibility of that calling function
+ * to propagate the -EAGAIN back up the call stack. Upon reentry, it is
+ * committed to re-calling that subroutine until it returns something other than
+ * -EAGAIN. Once that subroutine signals completion (by returning anything other
+ * than -EAGAIN), the calling function can resume using the state machine.
+ *
+ *  xfs_attr_set_iter()
+ *              │
+ *              v
+ *   ┌─y─ has an attr fork?
+ *   │          |
+ *   │          n
+ *   │          |
+ *   │          V
+ *   │       add a fork
+ *   │          │
+ *   └──────────┤
+ *              │
+ *              V
+ *   ┌─── is shortform?
+ *   │          │
+ *   │          y
+ *   │          │
+ *   │          V
+ *   │   xfs_attr_set_fmt
+ *   │          |
+ *   │          V
+ *   │ xfs_attr_try_sf_addname
+ *   │          │
+ *   │          V
+ *   │      had enough ──y──> done
+ *   │        space?
+ *   n          │
+ *   │          n
+ *   │          │
+ *   │          V
+ *   │   transform to leaf
+ *   │          │
+ *   │          V
+ *   │   hold the leaf buffer
+ *   │          │
+ *   │          V
+ *   │     return -EAGAIN
+ *   │      Re-enter in
+ *   │       leaf form
+ *   │
+ *   └─> release leaf buffer
+ *          if needed
+ *              │
+ *              V
+ *   ┌───n── fork has
+ *   │      only 1 blk?
+ *   │          │
+ *   │          y
+ *   │          │
+ *   │          v
+ *   │ xfs_attr_leaf_try_add()
+ *   │          │
+ *   │          v
+ *   │      had enough ──────────────y─────────────┐
+ *   │        space?                               │
+ *   │          │                                  │
+ *   │          n                                  │
+ *   │          │                                  │
+ *   │          v                                  │
+ *   │    return -EAGAIN                           │
+ *   │      re-enter in                            │
+ *   │        node form                            │
+ *   │          │                                  │
+ *   └──────────┤                                  │
+ *              │                                  │
+ *              V                                  │
+ * xfs_attr_node_addname_find_attr                 │
+ *        determines if this                       │
+ *       is create or rename                       │
+ *     find space to store attr                    │
+ *              │                                  │
+ *              v                                  │
+ *     xfs_attr_node_addname                       │
+ *              │                                  │
+ *              v                                  │
+ *   fits in a node leaf? ────n─────┐              │
+ *              │     ^             v              │
+ *              │     │       single leaf node?    │
+ *              │     │         │            │     │
+ *              y     │         y            n     │
+ *              │     │         │            │     │
+ *              v     │         v            v     │
+ *            update  │    grow the leaf  split if │
+ *           hashvals └── return -EAGAIN   needed  │
+ *              │         retry leaf add     │     │
+ *              │           on reentry       │     │
+ *              ├────────────────────────────┘     │
+ *              │                                  │
+ *              v                                  │
+ *         need to alloc                           │
+ *   ┌─y── or flip flag?                           │
+ *   │          │                                  │
+ *   │          n                                  │
+ *   │          │                                  │
+ *   │          v                                  │
+ *   │         done                                │
+ *   │                                             │
+ *   │                                             │
+ *   │         XFS_DAS_FOUND_LBLK <────────────────┘
+ *   │                  │
+ *   │                  V
+ *   │        xfs_attr_leaf_addname()
+ *   │                  │
+ *   │                  v
+ *   │      ┌──first time through?
+ *   │      │          │
+ *   │      │          y
+ *   │      │          │
+ *   │      n          v
+ *   │      │    if we have rmt blks
+ *   │      │    find space for them
+ *   │      │          │
+ *   │      └──────────┤
+ *   │                 │
+ *   │                 v
+ *   │            still have
+ *   │      ┌─n─ blks to alloc? <──┐
+ *   │      │          │           │
+ *   │      │          y           │
+ *   │      │          │           │
+ *   │      │          v           │
+ *   │      │     alloc one blk    │
+ *   │      │     return -EAGAIN ──┘
+ *   │      │    re-enter with one
+ *   │      │    less blk to alloc
+ *   │      │
+ *   │      │
+ *   │      └───> set the rmt
+ *   │               value
+ *   │                 │
+ *   │                 v
+ *   │               was this
+ *   │              a rename? ──n─┐
+ *   │                 │          │
+ *   │                 y          │
+ *   │                 │          │
+ *   │                 v          │
+ *   │           flip incomplete  │
+ *   │               flag         │
+ *   │                 │          │
+ *   │                 v          │
+ *   │         XFS_DAS_FLIP_LFLAG │
+ *   │                 │          │
+ *   │                 v          │
+ *   │          need to remove    │
+ *   │              old bks? ──n──┤
+ *   │                 │          │
+ *   │                 y          │
+ *   │                 │          │
+ *   │                 V          │
+ *   │               remove       │
+ *   │        ┌───> old blks      │
+ *   │        │        │          │
+ *   │ XFS_DAS_RM_LBLK │          │
+ *   │        ^        │          │
+ *   │        │        v          │
+ *   │        └──y── more to      │
+ *   │              remove?       │
+ *   │                 │          │
+ *   │                 n          │
+ *   │                 │          │
+ *   │                 v          │
+ *   │          XFS_DAS_RD_LEAF   │
+ *   │                 │          │
+ *   │                 v          │
+ *   │            remove leaf     │
+ *   │                 │          │
+ *   │                 v          │
+ *   │            shrink to sf    │
+ *   │             if needed      │
+ *   │                 │          │
+ *   │                 v          │
+ *   │                done <──────┘
+ *   │
+ *   └──────> XFS_DAS_FOUND_NBLK
+ *                     │
+ *                     v
+ *       ┌─────n──  need to
+ *       │        alloc blks?
+ *       │             │
+ *       │             y
+ *       │             │
+ *       │             v
+ *       │        find space
+ *       │             │
+ *       │             v
+ *       │  ┌─>XFS_DAS_ALLOC_NODE
+ *       │  │          │
+ *       │  │          v
+ *       │  │      alloc blk
+ *       │  │          │
+ *       │  │          v
+ *       │  └──y── need to alloc
+ *       │         more blocks?
+ *       │             │
+ *       │             n
+ *       │             │
+ *       │             v
+ *       │      set the rmt value
+ *       │             │
+ *       │             v
+ *       │          was this
+ *       └────────> a rename? ──n─┐
+ *                     │          │
+ *                     y          │
+ *                     │          │
+ *                     v          │
+ *               flip incomplete  │
+ *                   flag         │
+ *                     │          │
+ *                     v          │
+ *             XFS_DAS_FLIP_NFLAG │
+ *                     │          │
+ *                     v          │
+ *                 need to        │
+ *               remove blks? ─n──┤
+ *                     │          │
+ *                     y          │
+ *                     │          │
+ *                     v          │
+ *                   remove       │
+ *        ┌────────> old blks     │
+ *        │            │          │
+ *  XFS_DAS_RM_NBLK    │          │
+ *        ^            │          │
+ *        │            v          │
+ *        └──────y── more to      │
+ *                   remove       │
+ *                     │          │
+ *                     n          │
+ *                     │          │
+ *                     v          │
+ *              XFS_DAS_CLR_FLAG  │
+ *                     │          │
+ *                     v          │
+ *                clear flags     │
+ *                     │          │
+ *                     ├──────────┘
+ *                     │
+ *                     v
+ *                   done
  */
 
 /*
@@ -180,12 +438,22 @@ enum xfs_delattr_state {
 	XFS_DAS_RMTBLK,		      /* Removing remote blks */
 	XFS_DAS_RM_NAME,	      /* Remove attr name */
 	XFS_DAS_RM_SHRINK,	      /* We are shrinking the tree */
+	XFS_DAS_FOUND_LBLK,	      /* We found leaf blk for attr */
+	XFS_DAS_FOUND_NBLK,	      /* We found node blk for attr */
+	XFS_DAS_FLIP_LFLAG,	      /* Flipped leaf INCOMPLETE attr flag */
+	XFS_DAS_RM_LBLK,	      /* A rename is removing leaf blocks */
+	XFS_DAS_RD_LEAF,	      /* Read in the new leaf */
+	XFS_DAS_ALLOC_NODE,	      /* We are allocating node blocks */
+	XFS_DAS_FLIP_NFLAG,	      /* Flipped node INCOMPLETE attr flag */
+	XFS_DAS_RM_NBLK,	      /* A rename is removing node blocks */
+	XFS_DAS_CLR_FLAG,	      /* Clear incomplete flag */
 };
 
 /*
  * Defines for xfs_delattr_context.flags
  */
 #define XFS_DAC_DEFER_FINISH		0x01 /* finish the transaction */
+#define XFS_DAC_LEAF_ADDNAME_INIT	0x02 /* xfs_attr_leaf_addname init*/
 
 /*
  * Context used for keeping track of delayed attribute operations
@@ -193,6 +461,11 @@ enum xfs_delattr_state {
 struct xfs_delattr_context {
 	struct xfs_da_args      *da_args;
 
+	/* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */
+	struct xfs_bmbt_irec	map;
+	xfs_dablk_t		lblkno;
+	int			blkcnt;
+
 	/* Used in xfs_attr_node_removename to roll through removing blocks */
 	struct xfs_da_state     *da_state;
 
@@ -220,7 +493,6 @@ int xfs_attr_set_args(struct xfs_da_args *args);
 int xfs_has_attr(struct xfs_da_args *args);
 int xfs_attr_remove_args(struct xfs_da_args *args);
 int xfs_attr_remove_iter(struct xfs_delattr_context *dac);
-int xfs_attr_trans_roll(struct xfs_delattr_context *dac);
 bool xfs_attr_namecheck(const void *name, size_t length);
 void xfs_delattr_context_init(struct xfs_delattr_context *dac,
 			      struct xfs_da_args *args);
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index ada8254..ba3b1c8 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -439,9 +439,9 @@ xfs_attr_rmtval_get(
 
 /*
  * Find a "hole" in the attribute address space large enough for us to drop the
- * new attribute's value into
+ * new attributes value into
  */
-STATIC int
+int
 xfs_attr_rmt_find_hole(
 	struct xfs_da_args	*args)
 {
@@ -468,7 +468,7 @@ xfs_attr_rmt_find_hole(
 	return 0;
 }
 
-STATIC int
+int
 xfs_attr_rmtval_set_value(
 	struct xfs_da_args	*args)
 {
@@ -628,6 +628,69 @@ xfs_attr_rmtval_set(
 }
 
 /*
+ * Find a hole for the attr and store it in the delayed attr context.  This
+ * initializes the context to roll through allocating an attr extent for a
+ * delayed attr operation
+ */
+int
+xfs_attr_rmtval_find_space(
+	struct xfs_delattr_context	*dac)
+{
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_bmbt_irec		*map = &dac->map;
+	int				error;
+
+	dac->lblkno = 0;
+	dac->blkcnt = 0;
+	args->rmtblkcnt = 0;
+	args->rmtblkno = 0;
+	memset(map, 0, sizeof(struct xfs_bmbt_irec));
+
+	error = xfs_attr_rmt_find_hole(args);
+	if (error)
+		return error;
+
+	dac->blkcnt = args->rmtblkcnt;
+	dac->lblkno = args->rmtblkno;
+
+	return 0;
+}
+
+/*
+ * Write one block of the value associated with an attribute into the
+ * out-of-line buffer that we have defined for it. This is similar to a subset
+ * of xfs_attr_rmtval_set, but records the current block to the delayed attr
+ * context, and leaves transaction handling to the caller.
+ */
+int
+xfs_attr_rmtval_set_blk(
+	struct xfs_delattr_context	*dac)
+{
+	struct xfs_da_args		*args = dac->da_args;
+	struct xfs_inode		*dp = args->dp;
+	struct xfs_bmbt_irec		*map = &dac->map;
+	int nmap;
+	int error;
+
+	nmap = 1;
+	error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)dac->lblkno,
+			dac->blkcnt, XFS_BMAPI_ATTRFORK, args->total,
+			map, &nmap);
+	if (error)
+		return error;
+
+	ASSERT(nmap == 1);
+	ASSERT((map->br_startblock != DELAYSTARTBLOCK) &&
+	       (map->br_startblock != HOLESTARTBLOCK));
+
+	/* roll attribute extent map forwards */
+	dac->lblkno += map->br_blockcount;
+	dac->blkcnt -= map->br_blockcount;
+
+	return 0;
+}
+
+/*
  * Remove the value associated with an attribute by deleting the
  * out-of-line buffer that it is stored on.
  */
@@ -669,37 +732,6 @@ xfs_attr_rmtval_invalidate(
 }
 
 /*
- * Remove the value associated with an attribute by deleting the
- * out-of-line buffer that it is stored on.
- */
-int
-xfs_attr_rmtval_remove(
-	struct xfs_da_args		*args)
-{
-	int				error;
-	struct xfs_delattr_context	dac  = {
-		.da_args	= args,
-	};
-
-	trace_xfs_attr_rmtval_remove(args);
-
-	/*
-	 * Keep de-allocating extents until the remote-value region is gone.
-	 */
-	do {
-		error = __xfs_attr_rmtval_remove(&dac);
-		if (error && error != -EAGAIN)
-			break;
-
-		error = xfs_attr_trans_roll(&dac);
-		if (error)
-			return error;
-	} while (true);
-
-	return error;
-}
-
-/*
  * Remove the value associated with an attribute by deleting the out-of-line
  * buffer that it is stored on. Returns -EAGAIN for the caller to refresh the
  * transaction and re-call the function.  Callers should keep calling this
diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h
index 002fd30..8ad68d5 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.h
+++ b/fs/xfs/libxfs/xfs_attr_remote.h
@@ -10,9 +10,12 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
 
 int xfs_attr_rmtval_get(struct xfs_da_args *args);
 int xfs_attr_rmtval_set(struct xfs_da_args *args);
-int xfs_attr_rmtval_remove(struct xfs_da_args *args);
 int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
 		xfs_buf_flags_t incore_flags);
 int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);
 int __xfs_attr_rmtval_remove(struct xfs_delattr_context *dac);
+int xfs_attr_rmt_find_hole(struct xfs_da_args *args);
+int xfs_attr_rmtval_set_value(struct xfs_da_args *args);
+int xfs_attr_rmtval_set_blk(struct xfs_delattr_context *dac);
+int xfs_attr_rmtval_find_space(struct xfs_delattr_context *dac);
 #endif /* __XFS_ATTR_REMOTE_H__ */
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 3c1c830..96f93a7 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -1943,7 +1943,6 @@ DEFINE_ATTR_EVENT(xfs_attr_refillstate);
 
 DEFINE_ATTR_EVENT(xfs_attr_rmtval_get);
 DEFINE_ATTR_EVENT(xfs_attr_rmtval_set);
-DEFINE_ATTR_EVENT(xfs_attr_rmtval_remove);
 
 #define DEFINE_DA_EVENT(name) \
 DEFINE_EVENT(xfs_da_class, name, \
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (9 preceding siblings ...)
  2021-05-25 19:55 ` [PATCH v19 10/14] xfs: Add delay ready attr set routines Allison Henderson
@ 2021-05-25 19:55 ` Allison Henderson
  2021-05-25 20:34   ` Darrick J. Wong
  2021-05-27  6:13   ` Chandan Babu R
  2021-05-25 19:55 ` [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete Allison Henderson
                   ` (3 subsequent siblings)
  14 siblings, 2 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:55 UTC (permalink / raw)
  To: linux-xfs

This function is no longer used, so it is safe to remove

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
---
 fs/xfs/libxfs/xfs_attr_remote.c | 66 -----------------------------------------
 fs/xfs/libxfs/xfs_attr_remote.h |  1 -
 2 files changed, 67 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index ba3b1c8..b5bc50c 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -562,72 +562,6 @@ xfs_attr_rmtval_stale(
 }
 
 /*
- * Write the value associated with an attribute into the out-of-line buffer
- * that we have defined for it.
- */
-int
-xfs_attr_rmtval_set(
-	struct xfs_da_args	*args)
-{
-	struct xfs_inode	*dp = args->dp;
-	struct xfs_bmbt_irec	map;
-	xfs_dablk_t		lblkno;
-	int			blkcnt;
-	int			nmap;
-	int			error;
-
-	trace_xfs_attr_rmtval_set(args);
-
-	error = xfs_attr_rmt_find_hole(args);
-	if (error)
-		return error;
-
-	blkcnt = args->rmtblkcnt;
-	lblkno = (xfs_dablk_t)args->rmtblkno;
-	/*
-	 * Roll through the "value", allocating blocks on disk as required.
-	 */
-	while (blkcnt > 0) {
-		/*
-		 * Allocate a single extent, up to the size of the value.
-		 *
-		 * Note that we have to consider this a data allocation as we
-		 * write the remote attribute without logging the contents.
-		 * Hence we must ensure that we aren't using blocks that are on
-		 * the busy list so that we don't overwrite blocks which have
-		 * recently been freed but their transactions are not yet
-		 * committed to disk. If we overwrite the contents of a busy
-		 * extent and then crash then the block may not contain the
-		 * correct metadata after log recovery occurs.
-		 */
-		nmap = 1;
-		error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
-				  blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
-				  &nmap);
-		if (error)
-			return error;
-		error = xfs_defer_finish(&args->trans);
-		if (error)
-			return error;
-
-		ASSERT(nmap == 1);
-		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
-		       (map.br_startblock != HOLESTARTBLOCK));
-		lblkno += map.br_blockcount;
-		blkcnt -= map.br_blockcount;
-
-		/*
-		 * Start the next trans in the chain.
-		 */
-		error = xfs_trans_roll_inode(&args->trans, dp);
-		if (error)
-			return error;
-	}
-
-	return xfs_attr_rmtval_set_value(args);
-}
-
-/*
  * Find a hole for the attr and store it in the delayed attr context.  This
  * initializes the context to roll through allocating an attr extent for a
  * delayed attr operation
diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h
index 8ad68d5..61b85b9 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.h
+++ b/fs/xfs/libxfs/xfs_attr_remote.h
@@ -9,7 +9,6 @@
 int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
 
 int xfs_attr_rmtval_get(struct xfs_da_args *args);
-int xfs_attr_rmtval_set(struct xfs_da_args *args);
 int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
 		xfs_buf_flags_t incore_flags);
 int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (10 preceding siblings ...)
  2021-05-25 19:55 ` [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set Allison Henderson
@ 2021-05-25 19:55 ` Allison Henderson
  2021-05-25 20:35   ` Darrick J. Wong
  2021-05-27  7:03   ` Chandan Babu R
  2021-05-25 19:55 ` [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter Allison Henderson
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:55 UTC (permalink / raw)
  To: linux-xfs

We can use the helper function xfs_attr_node_remove_name to reduce
duplicate code in this function

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index f7b0e79..32d451b 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -63,6 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
 			     struct xfs_buf **leaf_bp);
+STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
+				     struct xfs_da_state *state);
 
 int
 xfs_inode_hasattr(
@@ -1207,7 +1209,6 @@ xfs_attr_node_addname_clear_incomplete(
 {
 	struct xfs_da_args		*args = dac->da_args;
 	struct xfs_da_state		*state = NULL;
-	struct xfs_da_state_blk		*blk;
 	int				retval = 0;
 	int				error = 0;
 
@@ -1222,13 +1223,7 @@ xfs_attr_node_addname_clear_incomplete(
 	if (error)
 		goto out;
 
-	/*
-	 * Remove the name and update the hashvals in the tree.
-	 */
-	blk = &state->path.blk[state->path.active-1];
-	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
-	error = xfs_attr3_leaf_remove(blk->bp, args);
-	xfs_da3_fixhashpath(state, &state->path);
+	error = xfs_attr_node_remove_name(args, state);
 
 	/*
 	 * Check to see if the tree needs to be collapsed.
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (11 preceding siblings ...)
  2021-05-25 19:55 ` [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete Allison Henderson
@ 2021-05-25 19:55 ` Allison Henderson
  2021-05-25 20:52   ` Darrick J. Wong
  2021-05-25 19:55 ` [PATCH v19 14/14] xfs: Make attr name schemes consistent Allison Henderson
  2021-05-26 18:19 ` [PATCH v19 00/14] Delay Ready Attributes Darrick J. Wong
  14 siblings, 1 reply; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:55 UTC (permalink / raw)
  To: linux-xfs

This ASSERT checks for the state value of RM_SHRINK in the set path.
Which would be invalid, and should never happen.  This change is being
set aside from the rest of the set for further discussion

Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 32d451b..7294a2e 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -612,7 +612,6 @@ xfs_attr_set_iter(
 		error = xfs_attr_node_addname_clear_incomplete(dac);
 		break;
 	default:
-		ASSERT(dac->dela_state != XFS_DAS_RM_SHRINK);
 		break;
 	}
 out:
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v19 14/14] xfs: Make attr name schemes consistent
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (12 preceding siblings ...)
  2021-05-25 19:55 ` [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter Allison Henderson
@ 2021-05-25 19:55 ` Allison Henderson
  2021-05-25 20:36   ` Darrick J. Wong
  2021-05-27  8:01   ` Chandan Babu R
  2021-05-26 18:19 ` [PATCH v19 00/14] Delay Ready Attributes Darrick J. Wong
  14 siblings, 2 replies; 27+ messages in thread
From: Allison Henderson @ 2021-05-25 19:55 UTC (permalink / raw)
  To: linux-xfs

This patch renames the following functions to make the nameing scheme more consistent:
xfs_attr_shortform_remove -> xfs_attr_sf_removename
xfs_attr_node_remove_name -> xfs_attr_node_removename
xfs_attr_set_fmt -> xfs_attr_sf_addname

Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c      | 18 +++++++++---------
 fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
 fs/xfs/libxfs/xfs_attr_leaf.h |  2 +-
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 7294a2e..20b1e3c 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -63,8 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
 			     struct xfs_buf **leaf_bp);
-STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
-				     struct xfs_da_state *state);
+STATIC int xfs_attr_node_removename(struct xfs_da_args *args,
+				    struct xfs_da_state *state);
 
 int
 xfs_inode_hasattr(
@@ -298,7 +298,7 @@ xfs_attr_set_args(
 }
 
 STATIC int
-xfs_attr_set_fmt(
+xfs_attr_sf_addname(
 	struct xfs_delattr_context	*dac,
 	struct xfs_buf			**leaf_bp)
 {
@@ -367,7 +367,7 @@ xfs_attr_set_iter(
 		 * release the hold once we return with a clean transaction.
 		 */
 		if (xfs_attr_is_shortform(dp))
-			return xfs_attr_set_fmt(dac, leaf_bp);
+			return xfs_attr_sf_addname(dac, leaf_bp);
 		if (*leaf_bp != NULL) {
 			xfs_trans_bhold_release(args->trans, *leaf_bp);
 			*leaf_bp = NULL;
@@ -839,7 +839,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
 	if (retval == -EEXIST) {
 		if (args->attr_flags & XATTR_CREATE)
 			return retval;
-		retval = xfs_attr_shortform_remove(args);
+		retval = xfs_attr_sf_removename(args);
 		if (retval)
 			return retval;
 		/*
@@ -1222,7 +1222,7 @@ xfs_attr_node_addname_clear_incomplete(
 	if (error)
 		goto out;
 
-	error = xfs_attr_node_remove_name(args, state);
+	error = xfs_attr_node_removename(args, state);
 
 	/*
 	 * Check to see if the tree needs to be collapsed.
@@ -1338,7 +1338,7 @@ int xfs_attr_node_removename_setup(
 }
 
 STATIC int
-xfs_attr_node_remove_name(
+xfs_attr_node_removename(
 	struct xfs_da_args	*args,
 	struct xfs_da_state	*state)
 {
@@ -1389,7 +1389,7 @@ xfs_attr_remove_iter(
 		 * thus state transitions. Call the right helper and return.
 		 */
 		if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
-			return xfs_attr_shortform_remove(args);
+			return xfs_attr_sf_removename(args);
 
 		if (xfs_attr_is_leaf(dp))
 			return xfs_attr_leaf_removename(args);
@@ -1442,7 +1442,7 @@ xfs_attr_remove_iter(
 
 		/* fallthrough */
 	case XFS_DAS_RM_NAME:
-		retval = xfs_attr_node_remove_name(args, state);
+		retval = xfs_attr_node_removename(args, state);
 
 		/*
 		 * Check to see if the tree needs to be collapsed. If so, roll
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index d97de20..5a3d261 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -773,7 +773,7 @@ xfs_attr_fork_remove(
  * Remove an attribute from the shortform attribute list structure.
  */
 int
-xfs_attr_shortform_remove(
+xfs_attr_sf_removename(
 	struct xfs_da_args		*args)
 {
 	struct xfs_attr_shortform	*sf;
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
index 9b1c59f..efa757f 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.h
+++ b/fs/xfs/libxfs/xfs_attr_leaf.h
@@ -51,7 +51,7 @@ int	xfs_attr_shortform_lookup(struct xfs_da_args *args);
 int	xfs_attr_shortform_getvalue(struct xfs_da_args *args);
 int	xfs_attr_shortform_to_leaf(struct xfs_da_args *args,
 			struct xfs_buf **leaf_bp);
-int	xfs_attr_shortform_remove(struct xfs_da_args *args);
+int	xfs_attr_sf_removename(struct xfs_da_args *args);
 int	xfs_attr_sf_findname(struct xfs_da_args *args,
 			     struct xfs_attr_sf_entry **sfep,
 			     unsigned int *basep);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set
  2021-05-25 19:55 ` [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set Allison Henderson
@ 2021-05-25 20:34   ` Darrick J. Wong
  2021-05-27  6:13   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-25 20:34 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Tue, May 25, 2021 at 12:55:01PM -0700, Allison Henderson wrote:
> This function is no longer used, so it is safe to remove
> 
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>

Looks good to me,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_attr_remote.c | 66 -----------------------------------------
>  fs/xfs/libxfs/xfs_attr_remote.h |  1 -
>  2 files changed, 67 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> index ba3b1c8..b5bc50c 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.c
> +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> @@ -562,72 +562,6 @@ xfs_attr_rmtval_stale(
>  }
>  
>  /*
> - * Write the value associated with an attribute into the out-of-line buffer
> - * that we have defined for it.
> - */
> -int
> -xfs_attr_rmtval_set(
> -	struct xfs_da_args	*args)
> -{
> -	struct xfs_inode	*dp = args->dp;
> -	struct xfs_bmbt_irec	map;
> -	xfs_dablk_t		lblkno;
> -	int			blkcnt;
> -	int			nmap;
> -	int			error;
> -
> -	trace_xfs_attr_rmtval_set(args);
> -
> -	error = xfs_attr_rmt_find_hole(args);
> -	if (error)
> -		return error;
> -
> -	blkcnt = args->rmtblkcnt;
> -	lblkno = (xfs_dablk_t)args->rmtblkno;
> -	/*
> -	 * Roll through the "value", allocating blocks on disk as required.
> -	 */
> -	while (blkcnt > 0) {
> -		/*
> -		 * Allocate a single extent, up to the size of the value.
> -		 *
> -		 * Note that we have to consider this a data allocation as we
> -		 * write the remote attribute without logging the contents.
> -		 * Hence we must ensure that we aren't using blocks that are on
> -		 * the busy list so that we don't overwrite blocks which have
> -		 * recently been freed but their transactions are not yet
> -		 * committed to disk. If we overwrite the contents of a busy
> -		 * extent and then crash then the block may not contain the
> -		 * correct metadata after log recovery occurs.
> -		 */
> -		nmap = 1;
> -		error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
> -				  blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
> -				  &nmap);
> -		if (error)
> -			return error;
> -		error = xfs_defer_finish(&args->trans);
> -		if (error)
> -			return error;
> -
> -		ASSERT(nmap == 1);
> -		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
> -		       (map.br_startblock != HOLESTARTBLOCK));
> -		lblkno += map.br_blockcount;
> -		blkcnt -= map.br_blockcount;
> -
> -		/*
> -		 * Start the next trans in the chain.
> -		 */
> -		error = xfs_trans_roll_inode(&args->trans, dp);
> -		if (error)
> -			return error;
> -	}
> -
> -	return xfs_attr_rmtval_set_value(args);
> -}
> -
> -/*
>   * Find a hole for the attr and store it in the delayed attr context.  This
>   * initializes the context to roll through allocating an attr extent for a
>   * delayed attr operation
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h
> index 8ad68d5..61b85b9 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.h
> +++ b/fs/xfs/libxfs/xfs_attr_remote.h
> @@ -9,7 +9,6 @@
>  int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
>  
>  int xfs_attr_rmtval_get(struct xfs_da_args *args);
> -int xfs_attr_rmtval_set(struct xfs_da_args *args);
>  int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
>  		xfs_buf_flags_t incore_flags);
>  int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete
  2021-05-25 19:55 ` [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete Allison Henderson
@ 2021-05-25 20:35   ` Darrick J. Wong
  2021-05-27  7:03   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-25 20:35 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Tue, May 25, 2021 at 12:55:02PM -0700, Allison Henderson wrote:
> We can use the helper function xfs_attr_node_remove_name to reduce
> duplicate code in this function
> 
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>

Nice cleanup,
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_attr.c | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index f7b0e79..32d451b 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -63,6 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
>  			     struct xfs_buf **leaf_bp);
> +STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
> +				     struct xfs_da_state *state);
>  
>  int
>  xfs_inode_hasattr(
> @@ -1207,7 +1209,6 @@ xfs_attr_node_addname_clear_incomplete(
>  {
>  	struct xfs_da_args		*args = dac->da_args;
>  	struct xfs_da_state		*state = NULL;
> -	struct xfs_da_state_blk		*blk;
>  	int				retval = 0;
>  	int				error = 0;
>  
> @@ -1222,13 +1223,7 @@ xfs_attr_node_addname_clear_incomplete(
>  	if (error)
>  		goto out;
>  
> -	/*
> -	 * Remove the name and update the hashvals in the tree.
> -	 */
> -	blk = &state->path.blk[state->path.active-1];
> -	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> -	error = xfs_attr3_leaf_remove(blk->bp, args);
> -	xfs_da3_fixhashpath(state, &state->path);
> +	error = xfs_attr_node_remove_name(args, state);
>  
>  	/*
>  	 * Check to see if the tree needs to be collapsed.
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 14/14] xfs: Make attr name schemes consistent
  2021-05-25 19:55 ` [PATCH v19 14/14] xfs: Make attr name schemes consistent Allison Henderson
@ 2021-05-25 20:36   ` Darrick J. Wong
  2021-05-27  8:01   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-25 20:36 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Tue, May 25, 2021 at 12:55:04PM -0700, Allison Henderson wrote:
> This patch renames the following functions to make the nameing scheme more consistent:
> xfs_attr_shortform_remove -> xfs_attr_sf_removename
> xfs_attr_node_remove_name -> xfs_attr_node_removename
> xfs_attr_set_fmt -> xfs_attr_sf_addname
> 
> Suggested-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>

:)
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> ---
>  fs/xfs/libxfs/xfs_attr.c      | 18 +++++++++---------
>  fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_attr_leaf.h |  2 +-
>  3 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 7294a2e..20b1e3c 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -63,8 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
>  			     struct xfs_buf **leaf_bp);
> -STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
> -				     struct xfs_da_state *state);
> +STATIC int xfs_attr_node_removename(struct xfs_da_args *args,
> +				    struct xfs_da_state *state);
>  
>  int
>  xfs_inode_hasattr(
> @@ -298,7 +298,7 @@ xfs_attr_set_args(
>  }
>  
>  STATIC int
> -xfs_attr_set_fmt(
> +xfs_attr_sf_addname(
>  	struct xfs_delattr_context	*dac,
>  	struct xfs_buf			**leaf_bp)
>  {
> @@ -367,7 +367,7 @@ xfs_attr_set_iter(
>  		 * release the hold once we return with a clean transaction.
>  		 */
>  		if (xfs_attr_is_shortform(dp))
> -			return xfs_attr_set_fmt(dac, leaf_bp);
> +			return xfs_attr_sf_addname(dac, leaf_bp);
>  		if (*leaf_bp != NULL) {
>  			xfs_trans_bhold_release(args->trans, *leaf_bp);
>  			*leaf_bp = NULL;
> @@ -839,7 +839,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
>  	if (retval == -EEXIST) {
>  		if (args->attr_flags & XATTR_CREATE)
>  			return retval;
> -		retval = xfs_attr_shortform_remove(args);
> +		retval = xfs_attr_sf_removename(args);
>  		if (retval)
>  			return retval;
>  		/*
> @@ -1222,7 +1222,7 @@ xfs_attr_node_addname_clear_incomplete(
>  	if (error)
>  		goto out;
>  
> -	error = xfs_attr_node_remove_name(args, state);
> +	error = xfs_attr_node_removename(args, state);
>  
>  	/*
>  	 * Check to see if the tree needs to be collapsed.
> @@ -1338,7 +1338,7 @@ int xfs_attr_node_removename_setup(
>  }
>  
>  STATIC int
> -xfs_attr_node_remove_name(
> +xfs_attr_node_removename(
>  	struct xfs_da_args	*args,
>  	struct xfs_da_state	*state)
>  {
> @@ -1389,7 +1389,7 @@ xfs_attr_remove_iter(
>  		 * thus state transitions. Call the right helper and return.
>  		 */
>  		if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
> -			return xfs_attr_shortform_remove(args);
> +			return xfs_attr_sf_removename(args);
>  
>  		if (xfs_attr_is_leaf(dp))
>  			return xfs_attr_leaf_removename(args);
> @@ -1442,7 +1442,7 @@ xfs_attr_remove_iter(
>  
>  		/* fallthrough */
>  	case XFS_DAS_RM_NAME:
> -		retval = xfs_attr_node_remove_name(args, state);
> +		retval = xfs_attr_node_removename(args, state);
>  
>  		/*
>  		 * Check to see if the tree needs to be collapsed. If so, roll
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index d97de20..5a3d261 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -773,7 +773,7 @@ xfs_attr_fork_remove(
>   * Remove an attribute from the shortform attribute list structure.
>   */
>  int
> -xfs_attr_shortform_remove(
> +xfs_attr_sf_removename(
>  	struct xfs_da_args		*args)
>  {
>  	struct xfs_attr_shortform	*sf;
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
> index 9b1c59f..efa757f 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.h
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.h
> @@ -51,7 +51,7 @@ int	xfs_attr_shortform_lookup(struct xfs_da_args *args);
>  int	xfs_attr_shortform_getvalue(struct xfs_da_args *args);
>  int	xfs_attr_shortform_to_leaf(struct xfs_da_args *args,
>  			struct xfs_buf **leaf_bp);
> -int	xfs_attr_shortform_remove(struct xfs_da_args *args);
> +int	xfs_attr_sf_removename(struct xfs_da_args *args);
>  int	xfs_attr_sf_findname(struct xfs_da_args *args,
>  			     struct xfs_attr_sf_entry **sfep,
>  			     unsigned int *basep);
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter
  2021-05-25 19:55 ` [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter Allison Henderson
@ 2021-05-25 20:52   ` Darrick J. Wong
  2021-05-26 18:13     ` Allison Henderson
  0 siblings, 1 reply; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-25 20:52 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Tue, May 25, 2021 at 12:55:03PM -0700, Allison Henderson wrote:
> This ASSERT checks for the state value of RM_SHRINK in the set path.
> Which would be invalid, and should never happen.  This change is being
> set aside from the rest of the set for further discussion
> 
> Suggested-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 32d451b..7294a2e 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -612,7 +612,6 @@ xfs_attr_set_iter(
>  		error = xfs_attr_node_addname_clear_incomplete(dac);
>  		break;
>  	default:
> -		ASSERT(dac->dela_state != XFS_DAS_RM_SHRINK);

ASSERT(0); ?

AFAICT the switch statement covers all the states mentioned in the state
diagram for attr setting, so in theory it should be impossible to land
in this state, correct?

--D

>  		break;
>  	}
>  out:
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter
  2021-05-25 20:52   ` Darrick J. Wong
@ 2021-05-26 18:13     ` Allison Henderson
  2021-05-27  7:40       ` Chandan Babu R
  0 siblings, 1 reply; 27+ messages in thread
From: Allison Henderson @ 2021-05-26 18:13 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 5/25/21 1:52 PM, Darrick J. Wong wrote:
> On Tue, May 25, 2021 at 12:55:03PM -0700, Allison Henderson wrote:
>> This ASSERT checks for the state value of RM_SHRINK in the set path.
>> Which would be invalid, and should never happen.  This change is being
>> set aside from the rest of the set for further discussion
>>
>> Suggested-by: Darrick J. Wong <djwong@kernel.org>
>> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
>> ---
>>   fs/xfs/libxfs/xfs_attr.c | 1 -
>>   1 file changed, 1 deletion(-)
>>
>> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
>> index 32d451b..7294a2e 100644
>> --- a/fs/xfs/libxfs/xfs_attr.c
>> +++ b/fs/xfs/libxfs/xfs_attr.c
>> @@ -612,7 +612,6 @@ xfs_attr_set_iter(
>>   		error = xfs_attr_node_addname_clear_incomplete(dac);
>>   		break;
>>   	default:
>> -		ASSERT(dac->dela_state != XFS_DAS_RM_SHRINK);
> 
> ASSERT(0); ?
> 
> AFAICT the switch statement covers all the states mentioned in the state
> diagram for attr setting, so in theory it should be impossible to land
> in this state, correct?
Yes, that's correct, so ASSERT(0); should work too.  I am fine with this 
change if others are.

Allison

> 
> --D
> 
>>   		break;
>>   	}
>>   out:
>> -- 
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 00/14] Delay Ready Attributes
  2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
                   ` (13 preceding siblings ...)
  2021-05-25 19:55 ` [PATCH v19 14/14] xfs: Make attr name schemes consistent Allison Henderson
@ 2021-05-26 18:19 ` Darrick J. Wong
  2021-05-27 16:54   ` Allison Henderson
  14 siblings, 1 reply; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-26 18:19 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Tue, May 25, 2021 at 12:54:50PM -0700, Allison Henderson wrote:
> Hi all,
> 
> This set is a subset of a larger series for Dealyed Attributes. Which is a
> subset of a yet larger series for parent pointers. Delayed attributes allow
> attribute operations (set and remove) to be logged and committed in the same
> way that other delayed operations do. This allows more complex operations (like
> parent pointers) to be broken up into multiple smaller transactions. To do
> this, the existing attr operations must be modified to operate as a delayed
> operation.  This means that they cannot roll, commit, or finish transactions.
> Instead, they return -EAGAIN to allow the calling function to handle the
> transaction.  In this series, we focus on only the delayed attribute portion.
> We will introduce parent pointers in a later set.

Somewhere in here, this introduced a regression that I can reproduce
pretty easily when running:

# FSTYP=xfs ./check -overlay generic/020

[ 1093.136172] XFS: Assertion failed: args->rmtblkno == 0, file: fs/xfs/libxfs/xfs_attr.c, line: 1434
[ 1093.139776] ------------[ cut here ]------------
[ 1093.141590] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.144841] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.153636] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.156094] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.158530] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.159987] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.164680] RSP: 0018:ffffc90001a0fa90 EFLAGS: 00010246
[ 1093.166021] RAX: 0000000000000000 RBX: ffffc90001a0fa00 RCX: 0000000000000000
[ 1093.167761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.169461] RBP: ffff88804b6c4d20 R08: 0000000000000000 R09: 000000000000000a
[ 1093.171095] R10: 000000000000000a R11: f000000000000000 R12: 0000000000000000
[ 1093.172687] R13: ffffc90001a0fb70 R14: ffff88800abe4c00 R15: 0000000000000000
[ 1093.174267] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.176031] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.177250] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.178759] Call Trace:
[ 1093.179328]  xfs_attr_remove_iter+0x25d/0x270 [xfs]
[ 1093.180387]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.181340]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.182269]  __vfs_removexattr+0x52/0x70
[ 1093.183062]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.183957]  vfs_removexattr+0x56/0x100
[ 1093.184729]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.185654]  __vfs_removexattr+0x52/0x70
[ 1093.186419]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.187300]  vfs_removexattr+0x56/0x100
[ 1093.188028]  removexattr+0x58/0x90
[ 1093.188672]  ? __check_object_size+0xc8/0x280
[ 1093.189513]  ? strncpy_from_user+0x47/0x180
[ 1093.190302]  ? preempt_count_add+0x50/0xa0
[ 1093.191119]  ? __mnt_want_write+0x65/0x90
[ 1093.191867]  path_removexattr+0x9e/0xc0
[ 1093.192584]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.193395]  do_syscall_64+0x3a/0x70
[ 1093.194067]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.195017] RIP: 0033:0x7f8c34a7207b
[ 1093.195713] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.199072] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.200454] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.201776] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.203121] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.204441] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.205754] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.207095] ---[ end trace d5f6b816d902441c ]---
[ 1093.208039] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
[ 1093.209609] ------------[ cut here ]------------
[ 1093.210483] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.212095] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.217174] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.218658] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.220280] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.221204] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.224534] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
[ 1093.225502] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
[ 1093.226823] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.228106] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
[ 1093.228952] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
[ 1093.229726] R13: 0000000000000fdc R14: ffff888042f11740 R15: ffff88804e004738
[ 1093.230500] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.231391] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.232033] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.232811] Call Trace:
[ 1093.233115]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
[ 1093.233742]  xfs_trans_log_buf+0x4c/0x100 [xfs]
[ 1093.234349]  xfs_attr3_leaf_remove+0x2b5/0xc30 [xfs]
[ 1093.235001]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
[ 1093.235628]  xfs_attr_node_removename+0x3d/0x90 [xfs]
[ 1093.236273]  xfs_attr_remove_iter+0x50/0x270 [xfs]
[ 1093.236891]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.237445]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.238010]  __vfs_removexattr+0x52/0x70
[ 1093.238460]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.239009]  vfs_removexattr+0x56/0x100
[ 1093.239452]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.239979]  __vfs_removexattr+0x52/0x70
[ 1093.240430]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.240949]  vfs_removexattr+0x56/0x100
[ 1093.241389]  removexattr+0x58/0x90
[ 1093.241786]  ? __check_object_size+0xc8/0x280
[ 1093.242286]  ? strncpy_from_user+0x47/0x180
[ 1093.242780]  ? preempt_count_add+0x50/0xa0
[ 1093.243252]  ? __mnt_want_write+0x65/0x90
[ 1093.243708]  path_removexattr+0x9e/0xc0
[ 1093.244153]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.244647]  do_syscall_64+0x3a/0x70
[ 1093.245064]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.245630] RIP: 0033:0x7f8c34a7207b
[ 1093.246047] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.248025] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.248843] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.249621] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.250395] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.251191] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.251976] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.252753] ---[ end trace d5f6b816d902441d ]---
[ 1093.253282] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
[ 1093.254223] ------------[ cut here ]------------
[ 1093.254758] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.255762] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.258748] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.259642] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.260604] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.261200] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.263184] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
[ 1093.263763] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
[ 1093.264536] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.265315] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
[ 1093.266116] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
[ 1093.266907] R13: 0000000000000058 R14: ffff888042f11740 R15: ffff88804e004738
[ 1093.267675] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.268544] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.269178] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.269949] Call Trace:
[ 1093.270244]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
[ 1093.270888]  xfs_trans_log_buf+0x4c/0x100 [xfs]
[ 1093.271490]  xfs_attr3_leaf_remove+0x2ef/0xc30 [xfs]
[ 1093.272129]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
[ 1093.272759]  xfs_attr_node_removename+0x3d/0x90 [xfs]
[ 1093.273400]  xfs_attr_remove_iter+0x50/0x270 [xfs]
[ 1093.274015]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.274562]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.275139]  __vfs_removexattr+0x52/0x70
[ 1093.275592]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.276117]  vfs_removexattr+0x56/0x100
[ 1093.276558]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.277085]  __vfs_removexattr+0x52/0x70
[ 1093.277534]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.278063]  vfs_removexattr+0x56/0x100
[ 1093.278506]  removexattr+0x58/0x90
[ 1093.278934]  ? __check_object_size+0xc8/0x280
[ 1093.279435]  ? strncpy_from_user+0x47/0x180
[ 1093.279919]  ? preempt_count_add+0x50/0xa0
[ 1093.280384]  ? __mnt_want_write+0x65/0x90
[ 1093.280843]  path_removexattr+0x9e/0xc0
[ 1093.281290]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.281788]  do_syscall_64+0x3a/0x70
[ 1093.282208]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.282792] RIP: 0033:0x7f8c34a7207b
[ 1093.283216] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.285191] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.286027] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.286822] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.287614] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.288396] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.289174] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.289956] ---[ end trace d5f6b816d902441e ]---
[ 1093.290487] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
[ 1093.291444] ------------[ cut here ]------------
[ 1093.291980] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.292978] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.295967] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.296855] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.297814] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.298412] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.300398] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
[ 1093.300987] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
[ 1093.301761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.302541] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
[ 1093.303328] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
[ 1093.304107] R13: 0000000000000000 R14: ffff888042f11740 R15: ffff88804e004738
[ 1093.304878] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.305743] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.306377] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.307172] Call Trace:
[ 1093.307470]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
[ 1093.308100]  xfs_trans_log_buf+0x4c/0x100 [xfs]
[ 1093.308700]  xfs_attr3_leaf_remove+0x3b6/0xc30 [xfs]
[ 1093.309333]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
[ 1093.309971]  xfs_attr_node_removename+0x3d/0x90 [xfs]
[ 1093.310614]  xfs_attr_remove_iter+0x50/0x270 [xfs]
[ 1093.311254]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.311809]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.312381]  __vfs_removexattr+0x52/0x70
[ 1093.312836]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.313367]  vfs_removexattr+0x56/0x100
[ 1093.313813]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.314350]  __vfs_removexattr+0x52/0x70
[ 1093.314820]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.315352]  vfs_removexattr+0x56/0x100
[ 1093.315799]  removexattr+0x58/0x90
[ 1093.316204]  ? __check_object_size+0xc8/0x280
[ 1093.316701]  ? strncpy_from_user+0x47/0x180
[ 1093.317187]  ? preempt_count_add+0x50/0xa0
[ 1093.317656]  ? __mnt_want_write+0x65/0x90
[ 1093.318124]  path_removexattr+0x9e/0xc0
[ 1093.318569]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.319083]  do_syscall_64+0x3a/0x70
[ 1093.319502]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.320075] RIP: 0033:0x7f8c34a7207b
[ 1093.320491] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.322466] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.323307] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.324092] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.324864] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.325647] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.326426] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.327224] ---[ end trace d5f6b816d902441f ]---
[ 1093.327751] XFS: Assertion failed: !(bip->bli_flags & XFS_BLI_LOGGED), file: fs/xfs/xfs_trans_buf.c, line: 79
[ 1093.328827] ------------[ cut here ]------------
[ 1093.329352] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.330350] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.333309] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.334209] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.335181] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.335774] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.337749] RSP: 0018:ffffc90001a0f930 EFLAGS: 00010246
[ 1093.338337] RAX: 0000000000000000 RBX: ffff88804e9fee00 RCX: 0000000000000000
[ 1093.339134] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.339920] RBP: ffff88804e004738 R08: 0000000000000000 R09: 000000000000000a
[ 1093.340697] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
[ 1093.341477] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
[ 1093.342258] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.343144] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.343779] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.344561] Call Trace:
[ 1093.344857]  _xfs_trans_bjoin+0x100/0x110 [xfs]
[ 1093.345469]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
[ 1093.346130]  xfs_da_read_buf+0xce/0x120 [xfs]
[ 1093.346714]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
[ 1093.347313]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
[ 1093.347901]  xfs_attr_node_shrink+0x54/0x100 [xfs]
[ 1093.348514]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
[ 1093.349129]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.349675]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.350237]  __vfs_removexattr+0x52/0x70
[ 1093.350684]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.351228]  vfs_removexattr+0x56/0x100
[ 1093.351667]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.352194]  __vfs_removexattr+0x52/0x70
[ 1093.352642]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.353165]  vfs_removexattr+0x56/0x100
[ 1093.353603]  removexattr+0x58/0x90
[ 1093.354003]  ? __check_object_size+0xc8/0x280
[ 1093.354493]  ? strncpy_from_user+0x47/0x180
[ 1093.354983]  ? preempt_count_add+0x50/0xa0
[ 1093.355452]  ? __mnt_want_write+0x65/0x90
[ 1093.355914]  path_removexattr+0x9e/0xc0
[ 1093.356353]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.356840]  do_syscall_64+0x3a/0x70
[ 1093.357258]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.357819] RIP: 0033:0x7f8c34a7207b
[ 1093.358236] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.360210] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.361031] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.361800] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.362574] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.363361] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.364137] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.364912] ---[ end trace d5f6b816d9024420 ]---
[ 1093.365425] XFS: Assertion failed: !test_bit(XFS_LI_DIRTY, &lip->li_flags), file: fs/xfs/xfs_trans.c, line: 657
[ 1093.366508] ------------[ cut here ]------------
[ 1093.367045] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
[ 1093.368050] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
[ 1093.371056] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
[ 1093.371941] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[ 1093.372891] RIP: 0010:assfail+0x3c/0x40 [xfs]
[ 1093.373477] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
[ 1093.375457] RSP: 0018:ffffc90001a0f900 EFLAGS: 00010246
[ 1093.376042] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
[ 1093.376811] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
[ 1093.377584] RBP: ffff888042f11740 R08: 0000000000000000 R09: 000000000000000a
[ 1093.378361] R10: 000000000000000a R11: f000000000000000 R12: ffff88804e004748
[ 1093.379147] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
[ 1093.379926] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
[ 1093.380796] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1093.381427] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
[ 1093.382201] Call Trace:
[ 1093.382497]  xfs_trans_add_item+0x171/0x180 [xfs]
[ 1093.383137]  _xfs_trans_bjoin+0x72/0x110 [xfs]
[ 1093.383732]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
[ 1093.384395]  xfs_da_read_buf+0xce/0x120 [xfs]
[ 1093.384973]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
[ 1093.385567]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
[ 1093.386162]  xfs_attr_node_shrink+0x54/0x100 [xfs]
[ 1093.386789]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
[ 1093.387402]  xfs_attr_set+0x2ff/0x430 [xfs]
[ 1093.387953]  xfs_xattr_set+0x89/0xd0 [xfs]
[ 1093.388507]  __vfs_removexattr+0x52/0x70
[ 1093.388959]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.389476]  vfs_removexattr+0x56/0x100
[ 1093.389919]  ovl_xattr_set+0x131/0x1d0 [overlay]
[ 1093.390437]  __vfs_removexattr+0x52/0x70
[ 1093.390902]  __vfs_removexattr_locked+0xb8/0x140
[ 1093.391420]  vfs_removexattr+0x56/0x100
[ 1093.391856]  removexattr+0x58/0x90
[ 1093.392257]  ? __check_object_size+0xc8/0x280
[ 1093.392747]  ? strncpy_from_user+0x47/0x180
[ 1093.393223]  ? preempt_count_add+0x50/0xa0
[ 1093.393684]  ? __mnt_want_write+0x65/0x90
[ 1093.394145]  path_removexattr+0x9e/0xc0
[ 1093.394582]  __x64_sys_lremovexattr+0x14/0x20
[ 1093.395095]  do_syscall_64+0x3a/0x70
[ 1093.395508]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 1093.396072] RIP: 0033:0x7f8c34a7207b
[ 1093.396478] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
[ 1093.398426] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
[ 1093.399254] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
[ 1093.400032] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
[ 1093.400800] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
[ 1093.401571] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
[ 1093.402343] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
[ 1093.403130] ---[ end trace d5f6b816d9024421 ]---
[ 1093.565232] XFS (sdc): Unmounting Filesystem
[ 1093.604852] [U] TEST FINISHED: -overlay generic/020 @ Wed May 26 10:34:41 PDT 2021

The first assertion, I think, is an accounting problem -- the ASSERT
checks that args->rmtblkno should be zero after calling the function
__xfs_attr_rmtval_remove to unmap the blocks backing the remote value
from the attr fork.  I don't see anywhere in that function that actually
updates the args fields, however.

AFAICT all this needs is a little bookkeeping update in
__xfs_attr_rmtval_remove.

The second and subsequent assertions come from trying to log a buffer
that isn't attached to the current transaction.  I think what's
happening is:

1. we're in state XFS_DAS_RMTBLK
2. call __xfs_attr_rmtval_remove to remove a remote block, which returns 0
3. call xfs_attr_refillstate to re-attach buffers to the da state
4. set state to XFS_DAS_RM_NAME
5. set XFS_DAC_DEFER_FINISH and return EAGAIN to finish deferred updates
6. <transaction roll releases buffers>
7. now we're in state XFS_DAS_RM_NAME
8. call xfs_attr_node_removename to remove the name
9. trip assert because the buffers in state->path.blk[] aren't joined to the
   current transaction

I think the solution here is to call xfs_attr_refillstate to reattach
all the buffers to the transaction, but only if we've freshly rolled the
transaction.  If we fell through the UNINIT and RMTBLK cases into
RM_NAME without rolling anything, then we're still on the same
transaction that we used for the first lookup and don't need to refill
the state.

Can you take a look at this patch?  It fixes the problems for that one
test, but I haven't run it through QA yet.

--D

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 20b1e3c6bdd0..7b3d0c3d2e65 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -1442,6 +1442,17 @@ xfs_attr_remove_iter(
 
 		/* fallthrough */
 	case XFS_DAS_RM_NAME:
+
+		/*
+		 * If we came here fresh from a transaction roll, reattach all
+		 * the buffers to the current transaction.
+		 */
+		if (dac->dela_state == XFS_DAS_RM_NAME) {
+			error = xfs_attr_refillstate(state);
+			if (error)
+				goto out;
+		}
+
 		retval = xfs_attr_node_removename(args, state);
 
 		/*
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index b5bc50cad9bf..d560b55abedb 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -699,5 +699,8 @@ __xfs_attr_rmtval_remove(
 		return -EAGAIN;
 	}
 
-	return error;
+	/* We've unmapped the remote value blocks, so zero these out */
+	args->rmtblkno = 0;
+	args->rmtblkcnt = 0;
+	return 0;
 }

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set
  2021-05-25 19:55 ` [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set Allison Henderson
  2021-05-25 20:34   ` Darrick J. Wong
@ 2021-05-27  6:13   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Chandan Babu R @ 2021-05-27  6:13 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On 26 May 2021 at 01:25, Allison Henderson wrote:
> This function is no longer used, so it is safe to remove
>

Looks good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr_remote.c | 66 -----------------------------------------
>  fs/xfs/libxfs/xfs_attr_remote.h |  1 -
>  2 files changed, 67 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> index ba3b1c8..b5bc50c 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.c
> +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> @@ -562,72 +562,6 @@ xfs_attr_rmtval_stale(
>  }
>  
>  /*
> - * Write the value associated with an attribute into the out-of-line buffer
> - * that we have defined for it.
> - */
> -int
> -xfs_attr_rmtval_set(
> -	struct xfs_da_args	*args)
> -{
> -	struct xfs_inode	*dp = args->dp;
> -	struct xfs_bmbt_irec	map;
> -	xfs_dablk_t		lblkno;
> -	int			blkcnt;
> -	int			nmap;
> -	int			error;
> -
> -	trace_xfs_attr_rmtval_set(args);
> -
> -	error = xfs_attr_rmt_find_hole(args);
> -	if (error)
> -		return error;
> -
> -	blkcnt = args->rmtblkcnt;
> -	lblkno = (xfs_dablk_t)args->rmtblkno;
> -	/*
> -	 * Roll through the "value", allocating blocks on disk as required.
> -	 */
> -	while (blkcnt > 0) {
> -		/*
> -		 * Allocate a single extent, up to the size of the value.
> -		 *
> -		 * Note that we have to consider this a data allocation as we
> -		 * write the remote attribute without logging the contents.
> -		 * Hence we must ensure that we aren't using blocks that are on
> -		 * the busy list so that we don't overwrite blocks which have
> -		 * recently been freed but their transactions are not yet
> -		 * committed to disk. If we overwrite the contents of a busy
> -		 * extent and then crash then the block may not contain the
> -		 * correct metadata after log recovery occurs.
> -		 */
> -		nmap = 1;
> -		error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
> -				  blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
> -				  &nmap);
> -		if (error)
> -			return error;
> -		error = xfs_defer_finish(&args->trans);
> -		if (error)
> -			return error;
> -
> -		ASSERT(nmap == 1);
> -		ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
> -		       (map.br_startblock != HOLESTARTBLOCK));
> -		lblkno += map.br_blockcount;
> -		blkcnt -= map.br_blockcount;
> -
> -		/*
> -		 * Start the next trans in the chain.
> -		 */
> -		error = xfs_trans_roll_inode(&args->trans, dp);
> -		if (error)
> -			return error;
> -	}
> -
> -	return xfs_attr_rmtval_set_value(args);
> -}
> -
> -/*
>   * Find a hole for the attr and store it in the delayed attr context.  This
>   * initializes the context to roll through allocating an attr extent for a
>   * delayed attr operation
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h
> index 8ad68d5..61b85b9 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.h
> +++ b/fs/xfs/libxfs/xfs_attr_remote.h
> @@ -9,7 +9,6 @@
>  int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
>  
>  int xfs_attr_rmtval_get(struct xfs_da_args *args);
> -int xfs_attr_rmtval_set(struct xfs_da_args *args);
>  int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
>  		xfs_buf_flags_t incore_flags);
>  int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);


-- 
chandan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete
  2021-05-25 19:55 ` [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete Allison Henderson
  2021-05-25 20:35   ` Darrick J. Wong
@ 2021-05-27  7:03   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Chandan Babu R @ 2021-05-27  7:03 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On 26 May 2021 at 01:25, Allison Henderson wrote:
> We can use the helper function xfs_attr_node_remove_name to reduce
> duplicate code in this function
>

Looks good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index f7b0e79..32d451b 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -63,6 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
>  			     struct xfs_buf **leaf_bp);
> +STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
> +				     struct xfs_da_state *state);
>  
>  int
>  xfs_inode_hasattr(
> @@ -1207,7 +1209,6 @@ xfs_attr_node_addname_clear_incomplete(
>  {
>  	struct xfs_da_args		*args = dac->da_args;
>  	struct xfs_da_state		*state = NULL;
> -	struct xfs_da_state_blk		*blk;
>  	int				retval = 0;
>  	int				error = 0;
>  
> @@ -1222,13 +1223,7 @@ xfs_attr_node_addname_clear_incomplete(
>  	if (error)
>  		goto out;
>  
> -	/*
> -	 * Remove the name and update the hashvals in the tree.
> -	 */
> -	blk = &state->path.blk[state->path.active-1];
> -	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> -	error = xfs_attr3_leaf_remove(blk->bp, args);
> -	xfs_da3_fixhashpath(state, &state->path);
> +	error = xfs_attr_node_remove_name(args, state);
>  
>  	/*
>  	 * Check to see if the tree needs to be collapsed.


-- 
chandan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter
  2021-05-26 18:13     ` Allison Henderson
@ 2021-05-27  7:40       ` Chandan Babu R
  0 siblings, 0 replies; 27+ messages in thread
From: Chandan Babu R @ 2021-05-27  7:40 UTC (permalink / raw)
  To: Allison Henderson; +Cc: Darrick J. Wong, linux-xfs

On 26 May 2021 at 23:43, Allison Henderson wrote:
> On 5/25/21 1:52 PM, Darrick J. Wong wrote:
>> On Tue, May 25, 2021 at 12:55:03PM -0700, Allison Henderson wrote:
>>> This ASSERT checks for the state value of RM_SHRINK in the set path.
>>> Which would be invalid, and should never happen.  This change is being
>>> set aside from the rest of the set for further discussion
>>>
>>> Suggested-by: Darrick J. Wong <djwong@kernel.org>
>>> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
>>> ---
>>>   fs/xfs/libxfs/xfs_attr.c | 1 -
>>>   1 file changed, 1 deletion(-)
>>>
>>> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
>>> index 32d451b..7294a2e 100644
>>> --- a/fs/xfs/libxfs/xfs_attr.c
>>> +++ b/fs/xfs/libxfs/xfs_attr.c
>>> @@ -612,7 +612,6 @@ xfs_attr_set_iter(
>>>   		error = xfs_attr_node_addname_clear_incomplete(dac);
>>>   		break;
>>>   	default:
>>> -		ASSERT(dac->dela_state != XFS_DAS_RM_SHRINK);
>>
>> ASSERT(0); ?
>>
>> AFAICT the switch statement covers all the states mentioned in the state
>> diagram for attr setting, so in theory it should be impossible to land
>> in this state, correct?
> Yes, that's correct, so ASSERT(0); should work too.  I am fine with
> this change if others are.

"ASSERT(0);" looks good to me as well.

-- 
chandan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 14/14] xfs: Make attr name schemes consistent
  2021-05-25 19:55 ` [PATCH v19 14/14] xfs: Make attr name schemes consistent Allison Henderson
  2021-05-25 20:36   ` Darrick J. Wong
@ 2021-05-27  8:01   ` Chandan Babu R
  1 sibling, 0 replies; 27+ messages in thread
From: Chandan Babu R @ 2021-05-27  8:01 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On 26 May 2021 at 01:25, Allison Henderson wrote:
> This patch renames the following functions to make the nameing scheme more consistent:
> xfs_attr_shortform_remove -> xfs_attr_sf_removename
> xfs_attr_node_remove_name -> xfs_attr_node_removename
> xfs_attr_set_fmt -> xfs_attr_sf_addname
>

Looks good.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Suggested-by: Darrick J. Wong <djwong@kernel.org>
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c      | 18 +++++++++---------
>  fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_attr_leaf.h |  2 +-
>  3 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 7294a2e..20b1e3c 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -63,8 +63,8 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_set_iter(struct xfs_delattr_context *dac,
>  			     struct xfs_buf **leaf_bp);
> -STATIC int xfs_attr_node_remove_name(struct xfs_da_args *args,
> -				     struct xfs_da_state *state);
> +STATIC int xfs_attr_node_removename(struct xfs_da_args *args,
> +				    struct xfs_da_state *state);
>  
>  int
>  xfs_inode_hasattr(
> @@ -298,7 +298,7 @@ xfs_attr_set_args(
>  }
>  
>  STATIC int
> -xfs_attr_set_fmt(
> +xfs_attr_sf_addname(
>  	struct xfs_delattr_context	*dac,
>  	struct xfs_buf			**leaf_bp)
>  {
> @@ -367,7 +367,7 @@ xfs_attr_set_iter(
>  		 * release the hold once we return with a clean transaction.
>  		 */
>  		if (xfs_attr_is_shortform(dp))
> -			return xfs_attr_set_fmt(dac, leaf_bp);
> +			return xfs_attr_sf_addname(dac, leaf_bp);
>  		if (*leaf_bp != NULL) {
>  			xfs_trans_bhold_release(args->trans, *leaf_bp);
>  			*leaf_bp = NULL;
> @@ -839,7 +839,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
>  	if (retval == -EEXIST) {
>  		if (args->attr_flags & XATTR_CREATE)
>  			return retval;
> -		retval = xfs_attr_shortform_remove(args);
> +		retval = xfs_attr_sf_removename(args);
>  		if (retval)
>  			return retval;
>  		/*
> @@ -1222,7 +1222,7 @@ xfs_attr_node_addname_clear_incomplete(
>  	if (error)
>  		goto out;
>  
> -	error = xfs_attr_node_remove_name(args, state);
> +	error = xfs_attr_node_removename(args, state);
>  
>  	/*
>  	 * Check to see if the tree needs to be collapsed.
> @@ -1338,7 +1338,7 @@ int xfs_attr_node_removename_setup(
>  }
>  
>  STATIC int
> -xfs_attr_node_remove_name(
> +xfs_attr_node_removename(
>  	struct xfs_da_args	*args,
>  	struct xfs_da_state	*state)
>  {
> @@ -1389,7 +1389,7 @@ xfs_attr_remove_iter(
>  		 * thus state transitions. Call the right helper and return.
>  		 */
>  		if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
> -			return xfs_attr_shortform_remove(args);
> +			return xfs_attr_sf_removename(args);
>  
>  		if (xfs_attr_is_leaf(dp))
>  			return xfs_attr_leaf_removename(args);
> @@ -1442,7 +1442,7 @@ xfs_attr_remove_iter(
>  
>  		/* fallthrough */
>  	case XFS_DAS_RM_NAME:
> -		retval = xfs_attr_node_remove_name(args, state);
> +		retval = xfs_attr_node_removename(args, state);
>  
>  		/*
>  		 * Check to see if the tree needs to be collapsed. If so, roll
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index d97de20..5a3d261 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -773,7 +773,7 @@ xfs_attr_fork_remove(
>   * Remove an attribute from the shortform attribute list structure.
>   */
>  int
> -xfs_attr_shortform_remove(
> +xfs_attr_sf_removename(
>  	struct xfs_da_args		*args)
>  {
>  	struct xfs_attr_shortform	*sf;
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
> index 9b1c59f..efa757f 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.h
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.h
> @@ -51,7 +51,7 @@ int	xfs_attr_shortform_lookup(struct xfs_da_args *args);
>  int	xfs_attr_shortform_getvalue(struct xfs_da_args *args);
>  int	xfs_attr_shortform_to_leaf(struct xfs_da_args *args,
>  			struct xfs_buf **leaf_bp);
> -int	xfs_attr_shortform_remove(struct xfs_da_args *args);
> +int	xfs_attr_sf_removename(struct xfs_da_args *args);
>  int	xfs_attr_sf_findname(struct xfs_da_args *args,
>  			     struct xfs_attr_sf_entry **sfep,
>  			     unsigned int *basep);


-- 
chandan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 00/14] Delay Ready Attributes
  2021-05-26 18:19 ` [PATCH v19 00/14] Delay Ready Attributes Darrick J. Wong
@ 2021-05-27 16:54   ` Allison Henderson
  2021-05-27 17:00     ` Darrick J. Wong
  0 siblings, 1 reply; 27+ messages in thread
From: Allison Henderson @ 2021-05-27 16:54 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 5/26/21 11:19 AM, Darrick J. Wong wrote:
> On Tue, May 25, 2021 at 12:54:50PM -0700, Allison Henderson wrote:
>> Hi all,
>>
>> This set is a subset of a larger series for Dealyed Attributes. Which is a
>> subset of a yet larger series for parent pointers. Delayed attributes allow
>> attribute operations (set and remove) to be logged and committed in the same
>> way that other delayed operations do. This allows more complex operations (like
>> parent pointers) to be broken up into multiple smaller transactions. To do
>> this, the existing attr operations must be modified to operate as a delayed
>> operation.  This means that they cannot roll, commit, or finish transactions.
>> Instead, they return -EAGAIN to allow the calling function to handle the
>> transaction.  In this series, we focus on only the delayed attribute portion.
>> We will introduce parent pointers in a later set.
> 
> Somewhere in here, this introduced a regression that I can reproduce
> pretty easily when running:
> 
> # FSTYP=xfs ./check -overlay generic/020
Ok, I am able to reproduce with the same command.  Should be reguarly 
testing with these parameters?  Usually I just run ./check -g attr

> 
> [ 1093.136172] XFS: Assertion failed: args->rmtblkno == 0, file: fs/xfs/libxfs/xfs_attr.c, line: 1434
> [ 1093.139776] ------------[ cut here ]------------
> [ 1093.141590] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.144841] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.153636] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.156094] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.158530] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.159987] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.164680] RSP: 0018:ffffc90001a0fa90 EFLAGS: 00010246
> [ 1093.166021] RAX: 0000000000000000 RBX: ffffc90001a0fa00 RCX: 0000000000000000
> [ 1093.167761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.169461] RBP: ffff88804b6c4d20 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.171095] R10: 000000000000000a R11: f000000000000000 R12: 0000000000000000
> [ 1093.172687] R13: ffffc90001a0fb70 R14: ffff88800abe4c00 R15: 0000000000000000
> [ 1093.174267] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.176031] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.177250] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.178759] Call Trace:
> [ 1093.179328]  xfs_attr_remove_iter+0x25d/0x270 [xfs]
> [ 1093.180387]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.181340]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.182269]  __vfs_removexattr+0x52/0x70
> [ 1093.183062]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.183957]  vfs_removexattr+0x56/0x100
> [ 1093.184729]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.185654]  __vfs_removexattr+0x52/0x70
> [ 1093.186419]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.187300]  vfs_removexattr+0x56/0x100
> [ 1093.188028]  removexattr+0x58/0x90
> [ 1093.188672]  ? __check_object_size+0xc8/0x280
> [ 1093.189513]  ? strncpy_from_user+0x47/0x180
> [ 1093.190302]  ? preempt_count_add+0x50/0xa0
> [ 1093.191119]  ? __mnt_want_write+0x65/0x90
> [ 1093.191867]  path_removexattr+0x9e/0xc0
> [ 1093.192584]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.193395]  do_syscall_64+0x3a/0x70
> [ 1093.194067]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.195017] RIP: 0033:0x7f8c34a7207b
> [ 1093.195713] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.199072] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.200454] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.201776] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.203121] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.204441] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.205754] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.207095] ---[ end trace d5f6b816d902441c ]---
> [ 1093.208039] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> [ 1093.209609] ------------[ cut here ]------------
> [ 1093.210483] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.212095] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.217174] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.218658] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.220280] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.221204] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.224534] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> [ 1093.225502] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> [ 1093.226823] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.228106] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.228952] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> [ 1093.229726] R13: 0000000000000fdc R14: ffff888042f11740 R15: ffff88804e004738
> [ 1093.230500] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.231391] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.232033] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.232811] Call Trace:
> [ 1093.233115]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> [ 1093.233742]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> [ 1093.234349]  xfs_attr3_leaf_remove+0x2b5/0xc30 [xfs]
> [ 1093.235001]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> [ 1093.235628]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> [ 1093.236273]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> [ 1093.236891]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.237445]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.238010]  __vfs_removexattr+0x52/0x70
> [ 1093.238460]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.239009]  vfs_removexattr+0x56/0x100
> [ 1093.239452]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.239979]  __vfs_removexattr+0x52/0x70
> [ 1093.240430]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.240949]  vfs_removexattr+0x56/0x100
> [ 1093.241389]  removexattr+0x58/0x90
> [ 1093.241786]  ? __check_object_size+0xc8/0x280
> [ 1093.242286]  ? strncpy_from_user+0x47/0x180
> [ 1093.242780]  ? preempt_count_add+0x50/0xa0
> [ 1093.243252]  ? __mnt_want_write+0x65/0x90
> [ 1093.243708]  path_removexattr+0x9e/0xc0
> [ 1093.244153]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.244647]  do_syscall_64+0x3a/0x70
> [ 1093.245064]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.245630] RIP: 0033:0x7f8c34a7207b
> [ 1093.246047] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.248025] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.248843] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.249621] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.250395] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.251191] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.251976] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.252753] ---[ end trace d5f6b816d902441d ]---
> [ 1093.253282] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> [ 1093.254223] ------------[ cut here ]------------
> [ 1093.254758] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.255762] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.258748] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.259642] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.260604] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.261200] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.263184] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> [ 1093.263763] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> [ 1093.264536] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.265315] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.266116] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> [ 1093.266907] R13: 0000000000000058 R14: ffff888042f11740 R15: ffff88804e004738
> [ 1093.267675] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.268544] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.269178] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.269949] Call Trace:
> [ 1093.270244]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> [ 1093.270888]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> [ 1093.271490]  xfs_attr3_leaf_remove+0x2ef/0xc30 [xfs]
> [ 1093.272129]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> [ 1093.272759]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> [ 1093.273400]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> [ 1093.274015]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.274562]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.275139]  __vfs_removexattr+0x52/0x70
> [ 1093.275592]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.276117]  vfs_removexattr+0x56/0x100
> [ 1093.276558]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.277085]  __vfs_removexattr+0x52/0x70
> [ 1093.277534]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.278063]  vfs_removexattr+0x56/0x100
> [ 1093.278506]  removexattr+0x58/0x90
> [ 1093.278934]  ? __check_object_size+0xc8/0x280
> [ 1093.279435]  ? strncpy_from_user+0x47/0x180
> [ 1093.279919]  ? preempt_count_add+0x50/0xa0
> [ 1093.280384]  ? __mnt_want_write+0x65/0x90
> [ 1093.280843]  path_removexattr+0x9e/0xc0
> [ 1093.281290]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.281788]  do_syscall_64+0x3a/0x70
> [ 1093.282208]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.282792] RIP: 0033:0x7f8c34a7207b
> [ 1093.283216] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.285191] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.286027] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.286822] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.287614] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.288396] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.289174] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.289956] ---[ end trace d5f6b816d902441e ]---
> [ 1093.290487] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> [ 1093.291444] ------------[ cut here ]------------
> [ 1093.291980] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.292978] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.295967] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.296855] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.297814] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.298412] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.300398] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> [ 1093.300987] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> [ 1093.301761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.302541] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.303328] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> [ 1093.304107] R13: 0000000000000000 R14: ffff888042f11740 R15: ffff88804e004738
> [ 1093.304878] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.305743] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.306377] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.307172] Call Trace:
> [ 1093.307470]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> [ 1093.308100]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> [ 1093.308700]  xfs_attr3_leaf_remove+0x3b6/0xc30 [xfs]
> [ 1093.309333]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> [ 1093.309971]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> [ 1093.310614]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> [ 1093.311254]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.311809]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.312381]  __vfs_removexattr+0x52/0x70
> [ 1093.312836]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.313367]  vfs_removexattr+0x56/0x100
> [ 1093.313813]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.314350]  __vfs_removexattr+0x52/0x70
> [ 1093.314820]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.315352]  vfs_removexattr+0x56/0x100
> [ 1093.315799]  removexattr+0x58/0x90
> [ 1093.316204]  ? __check_object_size+0xc8/0x280
> [ 1093.316701]  ? strncpy_from_user+0x47/0x180
> [ 1093.317187]  ? preempt_count_add+0x50/0xa0
> [ 1093.317656]  ? __mnt_want_write+0x65/0x90
> [ 1093.318124]  path_removexattr+0x9e/0xc0
> [ 1093.318569]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.319083]  do_syscall_64+0x3a/0x70
> [ 1093.319502]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.320075] RIP: 0033:0x7f8c34a7207b
> [ 1093.320491] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.322466] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.323307] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.324092] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.324864] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.325647] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.326426] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.327224] ---[ end trace d5f6b816d902441f ]---
> [ 1093.327751] XFS: Assertion failed: !(bip->bli_flags & XFS_BLI_LOGGED), file: fs/xfs/xfs_trans_buf.c, line: 79
> [ 1093.328827] ------------[ cut here ]------------
> [ 1093.329352] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.330350] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.333309] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.334209] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.335181] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.335774] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.337749] RSP: 0018:ffffc90001a0f930 EFLAGS: 00010246
> [ 1093.338337] RAX: 0000000000000000 RBX: ffff88804e9fee00 RCX: 0000000000000000
> [ 1093.339134] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.339920] RBP: ffff88804e004738 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.340697] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> [ 1093.341477] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
> [ 1093.342258] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.343144] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.343779] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.344561] Call Trace:
> [ 1093.344857]  _xfs_trans_bjoin+0x100/0x110 [xfs]
> [ 1093.345469]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
> [ 1093.346130]  xfs_da_read_buf+0xce/0x120 [xfs]
> [ 1093.346714]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
> [ 1093.347313]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
> [ 1093.347901]  xfs_attr_node_shrink+0x54/0x100 [xfs]
> [ 1093.348514]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
> [ 1093.349129]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.349675]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.350237]  __vfs_removexattr+0x52/0x70
> [ 1093.350684]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.351228]  vfs_removexattr+0x56/0x100
> [ 1093.351667]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.352194]  __vfs_removexattr+0x52/0x70
> [ 1093.352642]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.353165]  vfs_removexattr+0x56/0x100
> [ 1093.353603]  removexattr+0x58/0x90
> [ 1093.354003]  ? __check_object_size+0xc8/0x280
> [ 1093.354493]  ? strncpy_from_user+0x47/0x180
> [ 1093.354983]  ? preempt_count_add+0x50/0xa0
> [ 1093.355452]  ? __mnt_want_write+0x65/0x90
> [ 1093.355914]  path_removexattr+0x9e/0xc0
> [ 1093.356353]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.356840]  do_syscall_64+0x3a/0x70
> [ 1093.357258]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.357819] RIP: 0033:0x7f8c34a7207b
> [ 1093.358236] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.360210] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.361031] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.361800] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.362574] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.363361] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.364137] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.364912] ---[ end trace d5f6b816d9024420 ]---
> [ 1093.365425] XFS: Assertion failed: !test_bit(XFS_LI_DIRTY, &lip->li_flags), file: fs/xfs/xfs_trans.c, line: 657
> [ 1093.366508] ------------[ cut here ]------------
> [ 1093.367045] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> [ 1093.368050] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> [ 1093.371056] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> [ 1093.371941] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> [ 1093.372891] RIP: 0010:assfail+0x3c/0x40 [xfs]
> [ 1093.373477] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> [ 1093.375457] RSP: 0018:ffffc90001a0f900 EFLAGS: 00010246
> [ 1093.376042] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> [ 1093.376811] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> [ 1093.377584] RBP: ffff888042f11740 R08: 0000000000000000 R09: 000000000000000a
> [ 1093.378361] R10: 000000000000000a R11: f000000000000000 R12: ffff88804e004748
> [ 1093.379147] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
> [ 1093.379926] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> [ 1093.380796] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 1093.381427] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> [ 1093.382201] Call Trace:
> [ 1093.382497]  xfs_trans_add_item+0x171/0x180 [xfs]
> [ 1093.383137]  _xfs_trans_bjoin+0x72/0x110 [xfs]
> [ 1093.383732]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
> [ 1093.384395]  xfs_da_read_buf+0xce/0x120 [xfs]
> [ 1093.384973]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
> [ 1093.385567]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
> [ 1093.386162]  xfs_attr_node_shrink+0x54/0x100 [xfs]
> [ 1093.386789]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
> [ 1093.387402]  xfs_attr_set+0x2ff/0x430 [xfs]
> [ 1093.387953]  xfs_xattr_set+0x89/0xd0 [xfs]
> [ 1093.388507]  __vfs_removexattr+0x52/0x70
> [ 1093.388959]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.389476]  vfs_removexattr+0x56/0x100
> [ 1093.389919]  ovl_xattr_set+0x131/0x1d0 [overlay]
> [ 1093.390437]  __vfs_removexattr+0x52/0x70
> [ 1093.390902]  __vfs_removexattr_locked+0xb8/0x140
> [ 1093.391420]  vfs_removexattr+0x56/0x100
> [ 1093.391856]  removexattr+0x58/0x90
> [ 1093.392257]  ? __check_object_size+0xc8/0x280
> [ 1093.392747]  ? strncpy_from_user+0x47/0x180
> [ 1093.393223]  ? preempt_count_add+0x50/0xa0
> [ 1093.393684]  ? __mnt_want_write+0x65/0x90
> [ 1093.394145]  path_removexattr+0x9e/0xc0
> [ 1093.394582]  __x64_sys_lremovexattr+0x14/0x20
> [ 1093.395095]  do_syscall_64+0x3a/0x70
> [ 1093.395508]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [ 1093.396072] RIP: 0033:0x7f8c34a7207b
> [ 1093.396478] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> [ 1093.398426] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> [ 1093.399254] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> [ 1093.400032] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> [ 1093.400800] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> [ 1093.401571] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> [ 1093.402343] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> [ 1093.403130] ---[ end trace d5f6b816d9024421 ]---
> [ 1093.565232] XFS (sdc): Unmounting Filesystem
> [ 1093.604852] [U] TEST FINISHED: -overlay generic/020 @ Wed May 26 10:34:41 PDT 2021
> 
> The first assertion, I think, is an accounting problem -- the ASSERT
> checks that args->rmtblkno should be zero after calling the function
> __xfs_attr_rmtval_remove to unmap the blocks backing the remote value
> from the attr fork.  I don't see anywhere in that function that actually
> updates the args fields, however.
> 
> AFAICT all this needs is a little bookkeeping update in
> __xfs_attr_rmtval_remove.
> 
> The second and subsequent assertions come from trying to log a buffer
> that isn't attached to the current transaction.  I think what's
> happening is:
> 
> 1. we're in state XFS_DAS_RMTBLK
> 2. call __xfs_attr_rmtval_remove to remove a remote block, which returns 0
> 3. call xfs_attr_refillstate to re-attach buffers to the da state
> 4. set state to XFS_DAS_RM_NAME
> 5. set XFS_DAC_DEFER_FINISH and return EAGAIN to finish deferred updates
> 6. <transaction roll releases buffers>
> 7. now we're in state XFS_DAS_RM_NAME
> 8. call xfs_attr_node_removename to remove the name
> 9. trip assert because the buffers in state->path.blk[] aren't joined to the
>     current transaction
> 
> I think the solution here is to call xfs_attr_refillstate to reattach
> all the buffers to the transaction, but only if we've freshly rolled the
> transaction.  If we fell through the UNINIT and RMTBLK cases into
> RM_NAME without rolling anything, then we're still on the same
> transaction that we used for the first lookup and don't need to refill
> the state.
> 
> Can you take a look at this patch?  It fixes the problems for that one
> test, but I haven't run it through QA yet.
Ok, it seems to be doing ok so far in other tests.  (at least for me!) 
Should I just add this to another patch at the end?  Thank you for the 
catch!

Allison

> 
> --D
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 20b1e3c6bdd0..7b3d0c3d2e65 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -1442,6 +1442,17 @@ xfs_attr_remove_iter(
>   
>   		/* fallthrough */
>   	case XFS_DAS_RM_NAME:
> +
> +		/*
> +		 * If we came here fresh from a transaction roll, reattach all
> +		 * the buffers to the current transaction.
> +		 */
> +		if (dac->dela_state == XFS_DAS_RM_NAME) {
> +			error = xfs_attr_refillstate(state);
> +			if (error)
> +				goto out;
> +		}
> +
>   		retval = xfs_attr_node_removename(args, state);
>   
>   		/*
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> index b5bc50cad9bf..d560b55abedb 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.c
> +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> @@ -699,5 +699,8 @@ __xfs_attr_rmtval_remove(
>   		return -EAGAIN;
>   	}
>   
> -	return error;
> +	/* We've unmapped the remote value blocks, so zero these out */
> +	args->rmtblkno = 0;
> +	args->rmtblkcnt = 0;
> +	return 0;
>   }
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v19 00/14] Delay Ready Attributes
  2021-05-27 16:54   ` Allison Henderson
@ 2021-05-27 17:00     ` Darrick J. Wong
  0 siblings, 0 replies; 27+ messages in thread
From: Darrick J. Wong @ 2021-05-27 17:00 UTC (permalink / raw)
  To: Allison Henderson; +Cc: linux-xfs

On Thu, May 27, 2021 at 09:54:49AM -0700, Allison Henderson wrote:
> 
> 
> On 5/26/21 11:19 AM, Darrick J. Wong wrote:
> > On Tue, May 25, 2021 at 12:54:50PM -0700, Allison Henderson wrote:
> > > Hi all,
> > > 
> > > This set is a subset of a larger series for Dealyed Attributes. Which is a
> > > subset of a yet larger series for parent pointers. Delayed attributes allow
> > > attribute operations (set and remove) to be logged and committed in the same
> > > way that other delayed operations do. This allows more complex operations (like
> > > parent pointers) to be broken up into multiple smaller transactions. To do
> > > this, the existing attr operations must be modified to operate as a delayed
> > > operation.  This means that they cannot roll, commit, or finish transactions.
> > > Instead, they return -EAGAIN to allow the calling function to handle the
> > > transaction.  In this series, we focus on only the delayed attribute portion.
> > > We will introduce parent pointers in a later set.
> > 
> > Somewhere in here, this introduced a regression that I can reproduce
> > pretty easily when running:
> > 
> > # FSTYP=xfs ./check -overlay generic/020
> Ok, I am able to reproduce with the same command.  Should be reguarly
> testing with these parameters?  Usually I just run ./check -g attr

'-g all' is a better idea since there are a lot of stress testers (e.g.
fsx and fsstress) that will exercise attr code but aren't specifically
tagged in the attr group.

As for overlayfs on top of XFS ... that didn't used to be part of my
standard testing configuration until $cloud made it cheap to spawn
dozens of VMs.

> 
> > 
> > [ 1093.136172] XFS: Assertion failed: args->rmtblkno == 0, file: fs/xfs/libxfs/xfs_attr.c, line: 1434
> > [ 1093.139776] ------------[ cut here ]------------
> > [ 1093.141590] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.144841] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.153636] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.156094] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.158530] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.159987] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.164680] RSP: 0018:ffffc90001a0fa90 EFLAGS: 00010246
> > [ 1093.166021] RAX: 0000000000000000 RBX: ffffc90001a0fa00 RCX: 0000000000000000
> > [ 1093.167761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.169461] RBP: ffff88804b6c4d20 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.171095] R10: 000000000000000a R11: f000000000000000 R12: 0000000000000000
> > [ 1093.172687] R13: ffffc90001a0fb70 R14: ffff88800abe4c00 R15: 0000000000000000
> > [ 1093.174267] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.176031] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.177250] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.178759] Call Trace:
> > [ 1093.179328]  xfs_attr_remove_iter+0x25d/0x270 [xfs]
> > [ 1093.180387]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.181340]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.182269]  __vfs_removexattr+0x52/0x70
> > [ 1093.183062]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.183957]  vfs_removexattr+0x56/0x100
> > [ 1093.184729]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.185654]  __vfs_removexattr+0x52/0x70
> > [ 1093.186419]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.187300]  vfs_removexattr+0x56/0x100
> > [ 1093.188028]  removexattr+0x58/0x90
> > [ 1093.188672]  ? __check_object_size+0xc8/0x280
> > [ 1093.189513]  ? strncpy_from_user+0x47/0x180
> > [ 1093.190302]  ? preempt_count_add+0x50/0xa0
> > [ 1093.191119]  ? __mnt_want_write+0x65/0x90
> > [ 1093.191867]  path_removexattr+0x9e/0xc0
> > [ 1093.192584]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.193395]  do_syscall_64+0x3a/0x70
> > [ 1093.194067]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.195017] RIP: 0033:0x7f8c34a7207b
> > [ 1093.195713] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.199072] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.200454] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.201776] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.203121] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.204441] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.205754] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.207095] ---[ end trace d5f6b816d902441c ]---
> > [ 1093.208039] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> > [ 1093.209609] ------------[ cut here ]------------
> > [ 1093.210483] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.212095] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.217174] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.218658] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.220280] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.221204] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.224534] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> > [ 1093.225502] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> > [ 1093.226823] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.228106] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.228952] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> > [ 1093.229726] R13: 0000000000000fdc R14: ffff888042f11740 R15: ffff88804e004738
> > [ 1093.230500] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.231391] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.232033] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.232811] Call Trace:
> > [ 1093.233115]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> > [ 1093.233742]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> > [ 1093.234349]  xfs_attr3_leaf_remove+0x2b5/0xc30 [xfs]
> > [ 1093.235001]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> > [ 1093.235628]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> > [ 1093.236273]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> > [ 1093.236891]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.237445]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.238010]  __vfs_removexattr+0x52/0x70
> > [ 1093.238460]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.239009]  vfs_removexattr+0x56/0x100
> > [ 1093.239452]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.239979]  __vfs_removexattr+0x52/0x70
> > [ 1093.240430]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.240949]  vfs_removexattr+0x56/0x100
> > [ 1093.241389]  removexattr+0x58/0x90
> > [ 1093.241786]  ? __check_object_size+0xc8/0x280
> > [ 1093.242286]  ? strncpy_from_user+0x47/0x180
> > [ 1093.242780]  ? preempt_count_add+0x50/0xa0
> > [ 1093.243252]  ? __mnt_want_write+0x65/0x90
> > [ 1093.243708]  path_removexattr+0x9e/0xc0
> > [ 1093.244153]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.244647]  do_syscall_64+0x3a/0x70
> > [ 1093.245064]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.245630] RIP: 0033:0x7f8c34a7207b
> > [ 1093.246047] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.248025] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.248843] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.249621] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.250395] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.251191] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.251976] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.252753] ---[ end trace d5f6b816d902441d ]---
> > [ 1093.253282] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> > [ 1093.254223] ------------[ cut here ]------------
> > [ 1093.254758] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.255762] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.258748] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.259642] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.260604] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.261200] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.263184] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> > [ 1093.263763] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> > [ 1093.264536] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.265315] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.266116] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> > [ 1093.266907] R13: 0000000000000058 R14: ffff888042f11740 R15: ffff88804e004738
> > [ 1093.267675] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.268544] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.269178] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.269949] Call Trace:
> > [ 1093.270244]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> > [ 1093.270888]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> > [ 1093.271490]  xfs_attr3_leaf_remove+0x2ef/0xc30 [xfs]
> > [ 1093.272129]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> > [ 1093.272759]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> > [ 1093.273400]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> > [ 1093.274015]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.274562]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.275139]  __vfs_removexattr+0x52/0x70
> > [ 1093.275592]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.276117]  vfs_removexattr+0x56/0x100
> > [ 1093.276558]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.277085]  __vfs_removexattr+0x52/0x70
> > [ 1093.277534]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.278063]  vfs_removexattr+0x56/0x100
> > [ 1093.278506]  removexattr+0x58/0x90
> > [ 1093.278934]  ? __check_object_size+0xc8/0x280
> > [ 1093.279435]  ? strncpy_from_user+0x47/0x180
> > [ 1093.279919]  ? preempt_count_add+0x50/0xa0
> > [ 1093.280384]  ? __mnt_want_write+0x65/0x90
> > [ 1093.280843]  path_removexattr+0x9e/0xc0
> > [ 1093.281290]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.281788]  do_syscall_64+0x3a/0x70
> > [ 1093.282208]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.282792] RIP: 0033:0x7f8c34a7207b
> > [ 1093.283216] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.285191] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.286027] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.286822] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.287614] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.288396] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.289174] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.289956] ---[ end trace d5f6b816d902441e ]---
> > [ 1093.290487] XFS: Assertion failed: bp->b_transp == tp, file: fs/xfs/xfs_trans_buf.c, line: 450
> > [ 1093.291444] ------------[ cut here ]------------
> > [ 1093.291980] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.292978] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.295967] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.296855] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.297814] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.298412] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.300398] RSP: 0018:ffffc90001a0f988 EFLAGS: 00010246
> > [ 1093.300987] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> > [ 1093.301761] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.302541] RBP: ffff88804e9fee00 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.303328] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> > [ 1093.304107] R13: 0000000000000000 R14: ffff888042f11740 R15: ffff88804e004738
> > [ 1093.304878] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.305743] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.306377] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.307172] Call Trace:
> > [ 1093.307470]  xfs_trans_dirty_buf+0xbe/0x120 [xfs]
> > [ 1093.308100]  xfs_trans_log_buf+0x4c/0x100 [xfs]
> > [ 1093.308700]  xfs_attr3_leaf_remove+0x3b6/0xc30 [xfs]
> > [ 1093.309333]  ? xfs_trans_add_item+0x6b/0x180 [xfs]
> > [ 1093.309971]  xfs_attr_node_removename+0x3d/0x90 [xfs]
> > [ 1093.310614]  xfs_attr_remove_iter+0x50/0x270 [xfs]
> > [ 1093.311254]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.311809]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.312381]  __vfs_removexattr+0x52/0x70
> > [ 1093.312836]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.313367]  vfs_removexattr+0x56/0x100
> > [ 1093.313813]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.314350]  __vfs_removexattr+0x52/0x70
> > [ 1093.314820]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.315352]  vfs_removexattr+0x56/0x100
> > [ 1093.315799]  removexattr+0x58/0x90
> > [ 1093.316204]  ? __check_object_size+0xc8/0x280
> > [ 1093.316701]  ? strncpy_from_user+0x47/0x180
> > [ 1093.317187]  ? preempt_count_add+0x50/0xa0
> > [ 1093.317656]  ? __mnt_want_write+0x65/0x90
> > [ 1093.318124]  path_removexattr+0x9e/0xc0
> > [ 1093.318569]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.319083]  do_syscall_64+0x3a/0x70
> > [ 1093.319502]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.320075] RIP: 0033:0x7f8c34a7207b
> > [ 1093.320491] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.322466] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.323307] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.324092] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.324864] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.325647] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.326426] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.327224] ---[ end trace d5f6b816d902441f ]---
> > [ 1093.327751] XFS: Assertion failed: !(bip->bli_flags & XFS_BLI_LOGGED), file: fs/xfs/xfs_trans_buf.c, line: 79
> > [ 1093.328827] ------------[ cut here ]------------
> > [ 1093.329352] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.330350] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.333309] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.334209] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.335181] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.335774] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.337749] RSP: 0018:ffffc90001a0f930 EFLAGS: 00010246
> > [ 1093.338337] RAX: 0000000000000000 RBX: ffff88804e9fee00 RCX: 0000000000000000
> > [ 1093.339134] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.339920] RBP: ffff88804e004738 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.340697] R10: 000000000000000a R11: f000000000000000 R12: ffff888042f11740
> > [ 1093.341477] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
> > [ 1093.342258] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.343144] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.343779] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.344561] Call Trace:
> > [ 1093.344857]  _xfs_trans_bjoin+0x100/0x110 [xfs]
> > [ 1093.345469]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
> > [ 1093.346130]  xfs_da_read_buf+0xce/0x120 [xfs]
> > [ 1093.346714]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
> > [ 1093.347313]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
> > [ 1093.347901]  xfs_attr_node_shrink+0x54/0x100 [xfs]
> > [ 1093.348514]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
> > [ 1093.349129]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.349675]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.350237]  __vfs_removexattr+0x52/0x70
> > [ 1093.350684]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.351228]  vfs_removexattr+0x56/0x100
> > [ 1093.351667]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.352194]  __vfs_removexattr+0x52/0x70
> > [ 1093.352642]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.353165]  vfs_removexattr+0x56/0x100
> > [ 1093.353603]  removexattr+0x58/0x90
> > [ 1093.354003]  ? __check_object_size+0xc8/0x280
> > [ 1093.354493]  ? strncpy_from_user+0x47/0x180
> > [ 1093.354983]  ? preempt_count_add+0x50/0xa0
> > [ 1093.355452]  ? __mnt_want_write+0x65/0x90
> > [ 1093.355914]  path_removexattr+0x9e/0xc0
> > [ 1093.356353]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.356840]  do_syscall_64+0x3a/0x70
> > [ 1093.357258]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.357819] RIP: 0033:0x7f8c34a7207b
> > [ 1093.358236] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.360210] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.361031] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.361800] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.362574] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.363361] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.364137] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.364912] ---[ end trace d5f6b816d9024420 ]---
> > [ 1093.365425] XFS: Assertion failed: !test_bit(XFS_LI_DIRTY, &lip->li_flags), file: fs/xfs/xfs_trans.c, line: 657
> > [ 1093.366508] ------------[ cut here ]------------
> > [ 1093.367045] WARNING: CPU: 3 PID: 12697 at fs/xfs/xfs_message.c:112 assfail+0x3c/0x40 [xfs]
> > [ 1093.368050] Modules linked in: xfs libcrc32c ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_tcpudp ip_set_hash_ip ip_set_hash_net xt_set ip_set_hash_mac ip_set nfnetlink bfq ip6table_filter ip6_tables iptable_filter pvpanic_mmio pvpanic sch_fq_codel ip_tables x_tables overlay nfsv4 af_packet [last unloaded: xfs]
> > [ 1093.371056] CPU: 3 PID: 12697 Comm: attr Tainted: G        W         5.13.0-rc2-djwx #rc2
> > [ 1093.371941] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> > [ 1093.372891] RIP: 0010:assfail+0x3c/0x40 [xfs]
> > [ 1093.373477] Code: 48 a2 3f a0 e8 81 f9 ff ff 8a 1d 7b e9 0b 00 80 fb 01 76 0f 0f b6 f3 48 c7 c7 a0 57 49 a0 e8 db c9 00 e1 80 e3 01 74 02 0f 0b <0f> 0b 5b c3 48 8d 45 10 48 89 e2 4c 89 e6 48 89 1c 24 48 89 44 24
> > [ 1093.375457] RSP: 0018:ffffc90001a0f900 EFLAGS: 00010246
> > [ 1093.376042] RAX: 0000000000000000 RBX: ffff88804e004700 RCX: 0000000000000000
> > [ 1093.376811] RDX: 00000000ffffffc0 RSI: 0000000000000000 RDI: ffffffffa03ea6d5
> > [ 1093.377584] RBP: ffff888042f11740 R08: 0000000000000000 R09: 000000000000000a
> > [ 1093.378361] R10: 000000000000000a R11: f000000000000000 R12: ffff88804e004748
> > [ 1093.379147] R13: 0000000000000001 R14: ffffc90001a0f9e0 R15: ffffffffa03daaa0
> > [ 1093.379926] FS:  00007f8c3494f740(0000) GS:ffff88807e100000(0000) knlGS:0000000000000000
> > [ 1093.380796] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 1093.381427] CR2: 00007f8c34a57710 CR3: 000000004b455005 CR4: 00000000001706a0
> > [ 1093.382201] Call Trace:
> > [ 1093.382497]  xfs_trans_add_item+0x171/0x180 [xfs]
> > [ 1093.383137]  _xfs_trans_bjoin+0x72/0x110 [xfs]
> > [ 1093.383732]  xfs_trans_read_buf_map+0x22b/0x4a0 [xfs]
> > [ 1093.384395]  xfs_da_read_buf+0xce/0x120 [xfs]
> > [ 1093.384973]  xfs_attr3_leaf_read+0x26/0x60 [xfs]
> > [ 1093.385567]  ? xfs_attr_is_leaf+0x76/0x90 [xfs]
> > [ 1093.386162]  xfs_attr_node_shrink+0x54/0x100 [xfs]
> > [ 1093.386789]  xfs_attr_remove_iter+0xa9/0x270 [xfs]
> > [ 1093.387402]  xfs_attr_set+0x2ff/0x430 [xfs]
> > [ 1093.387953]  xfs_xattr_set+0x89/0xd0 [xfs]
> > [ 1093.388507]  __vfs_removexattr+0x52/0x70
> > [ 1093.388959]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.389476]  vfs_removexattr+0x56/0x100
> > [ 1093.389919]  ovl_xattr_set+0x131/0x1d0 [overlay]
> > [ 1093.390437]  __vfs_removexattr+0x52/0x70
> > [ 1093.390902]  __vfs_removexattr_locked+0xb8/0x140
> > [ 1093.391420]  vfs_removexattr+0x56/0x100
> > [ 1093.391856]  removexattr+0x58/0x90
> > [ 1093.392257]  ? __check_object_size+0xc8/0x280
> > [ 1093.392747]  ? strncpy_from_user+0x47/0x180
> > [ 1093.393223]  ? preempt_count_add+0x50/0xa0
> > [ 1093.393684]  ? __mnt_want_write+0x65/0x90
> > [ 1093.394145]  path_removexattr+0x9e/0xc0
> > [ 1093.394582]  __x64_sys_lremovexattr+0x14/0x20
> > [ 1093.395095]  do_syscall_64+0x3a/0x70
> > [ 1093.395508]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> > [ 1093.396072] RIP: 0033:0x7f8c34a7207b
> > [ 1093.396478] Code: 73 01 c3 48 8b 0d 15 ae 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 c6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 ad 0c 00 f7 d8 64 89 01 48
> > [ 1093.398426] RSP: 002b:00007ffc9f3248f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000c6
> > [ 1093.399254] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f8c34a7207b
> > [ 1093.400032] RDX: 0000000000000072 RSI: 00007ffc9f324910 RDI: 00007ffc9f3261a0
> > [ 1093.400800] RBP: 00007ffc9f326196 R08: 0000000000000000 R09: 00007ffc9f324910
> > [ 1093.401571] R10: 00007f8c34b3dbe0 R11: 0000000000000202 R12: 00007ffc9f3261a0
> > [ 1093.402343] R13: 00007ffc9f324910 R14: 0000000000000000 R15: 0000000000000001
> > [ 1093.403130] ---[ end trace d5f6b816d9024421 ]---
> > [ 1093.565232] XFS (sdc): Unmounting Filesystem
> > [ 1093.604852] [U] TEST FINISHED: -overlay generic/020 @ Wed May 26 10:34:41 PDT 2021
> > 
> > The first assertion, I think, is an accounting problem -- the ASSERT
> > checks that args->rmtblkno should be zero after calling the function
> > __xfs_attr_rmtval_remove to unmap the blocks backing the remote value
> > from the attr fork.  I don't see anywhere in that function that actually
> > updates the args fields, however.
> > 
> > AFAICT all this needs is a little bookkeeping update in
> > __xfs_attr_rmtval_remove.
> > 
> > The second and subsequent assertions come from trying to log a buffer
> > that isn't attached to the current transaction.  I think what's
> > happening is:
> > 
> > 1. we're in state XFS_DAS_RMTBLK
> > 2. call __xfs_attr_rmtval_remove to remove a remote block, which returns 0
> > 3. call xfs_attr_refillstate to re-attach buffers to the da state
> > 4. set state to XFS_DAS_RM_NAME
> > 5. set XFS_DAC_DEFER_FINISH and return EAGAIN to finish deferred updates
> > 6. <transaction roll releases buffers>
> > 7. now we're in state XFS_DAS_RM_NAME
> > 8. call xfs_attr_node_removename to remove the name
> > 9. trip assert because the buffers in state->path.blk[] aren't joined to the
> >     current transaction
> > 
> > I think the solution here is to call xfs_attr_refillstate to reattach
> > all the buffers to the transaction, but only if we've freshly rolled the
> > transaction.  If we fell through the UNINIT and RMTBLK cases into
> > RM_NAME without rolling anything, then we're still on the same
> > transaction that we used for the first lookup and don't need to refill
> > the state.
> > 
> > Can you take a look at this patch?  It fixes the problems for that one
> > test, but I haven't run it through QA yet.
> Ok, it seems to be doing ok so far in other tests.  (at least for me!)
> Should I just add this to another patch at the end?  Thank you for the
> catch!

It seems to have passed an overnight fstests run.

The changes ought to be integrated into the appropriate parts of the
patch stack because we're not supposed to leave logic bombs for people
running bisections.  My guess is that they /probably/ belong in "Add
delay ready attr remove routines" because that's where the xattr code
transitions to the state machine, but ultimately the decision is up to
you. :)

--D

> 
> Allison
> 
> > 
> > --D
> > 
> > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> > index 20b1e3c6bdd0..7b3d0c3d2e65 100644
> > --- a/fs/xfs/libxfs/xfs_attr.c
> > +++ b/fs/xfs/libxfs/xfs_attr.c
> > @@ -1442,6 +1442,17 @@ xfs_attr_remove_iter(
> >   		/* fallthrough */
> >   	case XFS_DAS_RM_NAME:
> > +
> > +		/*
> > +		 * If we came here fresh from a transaction roll, reattach all
> > +		 * the buffers to the current transaction.
> > +		 */
> > +		if (dac->dela_state == XFS_DAS_RM_NAME) {
> > +			error = xfs_attr_refillstate(state);
> > +			if (error)
> > +				goto out;
> > +		}
> > +
> >   		retval = xfs_attr_node_removename(args, state);
> >   		/*
> > diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> > index b5bc50cad9bf..d560b55abedb 100644
> > --- a/fs/xfs/libxfs/xfs_attr_remote.c
> > +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> > @@ -699,5 +699,8 @@ __xfs_attr_rmtval_remove(
> >   		return -EAGAIN;
> >   	}
> > -	return error;
> > +	/* We've unmapped the remote value blocks, so zero these out */
> > +	args->rmtblkno = 0;
> > +	args->rmtblkcnt = 0;
> > +	return 0;
> >   }
> > 

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2021-05-27 17:00 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 19:54 [PATCH v19 00/14] Delay Ready Attributes Allison Henderson
2021-05-25 19:54 ` [PATCH v19 01/14] xfs: Reverse apply 72b97ea40d Allison Henderson
2021-05-25 19:54 ` [PATCH v19 02/14] xfs: Add xfs_attr_node_remove_name Allison Henderson
2021-05-25 19:54 ` [PATCH v19 03/14] xfs: Refactor xfs_attr_set_shortform Allison Henderson
2021-05-25 19:54 ` [PATCH v19 04/14] xfs: Separate xfs_attr_node_addname and xfs_attr_node_addname_clear_incomplete Allison Henderson
2021-05-25 19:54 ` [PATCH v19 05/14] xfs: Add helper xfs_attr_node_addname_find_attr Allison Henderson
2021-05-25 19:54 ` [PATCH v19 06/14] xfs: Hoist xfs_attr_node_addname Allison Henderson
2021-05-25 19:54 ` [PATCH v19 07/14] xfs: Hoist xfs_attr_leaf_addname Allison Henderson
2021-05-25 19:54 ` [PATCH v19 08/14] xfs: Hoist node transaction handling Allison Henderson
2021-05-25 19:54 ` [PATCH v19 09/14] xfs: Add delay ready attr remove routines Allison Henderson
2021-05-25 19:55 ` [PATCH v19 10/14] xfs: Add delay ready attr set routines Allison Henderson
2021-05-25 19:55 ` [PATCH v19 11/14] xfs: Remove xfs_attr_rmtval_set Allison Henderson
2021-05-25 20:34   ` Darrick J. Wong
2021-05-27  6:13   ` Chandan Babu R
2021-05-25 19:55 ` [PATCH v19 12/14] xfs: Clean up xfs_attr_node_addname_clear_incomplete Allison Henderson
2021-05-25 20:35   ` Darrick J. Wong
2021-05-27  7:03   ` Chandan Babu R
2021-05-25 19:55 ` [PATCH v19 13/14] xfs: Remove default ASSERT in xfs_attr_set_iter Allison Henderson
2021-05-25 20:52   ` Darrick J. Wong
2021-05-26 18:13     ` Allison Henderson
2021-05-27  7:40       ` Chandan Babu R
2021-05-25 19:55 ` [PATCH v19 14/14] xfs: Make attr name schemes consistent Allison Henderson
2021-05-25 20:36   ` Darrick J. Wong
2021-05-27  8:01   ` Chandan Babu R
2021-05-26 18:19 ` [PATCH v19 00/14] Delay Ready Attributes Darrick J. Wong
2021-05-27 16:54   ` Allison Henderson
2021-05-27 17:00     ` Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.