Re: [PATCH] Btrfs-progs: fsck: disable --init-extent-tree option when using snapshots

Shilong Wang
2014-03-17T12:21:07Z

Hi Josef,

Thanks for your information ^_^, i have just finished codes and it passed
my simple test and i will do more tests about rebuilding extent tree
with snapshots before
i send out patches.

Thanks,
Wang

2014-03-14 22:36 GMT+08:00 Josef Bacik <jbacik@fb.com>:
> On 03/14/2014 09:36 AM, Wang Shilong wrote:
>> Hi Josef,
>>
>> Just ping this again.
>>
>> Did you have any good ideas to rebuild extent tree if broken
>> filesystem is filled with snapshots.?
>>
>> I was working on this recently, i was blocked that i can not verify
>> if an extent is *FULL BACKREF* mode or not. As a *FULL BACKREF*
>> extent's refs can be 1 and more than 1..
>>
>> I am willing to test codes or have a try if you could give me some
>> advice etc.
>>
>
> Full backrefs aren't too hard. Basically all you have to do is walk
> down the fs tree and keep track of btrfs_header_owner(eb) for
> everything we walk into. If btrfs_header_owner(eb) == root->objectid
> for the tree we are walking down then we need a ye olde normal backref
> for this block. If btrfs_header_owner(eb) != root->objectid we _may_
> need a full backref, it depends on who owns the parent block. The
> following may be incomplete, I'm kind of sick
>
> 1) We walk down the original tree, every eb we encounter has
> btrfs_header_owner(eb) == root->objectid. We add normal references
> for this root (BTRFS_TREE_BLOCK_REF_KEY) for this root. World peace
> is achieved.
>
> 2) We walk down the snapshotted tree. Say we didn't change anything
> at all, it was just a clean snapshot and then boom. So the
> btrfs_header_owner(root->node) == root->objectid, so normal backref.
> We walk down to the next level, where btrfs_header_owner(eb) !=
> root->objectid, but the level above did, so we add normal refs for all
> of these blocks. We go down the next level, now our
> btrfs_header_owner(parent) != root->objectid and
> btrfs_header_owner(eb) != root->objectid. This is where we need to
> now go back and see if btrfs_header_owner(eb) currently has a ref on
> eb. If it does we are done, move on to the next block in this same
> level, we don't have to go further down.
>
> 3) Harder case, we snapshotted and then changed things in the original
> root. Do the same thing as in step 2, but now we get down to
> btrfs_header_level(eb) != root->objectid && btrfs_header_level(parent)
> != root->objectid. We lookup the references we have for eb and notice
> that btrfs_header_owner(eb) no longer refers to eb. So now we must
> set FULL_BACKREF on this extent reference and add a
> SHARED_BLOCK_REF_KEY for this eb using the parent->start as the
> offset. And we need to keep walking down and doing the same thing
> until we either hit level 0 or btrfs_header_owner(eb) has a ref on the
> block.
>
> 4) Not really a whole special case, just something to keep in mind, if
> btrfs_header_owner(parent) == root->objectid but
> btrfs_header_owner(eb) != root->objectid that means we have a normal
> TREE_BLOCK_REF on eb, it's only when the parent doesn't match our
> current root that it's a problem.
>
>
> Does that make sense? Thanks,
>
> Josef