From: Lachlan McIlroy <lachlan@sgi.com>
To: Russell Cattelan <cattelan@thebarn.com>
Cc: Eric Sandeen <sandeen@sandeen.net>, xfs@oss.sgi.com
Subject: Re: REVIEW: Fix for incore extent corruption.
Date: Mon, 22 Sep 2008 12:33:03 +1000 [thread overview]
Message-ID: <48D703DF.6000105@sgi.com> (raw)
In-Reply-To: <48D3BF30.60508@thebarn.com>
Russell Cattelan wrote:
> Lachlan McIlroy wrote:
>> Here's a patch to remove xfs_iext_irec_compact_full() like Russell
>> did in his original patch - are you guys happy with this?
>>
>> I'm putting it through it's paces now and so far it looks good.
> I guess looking at my original patch it would have made sense to
> drop the call to xfs_iext_irec_irec_compact_pages/full in
> xfs_iext_indirect_to_direct or do what you did and keep the
> if else logic.
Ah, I see what you did now. That does simplify the code a bit but
on the other hand it will result in calling xfs_iext_irec_compact_pages()
more often - every time we remove an extent instead of when the buffer
utilisation drops below 50%.
>
> So ya this look good.
>
>
>>
>> --- a/fs/xfs/xfs_inode.c 2008-09-19 13:08:08.000000000 +1000
>> +++ b/fs/xfs/xfs_inode.c 2008-09-19 13:16:34.000000000 +1000
>> @@ -4157,7 +4166,7 @@ xfs_iext_indirect_to_direct(
>> ASSERT(nextents <= XFS_LINEAR_EXTS);
>> size = nextents * sizeof(xfs_bmbt_rec_t);
>>
>> - xfs_iext_irec_compact_full(ifp);
>> + xfs_iext_irec_compact_pages(ifp);
>> ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
>>
>> ep = ifp->if_u1.if_ext_irec->er_extbuf;
>> @@ -4510,8 +4519,6 @@ xfs_iext_irec_compact(
>> xfs_iext_direct_to_inline(ifp, nextents);
>> } else if (nextents <= XFS_LINEAR_EXTS) {
>> xfs_iext_indirect_to_direct(ifp);
>> - } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) {
>> - xfs_iext_irec_compact_full(ifp);
>> } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
>> xfs_iext_irec_compact_pages(ifp);
>> }
>> @@ -4555,91 +4562,6 @@ xfs_iext_irec_compact_pages(
>> }
>>
>> /*
>> - * Fully compact the extent records managed by the indirection array.
>> - */
>> -void
>> -xfs_iext_irec_compact_full(
>> - xfs_ifork_t *ifp) /* inode fork pointer */
>> -{
>> - xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */
>> - xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */
>> - int erp_idx = 0; /* extent irec index */
>> - int ext_avail; /* empty entries in ex list */
>> - int ext_diff; /* number of exts to add */
>> - int nlists; /* number of irec's (ex lists) */
>> -
>> - ASSERT(ifp->if_flags & XFS_IFEXTIREC);
>> -
>> - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
>> - erp = ifp->if_u1.if_ext_irec;
>> - ep = &erp->er_extbuf[erp->er_extcount];
>> - erp_next = erp + 1;
>> - ep_next = erp_next->er_extbuf;
>> -
>> - while (erp_idx < nlists - 1) {
>> - /*
>> - * Check how many extent records are available in this irec.
>> - * If there is none skip the whole exercise.
>> - */
>> - ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
>> - if (ext_avail) {
>> -
>> - /*
>> - * Copy over as many as possible extent records into
>> - * the previous page.
>> - */
>> - ext_diff = MIN(ext_avail, erp_next->er_extcount);
>> - memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
>> - erp->er_extcount += ext_diff;
>> - erp_next->er_extcount -= ext_diff;
>> -
>> - /*
>> - * If the next irec is empty now we can simply
>> - * remove it.
>> - */
>> - if (erp_next->er_extcount == 0) {
>> - /*
>> - * Free page before removing extent record
>> - * so er_extoffs don't get modified in
>> - * xfs_iext_irec_remove.
>> - */
>> - kmem_free(erp_next->er_extbuf);
>> - erp_next->er_extbuf = NULL;
>> - xfs_iext_irec_remove(ifp, erp_idx + 1);
>> - erp = &ifp->if_u1.if_ext_irec[erp_idx];
>> - nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
>> -
>> - /*
>> - * If the next irec is not empty move up the content
>> - * that has not been copied to the previous page to
>> - * the beggining of this one.
>> - */
>> - } else {
>> - memmove(erp_next->er_extbuf, &ep_next[ext_diff],
>> - erp_next->er_extcount *
>> - sizeof(xfs_bmbt_rec_t));
>> - ep_next = erp_next->er_extbuf;
>> - memset(&ep_next[erp_next->er_extcount], 0,
>> - (XFS_LINEAR_EXTS -
>> - erp_next->er_extcount) *
>> - sizeof(xfs_bmbt_rec_t));
>> - }
>> - }
>> -
>> - if (erp->er_extcount == XFS_LINEAR_EXTS) {
>> - erp_idx++;
>> - if (erp_idx < nlists)
>> - erp = &ifp->if_u1.if_ext_irec[erp_idx];
>> - else
>> - break;
>> - }
>> - ep = &erp->er_extbuf[erp->er_extcount];
>> - erp_next = erp + 1;
>> - ep_next = erp_next->er_extbuf;
>> - }
>> -}
>> -
>> -/*
>> * This is called to update the er_extoff field in the indirection
>> * array when extents have been added or removed from one of the
>> * extent lists. erp_idx contains the irec index to begin updating
>>
>>
>> Lachlan McIlroy wrote:
>>> Eric Sandeen wrote:
>>>> Russell Cattelan wrote:
>>>>> Lachlan McIlroy wrote:
>>>>>> Russell, this fixes xfs_iext_irec_compact_full(). If we don't move
>>>>>> all the records from the next page into the current page then we need
>>>>>> to update the er_extoff of the modified page as we move the remaining
>>>>>> extents up. Would you mind giving it a go?
>>>>>>
>>>>>> --- a/fs/xfs/xfs_inode.c 2008-09-18 18:48:46.000000000 +1000
>>>>>> +++ b/fs/xfs/xfs_inode.c 2008-09-18 18:57:18.000000000 +1000
>>>>>> @@ -4623,6 +4623,7 @@ xfs_iext_irec_compact_full(
>>>>>> (XFS_LINEAR_EXTS -
>>>>>> erp_next->er_extcount) *
>>>>>> sizeof(xfs_bmbt_rec_t));
>>>>>> + erp_next->er_extoff += ext_diff;
>>>>>> }
>>>>>> }
>>>>>>
>>>>> Cool I'll give it some run through when I done traveling.
>>>>>
>>>>> I still think compact_full should simply be eliminated since
>>>>> it really doesn't help, and it's obviously confusing code.
>>>>> Or we should make sure it works and get rid of compact_pages
>>>>> since compact_full behaves just like compact_pages when not
>>>>> doing partial moves.
>>>>
>>>> I'd agree with that, at least as far as reevaluating this packing
>>>> stuff -
>>>> given the seriousness of the bug when you do hit it, and how rarely
>>>> it's
>>>> ever hit, apparently this chunk of code is almost never run ....
>>>>
>>>
>>> I agree too. If any code is difficult to reach it's also difficult
>>> to test.
>>> We've had numerous reports of extent corruption that could be
>>> explained by
>>> this bug but we have not been able to reproduce the symptoms let
>>> alone devise
>>> a reliable test case.
>>>
>>> What real benefit does compact_full have over compact_pages?
>>> Are there corner cases where compact_pages is not good enough?
>>>
>>>
>>>
>>>
>>
>
>
prev parent reply other threads:[~2008-09-22 2:22 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-18 0:02 REVIEW: Fix for incore extent corruption Russell Cattelan
2008-09-18 3:38 ` Lachlan McIlroy
2008-09-18 4:45 ` Russell Cattelan
2008-09-18 7:02 ` Lachlan McIlroy
2008-09-18 9:00 ` Lachlan McIlroy
2008-09-18 18:30 ` Eric Sandeen
2008-09-18 19:28 ` Eric Sandeen
2008-09-19 0:59 ` Lachlan McIlroy
2008-09-19 0:55 ` Lachlan McIlroy
2008-09-19 7:01 ` Eric Sandeen
2008-09-22 2:08 ` Lachlan McIlroy
2008-09-18 21:34 ` Russell Cattelan
2008-09-18 22:20 ` Eric Sandeen
2008-09-19 0:51 ` Lachlan McIlroy
2008-09-19 3:25 ` Lachlan McIlroy
2008-09-19 6:23 ` Eric Sandeen
2008-09-19 15:15 ` Russell Cattelan
2008-09-22 2:17 ` Lachlan McIlroy
2008-09-19 15:03 ` Russell Cattelan
2008-09-22 2:33 ` Lachlan McIlroy [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=48D703DF.6000105@sgi.com \
--to=lachlan@sgi.com \
--cc=cattelan@thebarn.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