public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Russell Cattelan <cattelan@thebarn.com>
To: lachlan@sgi.com
Cc: Eric Sandeen <sandeen@sandeen.net>, xfs@oss.sgi.com
Subject: Re: REVIEW: Fix for incore extent corruption.
Date: Fri, 19 Sep 2008 08:03:12 -0700	[thread overview]
Message-ID: <48D3BF30.60508@thebarn.com> (raw)
In-Reply-To: <48D31B9A.1080803@sgi.com>

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.

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?
>>
>>
>>
>>
>

  parent reply	other threads:[~2008-09-19 15:01 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 [this message]
2008-09-22  2:33                 ` Lachlan McIlroy

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=48D3BF30.60508@thebarn.com \
    --to=cattelan@thebarn.com \
    --cc=lachlan@sgi.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