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 |
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 --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;