From: Dave Chinner <david@fromorbit.com>
To: Ben Myers <bpm@sgi.com>
Cc: xfs@oss.sgi.com, aelder@sgi.com
Subject: Re: [PATCH] xfs_bmap_add_extent_delay_real should set br_startblock to nullstartblock
Date: Wed, 19 Jan 2011 15:42:18 +1100 [thread overview]
Message-ID: <20110119044218.GM16267@dastard> (raw)
In-Reply-To: <20110118203629.5531.1390.stgit@lady3jane.americas.sgi.com>
On Tue, Jan 18, 2011 at 02:36:29PM -0600, Ben Myers wrote:
> When filling in the middle of a previous delayed allocation in
> xfs_bmap_add_extent_delay_real, set br_startblock of the new delay extent to
> the right to nullstartblock instead of 0 before inserting the extent into the
> ifork (xfs_iext_insert), rather than setting br_startblock afterward.
>
> Adding the extent into the ifork with br_startblock=0 can lead to the extent
> being copied into the btree by xfs_bmap_extent_to_btree if we happen to convert
> from extents format to btree format before updating br_startblock with the
> correct value. The unexpected addition of this delay extent to the btree can
> cause subsequent XFS_WANT_CORRUPTED_GOTO filesystem shutdown in several
> xfs_bmap_add_extent_delay_real cases where we are converting a delay extent to
> real and unexpectedly find an extent already inserted. For example:
>
> 911 case BMAP_LEFT_FILLING:
> 912 /*
> 913 * Filling in the first part of a previous delayed allocation.
> 914 * The left neighbor is not contiguous.
> 915 */
> 916 trace_xfs_bmap_pre_update(ip, idx, state, _THIS_IP_);
> 917 xfs_bmbt_set_startoff(ep, new_endoff);
> 918 temp = PREV.br_blockcount - new->br_blockcount;
> 919 xfs_bmbt_set_blockcount(ep, temp);
> 920 xfs_iext_insert(ip, idx, 1, new, state);
> 921 ip->i_df.if_lastex = idx;
> 922 ip->i_d.di_nextents++;
> 923 if (cur == NULL)
> 924 rval = XFS_ILOG_CORE | XFS_ILOG_DEXT;
> 925 else {
> 926 rval = XFS_ILOG_CORE;
> 927 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
> 928 new->br_startblock, new->br_blockcount,
> 929 &i)))
> 930 goto done;
> 931 XFS_WANT_CORRUPTED_GOTO(i == 0, done);
>
> With the bogus extent in the btree we shutdown the filesystem at 931. The
> conversion from extents to btree format happens when the number of extents in
> the inode increases above ip->i_df.if_ext_max. xfs_bmap_extent_to_btree copies
> extents from the ifork into the btree, ignoring all delalloc extents which are
> denoted by br_startblock having some value of nullstartblock.
>
> SGI-PV: 1013221
>
> Signed-off-by: Ben Myers <bpm@sgi.com>
> ---
> fs/xfs/xfs_bmap.c | 11 ++++++-----
> 1 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
> index 4111cd3..754259f 100644
> --- a/fs/xfs/xfs_bmap.c
> +++ b/fs/xfs/xfs_bmap.c
> @@ -1040,13 +1040,14 @@ xfs_bmap_add_extent_delay_real(
> * This case is avoided almost all the time.
> */
> temp = new->br_startoff - PREV.br_startoff;
> + temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
> trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
> - xfs_bmbt_set_blockcount(ep, temp);
> - r[0] = *new;
> - r[1].br_state = PREV.br_state;
> - r[1].br_startblock = 0;
> + xfs_bmbt_set_blockcount(ep, temp); /* PREV becomes LEFT */
> + r[0] = *new; /* r[0] becomes MIDDLE */
> + r[1].br_state = PREV.br_state; /* r[1] is RIGHT */
> + r[1].br_startblock = nullstartblock(
> + (int)xfs_bmap_worst_indlen(ip, temp2));
> r[1].br_startoff = new_endoff;
> - temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
> r[1].br_blockcount = temp2;
> xfs_iext_insert(ip, idx + 1, 2, &r[0], state);
> ip->i_df.if_lastex = idx + 1;
I'd still prefer that you replace r[?] with PREV/LEFT/RIGHT rather
than the array notation to be consistent with the rest of the code,
and add a comment something like this:
/*
* We start with:
*
* +ddddddddddddddddddddddddddddddddddddddddddddddddd+
* PREV @ idx
*
* and we are allocating:
* +rrrrrrrrrrrrrrr+
* new
*
* and we set it up for insertion as:
*
* +ddddddddddddddddddd+rrrrrrrrrrrrrrr+ddddddddddddd+
* new
* PREV @ idx LEFT RIGHT
* inserted @ idx + 1
*/
So that there is no ambiguity about the case being handled and how
it is executed....
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:[~2011-01-19 4:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-18 20:36 [PATCH] xfs_bmap_add_extent_delay_real should set br_startblock to nullstartblock Ben Myers
2011-01-19 4:42 ` Dave Chinner [this message]
-- strict thread matches above, loose matches on Subject: below --
2011-01-19 17:41 Ben Myers
2011-01-24 22:04 ` Dave Chinner
2011-01-27 18:52 ` 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=20110119044218.GM16267@dastard \
--to=david@fromorbit.com \
--cc=aelder@sgi.com \
--cc=bpm@sgi.com \
--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