diff mbox

[v2,1/7] xfs: rework refcount cow recovery error handling

Message ID 20161010061122.GC5619@birch.djwong.org
State Accepted
Headers show

Commit Message

Darrick J. Wong Oct. 10, 2016, 6:11 a.m. UTC
The error handling in xfs_refcount_recover_cow_leftovers is confused
and can potentially leak memory, so rework it to release resources
correctly on error.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reported-by: Brian Foster <bfoster@redhat.com>
---
 fs/xfs/libxfs/xfs_refcount.c |   16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Darrick J. Wong Oct. 10, 2016, 6:21 p.m. UTC | #1
On Mon, Oct 10, 2016 at 03:21:13AM -0700, Christoph Hellwig wrote:
> On Sun, Oct 09, 2016 at 11:11:22PM -0700, Darrick J. Wong wrote:
> > The error handling in xfs_refcount_recover_cow_leftovers is confused
> > and can potentially leak memory, so rework it to release resources
> > correctly on error.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > Reported-by: Brian Foster <bfoster@redhat.com>
> > ---
> >  fs/xfs/libxfs/xfs_refcount.c |   16 ++++++----------
> >  1 file changed, 6 insertions(+), 10 deletions(-)
> > 
> > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> > index 56bfef1..955b1d9 100644
> > --- a/fs/xfs/libxfs/xfs_refcount.c
> > +++ b/fs/xfs/libxfs/xfs_refcount.c
> > @@ -1643,7 +1643,7 @@ xfs_refcount_recover_cow_leftovers(
> >  	error = xfs_btree_query_range(cur, &low, &high,
> >  			xfs_refcount_recover_extent, &debris);
> >  	if (error)
> > -		goto out_error;
> > +		goto out_cursor;
> >  	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
> >  	xfs_buf_relse(agbp);
> >  
> > @@ -1675,26 +1675,22 @@ xfs_refcount_recover_cow_leftovers(
> >  
> >  		error = xfs_trans_commit(tp);
> >  		if (error)
> > +			goto out_free;
> >  	}
> >  	goto out_free;
> 
> don't we need to also delete the cursor after a successful exit?

Gah.  Yeah.  Serves me right for trying to code patches on Sunday night.

I think Dave already made a separate fix, though, so I'll wait for the
next for-next update and see what needs to be fixed.

--D
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dave Chinner Oct. 10, 2016, 8:25 p.m. UTC | #2
On Mon, Oct 10, 2016 at 11:21:52AM -0700, Darrick J. Wong wrote:
> On Mon, Oct 10, 2016 at 03:21:13AM -0700, Christoph Hellwig wrote:
> > On Sun, Oct 09, 2016 at 11:11:22PM -0700, Darrick J. Wong wrote:
> > > The error handling in xfs_refcount_recover_cow_leftovers is confused
> > > and can potentially leak memory, so rework it to release resources
> > > correctly on error.
> > > 
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > Reported-by: Brian Foster <bfoster@redhat.com>
> > > ---
> > >  fs/xfs/libxfs/xfs_refcount.c |   16 ++++++----------
> > >  1 file changed, 6 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> > > index 56bfef1..955b1d9 100644
> > > --- a/fs/xfs/libxfs/xfs_refcount.c
> > > +++ b/fs/xfs/libxfs/xfs_refcount.c
> > > @@ -1643,7 +1643,7 @@ xfs_refcount_recover_cow_leftovers(
> > >  	error = xfs_btree_query_range(cur, &low, &high,
> > >  			xfs_refcount_recover_extent, &debris);
> > >  	if (error)
> > > -		goto out_error;
> > > +		goto out_cursor;
> > >  	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
> > >  	xfs_buf_relse(agbp);

Cursor is freed here when everything works...

I almost modified this to be:

	error = xfs_btree_query_range(cur, &low, &high,
			xfs_refcount_recover_extent, &debris);
	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
	xfs_buf_relse(agbp);
	if (error)
		goto out_free;

so the "out_cursor" branch could go away....

> > > @@ -1675,26 +1675,22 @@ xfs_refcount_recover_cow_leftovers(
> > >  
> > >  		error = xfs_trans_commit(tp);
> > >  		if (error)
> > > +			goto out_free;
> > >  	}
> > >  	goto out_free;
> > 
> > don't we need to also delete the cursor after a successful exit?
> 
> Gah.  Yeah.  Serves me right for trying to code patches on Sunday night.

It all looked ok to me - what did I miss?

Cheers,

Dave.
Darrick J. Wong Oct. 10, 2016, 9:46 p.m. UTC | #3
On Tue, Oct 11, 2016 at 07:25:28AM +1100, Dave Chinner wrote:
> On Mon, Oct 10, 2016 at 11:21:52AM -0700, Darrick J. Wong wrote:
> > On Mon, Oct 10, 2016 at 03:21:13AM -0700, Christoph Hellwig wrote:
> > > On Sun, Oct 09, 2016 at 11:11:22PM -0700, Darrick J. Wong wrote:
> > > > The error handling in xfs_refcount_recover_cow_leftovers is confused
> > > > and can potentially leak memory, so rework it to release resources
> > > > correctly on error.
> > > > 
> > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > Reported-by: Brian Foster <bfoster@redhat.com>
> > > > ---
> > > >  fs/xfs/libxfs/xfs_refcount.c |   16 ++++++----------
> > > >  1 file changed, 6 insertions(+), 10 deletions(-)
> > > > 
> > > > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
> > > > index 56bfef1..955b1d9 100644
> > > > --- a/fs/xfs/libxfs/xfs_refcount.c
> > > > +++ b/fs/xfs/libxfs/xfs_refcount.c
> > > > @@ -1643,7 +1643,7 @@ xfs_refcount_recover_cow_leftovers(
> > > >  	error = xfs_btree_query_range(cur, &low, &high,
> > > >  			xfs_refcount_recover_extent, &debris);
> > > >  	if (error)
> > > > -		goto out_error;
> > > > +		goto out_cursor;
> > > >  	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
> > > >  	xfs_buf_relse(agbp);
> 
> Cursor is freed here when everything works...
> 
> I almost modified this to be:
> 
> 	error = xfs_btree_query_range(cur, &low, &high,
> 			xfs_refcount_recover_extent, &debris);
> 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
> 	xfs_buf_relse(agbp);
> 	if (error)
> 		goto out_free;
> 
> so the "out_cursor" branch could go away....
> 
> > > > @@ -1675,26 +1675,22 @@ xfs_refcount_recover_cow_leftovers(
> > > >  
> > > >  		error = xfs_trans_commit(tp);
> > > >  		if (error)
> > > > +			goto out_free;
> > > >  	}
> > > >  	goto out_free;
> > > 
> > > don't we need to also delete the cursor after a successful exit?
> > 
> > Gah.  Yeah.  Serves me right for trying to code patches on Sunday night.
> 
> It all looked ok to me - what did I miss?

The current code in your for-next tree looks fine.

--D

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 56bfef1..955b1d9 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -1643,7 +1643,7 @@  xfs_refcount_recover_cow_leftovers(
 	error = xfs_btree_query_range(cur, &low, &high,
 			xfs_refcount_recover_extent, &debris);
 	if (error)
-		goto out_error;
+		goto out_cursor;
 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 	xfs_buf_relse(agbp);
 
@@ -1675,26 +1675,22 @@  xfs_refcount_recover_cow_leftovers(
 
 		error = xfs_trans_commit(tp);
 		if (error)
-			goto out_cancel;
+			goto out_free;
 	}
 	goto out_free;
 
 out_defer:
 	xfs_defer_cancel(&dfops);
-out_cancel:
 	xfs_trans_cancel(tp);
-
+	goto out_free;
+out_cursor:
+	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
+	xfs_buf_relse(agbp);
 out_free:
 	/* Free the leftover list */
 	list_for_each_entry_safe(rr, n, &debris, rr_list) {
 		list_del(&rr->rr_list);
 		kmem_free(rr);
 	}
-
-	return error;
-
-out_error:
-	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
-	xfs_buf_relse(agbp);
 	return error;
 }