xfs
[Top] [All Lists]

Re: [PATCH] xfsrestore: fix multi stream support

To: Rich Johnston <rjohnston@xxxxxxx>
Subject: Re: [PATCH] xfsrestore: fix multi stream support
From: Eric Sandeen <sandeen@xxxxxxxxxxx>
Date: Tue, 01 Oct 2013 23:26:08 -0500
Cc: xfs-oss <xfs@xxxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <524B4677.40200@xxxxxxx>
References: <524AF8AE.5030300@xxxxxxx> <524B34D4.10807@xxxxxxxxxxx> <524B4119.8020005@xxxxxxx> <524B4677.40200@xxxxxxx>
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20130801 Thunderbird/17.0.8
On 10/1/13 5:02 PM, Rich Johnston wrote:

>> If partialmax != 0
>> (multi-stream) and no extents exist (entire file is a hole), is there
>> anything to restore? Nope so why call parial_reg().  If you do call it
>> you will not find anything to restore:
>>


Sorry for the scattered replies.

But simply getting here w/ no extents doesn't make us reach the comment
/* Should never get here */ below.

first:

        /* Search for a matching inode.  Gaps can exist so we must search
         * all entries. 
         */
        for (i=0; i < partialmax; i++ ) {
                if (persp->a.parrest[i].is_ino == ino) {
                        isptr = &persp->a.parrest[i];
                        break;
                }
        }

so first it tries to find to see if this inode has another stream (?)
which has partially restored it.

If not:

>> 8977         /* If not found, find a free one, fill it in and return */
>> 8978         if ( ! isptr ) {
>> 8979                 mlog(MLOG_NITTY | MLOG_NOLOCK,
>> 8980                         "partial_reg: no entry found for %llu\n",
>> ino);
>> 8981                 /* find a free one */
>> 8982                 for (i=0; i < partialmax; i++ ) {
>> 8983                         if (persp->a.parrest[i].is_ino == 0) {

find a stream which doesn't have is_ino set

>> 8984                                 int j;
>> 8985
>> 8986                                 isptr = &persp->a.parrest[i];
>> 8987                                 isptr->is_ino = ino;

set ino

>> 8988                                 persp->a.parrestcnt++;
>> 8989
>> 8990                                 /* Clear all endoffsets (this value is
>> 8991                                  * used to decide if an entry is used or
>> 8992                                  * not
>> 8993                                  */
>> 8994                                 for (j=0, bsptr=isptr->is_bs;
>> 8995                                      j < drivecnt; j++, bsptr++) {
>> 8996                                      bsptr->endoffset = 0;
>> 8997                                 }
>> 8998

etc, and go to found, and everything's fine:

>> 8999                                 goto found;
>> 9000                         }
>> 9001                 }
>> 9002
>> 9003                 /* Should never get here. */
>>
>> And we reach the dreaded comment above :)

the only way to reach that comment & the associated warning is if the first
loop I pasted finds no matching is_ino on any stream, but the 2nd loop finds
no is_ino == 0.  i.e. persp->a.parrest[i].is_ino for every stream ("i") has
a different, non-zero is_ino.  How can that happen?  (I'm not sure...)

-Eric 

<Prev in Thread] Current Thread [Next in Thread>