From: Dave Chinner <david@fromorbit.com>
To: Jan Kara <jack@suse.cz>
Cc: Ben Myers <bpm@sgi.com>, Alex Elder <elder@kernel.org>, xfs@oss.sgi.com
Subject: Re: [PATCH] xfs: Fix oops on IO error during xlog_recover_process_iunlinks()
Date: Wed, 7 Mar 2012 12:17:16 +1100 [thread overview]
Message-ID: <20120307011716.GI3592@dastard> (raw)
In-Reply-To: <1331031616-31692-1-git-send-email-jack@suse.cz>
On Tue, Mar 06, 2012 at 12:00:16PM +0100, Jan Kara wrote:
> When an IO error happens during inode deletion run from
> xlog_recover_process_iunlinks() filesystem gets shutdown. Thus any subsequent
> attempt to read buffers fails. Code in xlog_recover_process_iunlinks() does not
> count with the fact that read of a buffer which was read a while ago can
> really fail which results in the oops on
> agi = XFS_BUF_TO_AGI(agibp);
>
> Fix the problem by handling error from xfs_read_agi() in all cases.
>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
> fs/xfs/xfs_log_recover.c | 15 ++++++++++++---
> 1 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index 0ed9ee7..3899264 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -3178,11 +3178,17 @@ xlog_recover_process_iunlinks(
>
> /*
> * Reacquire the agibuffer and continue around
> - * the loop. This should never fail as we know
> - * the buffer was good earlier on.
> + * the loop.
> */
> error = xfs_read_agi(mp, NULL, agno, &agibp);
> - ASSERT(error == 0);
> + /*
> + * We failed to read a buffer we succeeded
> + * reading just a while ago. Likely because the
> + * filesystem is shutdown now. Just try the
> + * next AG.
> + */
> + if (error)
> + goto next_ag;
> agi = XFS_BUF_TO_AGI(agibp);
> }
> }
That function is full of ugly code. We don't need to continually
lock and unlock the AGI in the inner loop. Indeed, we probably don't
even need to lock the buffer to read the AGI bucket entries because
we aren't going to be racing with anyone here. Hence all we really
need is an extra hold on the agi buffer to make sure it doesn't go
away once we've dropped the lock via xfs_buf_relse(). i.e.
/*
* take an extra reference to the buffer and then release it
* to drop the lock so that it can be acquired in the normal
* course of the transaction to truncate and free each
* inode. Because we are not racing with anyone else here
* for the AGI buffer, we don't even need to hold it locked
* to read the initial unlinked bucket entries out of the
* buffer.
*/
agi = XFS_BUF_TO_AGI(agibp);
xfs_buf_hold(agibp);
xfs_buf_relse(agibp);
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
agino = be32_to_cpu(agi->agi_unlinked[bucket]);
while (agino != NULLAGINO) {
agino = xlog_recover_process_one_iunlink(mp,
agno, agino, bucket);
}
}
xfs_buf_rele(agibp)
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2012-03-07 1:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-06 11:00 [PATCH] xfs: Fix oops on IO error during xlog_recover_process_iunlinks() Jan Kara
2012-03-07 1:17 ` Dave Chinner [this message]
2012-03-07 11:07 ` Jan Kara
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=20120307011716.GI3592@dastard \
--to=david@fromorbit.com \
--cc=bpm@sgi.com \
--cc=elder@kernel.org \
--cc=jack@suse.cz \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox