All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 2/8] xfs: fix efi item leak on forced shutdown
Date: Thu, 27 Jan 2011 11:35:23 +1100	[thread overview]
Message-ID: <20110127003523.GB21311@dastard> (raw)
In-Reply-To: <20110125235354.GA3832@infradead.org>

On Tue, Jan 25, 2011 at 06:53:54PM -0500, Christoph Hellwig wrote:
> On Tue, Jan 25, 2011 at 07:50:38PM +1100, Dave Chinner wrote:
> > diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> > index 75f2ef6..effbb41 100644
> > --- a/fs/xfs/xfs_extfree_item.c
> > +++ b/fs/xfs/xfs_extfree_item.c
> > @@ -138,7 +138,6 @@ xfs_efi_item_unpin(
> >  
> >  	if (remove) {
> >  		ASSERT(!(lip->li_flags & XFS_LI_IN_AIL));
> > -		xfs_trans_del_item(lip);
> >  		xfs_efi_item_free(efip);
> >  		return;
> >  	}
> 
> >  STATIC void
> >  xfs_trans_uncommit(
> >  	struct xfs_trans	*tp,
> >  	uint			flags)
> >  {
> > -	struct xfs_log_item_desc *lidp;
> > +	struct xfs_log_item_desc *lidp, *n;
> >  
> > -	list_for_each_entry(lidp, &tp->t_items, lid_trans) {
> > +	list_for_each_entry_safe(lidp, n, &tp->t_items, lid_trans) {
> >  		/*
> >  		 * Unpin all but those that aren't dirty.
> >  		 */
> > -		if (lidp->lid_flags & XFS_LID_DIRTY)
> > +		if (lidp->lid_flags & XFS_LID_DIRTY) {
> > +			xfs_trans_del_item(lidp->lid_item);
> >  			IOP_UNPIN(lidp->lid_item, 1);
> > +		}
> 
> This part of the patch isn't explained in the changelog, and I suspect
> it should be a separate patch from the addition of the IOP_UNPIN with
> remove call to the CIL error path.

Doing xfs_trans_del_item() inside IOP_UNPIN() during CIl commit
faliure processing causes a panic - there is not descriptior or
trransaction attached to the item at that point. Hence it is simply
not safe to call IOP_UNPIN(aborted) from outside a transaction
context if we allow xfs_trans_del_item() to be run inside the
IOP_UNPIN() call.

Further, if we do xfs_trans_del_item() inside the IOP_UNPIN(aborted)
path, we corrupt the list walk in xfs_trans_uncommit() case. Hence
it needs to be an list_for_each_entry_safe() walk, and must do
explicit removal of the item from the transaction because the item
can be freed in IOP_UNPIN(aborted).

> Moving the xfs_trans_del_item from the IOP_UNPIN implementation into
> the caller seems sane to me, but:
> 
>  - why is the call to xfs_trans_del_item left in xfs_buf_item_unpin

Because I didn't notice it. It never triggers in the
xfs_trans_uncommit() case as there are two references on the buf
item - one for the pin, and one for the lock. We call IOP_UNPIN()
first, so it never goes down the (freed && stale) path in this case.

As to why it hasn't triggered from a iclog write completion or CIL
checkpoint failure after the IOP_UNLOCK() has been run and dropped
that reference - just luck I guess....

>  - why did xfs_buf_item_unpin get away only calling it for the stale
>    case, and the other log item implementations completely without
>    it

The stale buffer case is special - it has a different lifecycle to
all other buffer items (and all other log item types, for that
matter). Basically a stale buffer never enters the AIL on
transaction commit, so on the last reference going away it needs to
be freed rather than continuing to live while being tracked in the
AIL.

> I suspect the answer lies in xfs_trans_free_items opencoding the
> call to xfs_trans_del_item, thus avoiding any leak of log item
> descriptors or log items on the transaction list.

Actually, I don't think it does handle this case - we've already
removed all the dirty items from the transaction, so it appears to
me like they just get leaked.

> By adding the
> call of xfs_trans_del_item to xfs_trans_uncommit we thus skip
> the calls to IOP_UNLOCK for dirty log items, which is a large
> change in behaviour for the existing log items that didn't have
> the xfs_trans_del_item calls, and at least for the dquot and
> inode items seems incorrect.

You are right, it does break xfs_trans_free_items() and the way it
calls IOP_UNLOCK(). I'm surprised that it didn't cause any noticable
leaks of locked buffers....

----

Effectively, we've got a situation where we need to allow
xfs_trans_del_item() to be called in IOP_UNPIN(aborted) iff there is
a log item descriptor attached to the log item. That requires
xfs_trans_uncommit() to do a safe list traversal and both the efi
and buf items to check for a valid lidp before calling
xfs_trans_del_item(). I'll change the fix and commment it better in
the code and changelog.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2011-01-27  0:33 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-25  8:50 [PATCH 0/8] xfs: 2.6.38-rc candidate fixes V2 Dave Chinner
2011-01-25  8:50 ` [PATCH 1/8] xfs: fix log ticket leak on forced shutdown Dave Chinner
2011-01-26 21:22   ` Alex Elder
2011-01-25  8:50 ` [PATCH 2/8] xfs: fix efi item " Dave Chinner
2011-01-25 23:53   ` Christoph Hellwig
2011-01-27  0:35     ` Dave Chinner [this message]
2011-01-26 21:22   ` Alex Elder
2011-01-25  8:50 ` [PATCH 3/8] xfs: speculative delayed allocation uses rounddown_power_of_2 badly Dave Chinner
2011-01-26 21:22   ` Alex Elder
2011-01-25  8:50 ` [PATCH 4/8] xfs: limit extent length for allocation to AG size Dave Chinner
2011-01-26 21:22   ` Alex Elder
2011-01-27  0:38     ` Dave Chinner
2011-01-25  8:50 ` [PATCH 5/8] xfs: prevent extsize alignment from exceeding maximum extent size Dave Chinner
2011-01-25  9:49   ` Christoph Hellwig
2011-01-26 21:22   ` Alex Elder
2011-01-27  0:50     ` Dave Chinner
2011-01-25  8:50 ` [PATCH 6/8] xfs: limit extsize to size of AGs and/or MAXEXTLEN Dave Chinner
2011-01-26 21:23   ` Alex Elder
2011-01-25  8:50 ` [PATCH 7/8] xfs: handle CIl transaction commit failures correctly Dave Chinner
2011-01-25  9:53   ` Christoph Hellwig
2011-01-26 21:23   ` Alex Elder
2011-01-25  8:50 ` [PATCH 8/8] xfs: fix dquot shaker deadlock Dave Chinner
2011-01-25  9:52   ` Christoph Hellwig
2011-01-27  1:54     ` Dave Chinner
2011-01-27  2:24       ` Dave Chinner
2011-01-26 21:23   ` Alex Elder
2011-01-25  9:20 ` [PATCH 0/8] xfs: 2.6.38-rc candidate fixes V2 Christoph Hellwig
2011-01-26 21:23 ` Alex Elder
2011-01-27  3:53 [PATCH 0/8] xfs: candidate 2.6.38-rc fixes V3 Dave Chinner
2011-01-27  3:53 ` [PATCH 2/8] xfs: fix efi item leak on forced shutdown Dave Chinner
2011-01-28 14:54   ` Alex Elder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110127003523.GB21311@dastard \
    --to=david@fromorbit.com \
    --cc=hch@infradead.org \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.