public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
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?
>>>
>>>
>>>
>>>
>>
> 
> 

      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