• Josef Bacik's avatar
    Btrfs: fix send issues related to inode number reuse · ba5e8f2e
    Josef Bacik authored
    If you are sending a snapshot and specifying a parent snapshot we will walk the
    trees and figure out where they differ and send the differences only.  The way
    we check for differences are if the leaves aren't the same and if the keys are
    not the same within the leaves.  So if neither leaf is the same (ie the leaf has
    been cow'ed from the parent snapshot) we walk each item in the send root and
    check it against the parent root.  If the items match exactly then we don't do
    anything.  This doesn't quite work for inode refs, since they will just have the
    name and the parent objectid.  If you move the file from a directory and then
    remove that directory and re-create a directory with the same inode number as
    the old directory and then move that file back into that directory we will
    assume that nothing changed and you will get errors when you try to receive.
    
    In order to fix this we need to do extra checking to see if the inode ref really
    is the same or not.  So do this by passing down BTRFS_COMPARE_TREE_SAME if the
    items match.  Then if the key type is an inode ref we can do some extra
    checking, otherwise we just keep processing.  The extra checking is to look up
    the generation of the directory in the parent volume and compare it to the
    generation of the send volume.  If they match then they are the same directory
    and we are good to go.  If they don't we have to add them to the changed refs
    list.
    
    This means we have to track the generation of the ref we're trying to lookup
    when we iterate all the refs for a particular inode.  So in the case of looking
    for new refs we have to get the generation from the parent volume, and in the
    case of looking for deleted refs we have to get the generation from the send
    volume to compare with.
    
    There was also the issue of using a ulist to keep track of the directories we
    needed to check.  Because we can get a deleted ref and a new ref for the same
    inode number the ulist won't work since it indexes based on the value.  So
    instead just dup any directory ref we find and add it to a local list, and then
    process that list as normal and do away with using a ulist for this altogether.
    
    Before we would fail all of the tests in the far-progs that related to moving
    directories (test group 32).  With this patch we now pass these tests, and all
    of the tests in the far-progs send testing suite.  Thanks,
    Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
    Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
    ba5e8f2e
send.c 109 KB