From: Dave Chinner <david@fromorbit.com>
To: Eric Sandeen <sandeen@sandeen.net>
Cc: Jie Liu <jeff.liu@oracle.com>, xfs-oss <xfs@oss.sgi.com>
Subject: Re: [PATCH] xfs: fix agno increment in xfs_inumbers() loop
Date: Mon, 13 Oct 2014 09:35:16 +1100 [thread overview]
Message-ID: <20141012223516.GB5267@dastard> (raw)
In-Reply-To: <543AC7C9.5040503@sandeen.net>
On Sun, Oct 12, 2014 at 01:26:17PM -0500, Eric Sandeen wrote:
> commit c7cb51d xfs: fix error handling at xfs_inumbers
> caused a regression in xfs_inumbers, which in turn broke
> xfsdump, causing incomplete dumps.
>
> The loop in xfs_inumbers() needs to fill the user-supplied
> buffers, and iterates via xfs_btree_increment, reading new
> ags as needed.
>
> But the first time through the loop, if xfs_btree_increment()
> succeeds, we continue, which triggers the ++agno at the bottom
> of the loop, and we skip to soon to the next ag - without
> the proper setup under next_ag to read the next ag.
>
> Fix this by removing the agno increment from the loop conditional,
> and only increment agno if we have actually hit the code under
> the next_ag: target.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>
> p.s. it's alarming that apparently no test in the dump group
> detects this problem! I'll look into it.
The dump tests must not create more than an inode chunks worth
of files in each AG. Yup, see common/dump::_mk_fillconfig1() - maybe
35 files?
> So I can say that I've tested this with xfstests, but I guess
> that doesn't matter much, yet.
>
> diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
> index f71be9c..f1deb96 100644
> --- a/fs/xfs/xfs_itable.c
> +++ b/fs/xfs/xfs_itable.c
> @@ -639,7 +639,8 @@ next_ag:
> xfs_buf_relse(agbp);
> agbp = NULL;
> agino = 0;
> - } while (++agno < mp->m_sb.sb_agcount);
> + agno++;
> + } while (agno < mp->m_sb.sb_agcount);
Yeah, it fixes the bug, but I don't like the structure of the code
that leads to it. What we actually have it two loops in one:
do {
while (inobt records exist) {
/* format record */
}
} while (++agno < mp->m_sb.sb_agcount)
But the inner loop is not implemented as a loop, it's implemented
split across two iterations on the outer loop (i.e. increment in
one iteration, formatting in the next). Hence the bug.
The code should really be further factored to:
do {
/* read agi */
error = xfs_ialloc_read_agi(agno, &agbp)
if (error)
break;
error = xfs_inumbers_ag(...);
if (error)
break;
xfs_buf_relse(agbp);
agino = 0;
agno++;
} while (agno < mp->m_sb.sb_agcount)
So that the AG is traversed and records processed within it's own
cursor-based traversal loop inside xfs_inumbers_ag(), not split
across the outer ag scope loop.
I'll take the first patch right away, but can you follow up with
the above refactoring, Eric?
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
prev parent reply other threads:[~2014-10-12 22:35 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-12 18:26 [PATCH] xfs: fix agno increment in xfs_inumbers() loop Eric Sandeen
2014-10-12 22:35 ` Dave Chinner [this message]
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=20141012223516.GB5267@dastard \
--to=david@fromorbit.com \
--cc=jeff.liu@oracle.com \
--cc=sandeen@sandeen.net \
--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