diff mbox series

[2/4] xfs: don't leak the retained da state when doing a leaf to node conversion

Message ID 165267192341.625255.6169607924858686457.stgit@magnolia (mailing list archive)
State Accepted, archived
Headers show
Series xfs: fix leaks and validation errors in logged xattr updates | expand

Commit Message

Darrick J. Wong May 16, 2022, 3:32 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

If a setxattr operation finds an xattr structure in leaf format, adding
the attr can fail due to lack of space and hence requires an upgrade to
node format.  After this happens, we'll roll the transaction and
re-enter the state machine, at which time we need to perform a second
lookup of the attribute name to find its new location.  This lookup
attaches a new da state structure to the xfs_attr_item but doesn't free
the old one (from the leaf lookup) and leaks it.  Fix that.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/libxfs/xfs_attr.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Comments

Allison Henderson May 16, 2022, 11:56 p.m. UTC | #1
On Sun, 2022-05-15 at 20:32 -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> If a setxattr operation finds an xattr structure in leaf format,
> adding
> the attr can fail due to lack of space and hence requires an upgrade
> to
> node format.  After this happens, we'll roll the transaction and
> re-enter the state machine, at which time we need to perform a second
> lookup of the attribute name to find its new location.  This lookup
> attaches a new da state structure to the xfs_attr_item but doesn't
> free
> the old one (from the leaf lookup) and leaks it.  Fix that.
> 
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Ok, makes sense
Reviewed-by: Allison Henderson <allison.henderson@oracle.com>

> ---
>  fs/xfs/libxfs/xfs_attr.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 2da24954b2d7..499a15480b57 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -1401,8 +1401,10 @@ xfs_attr_node_hasname(
>  	int			retval, error;
>  
>  	state = xfs_da_state_alloc(args);
> -	if (statep != NULL)
> +	if (statep != NULL) {
> +		ASSERT(*statep == NULL);
>  		*statep = state;
> +	}
>  
>  	/*
>  	 * Search to see if name exists, and get back a pointer to it.
> @@ -1428,6 +1430,10 @@ xfs_attr_node_addname_find_attr(
>  	struct xfs_da_args	*args = attr->xattri_da_args;
>  	int			error;
>  
> +	if (attr->xattri_da_state)
> +		xfs_da_state_free(attr->xattri_da_state);
> +	attr->xattri_da_state = NULL;
> +
>  	/*
>  	 * Search to see if name already exists, and get back a pointer
>  	 * to where it should go.
> @@ -1593,7 +1599,7 @@ STATIC int
>  xfs_attr_node_get(
>  	struct xfs_da_args	*args)
>  {
> -	struct xfs_da_state	*state;
> +	struct xfs_da_state	*state = NULL;
>  	struct xfs_da_state_blk	*blk;
>  	int			i;
>  	int			error;
>
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 2da24954b2d7..499a15480b57 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -1401,8 +1401,10 @@  xfs_attr_node_hasname(
 	int			retval, error;
 
 	state = xfs_da_state_alloc(args);
-	if (statep != NULL)
+	if (statep != NULL) {
+		ASSERT(*statep == NULL);
 		*statep = state;
+	}
 
 	/*
 	 * Search to see if name exists, and get back a pointer to it.
@@ -1428,6 +1430,10 @@  xfs_attr_node_addname_find_attr(
 	struct xfs_da_args	*args = attr->xattri_da_args;
 	int			error;
 
+	if (attr->xattri_da_state)
+		xfs_da_state_free(attr->xattri_da_state);
+	attr->xattri_da_state = NULL;
+
 	/*
 	 * Search to see if name already exists, and get back a pointer
 	 * to where it should go.
@@ -1593,7 +1599,7 @@  STATIC int
 xfs_attr_node_get(
 	struct xfs_da_args	*args)
 {
-	struct xfs_da_state	*state;
+	struct xfs_da_state	*state = NULL;
 	struct xfs_da_state_blk	*blk;
 	int			i;
 	int			error;