On Fri, Nov 17, 2017 at 02:48:30PM +0000, fdman...@kernel.org wrote:
> From: Filipe Manana <fdman...@suse.com>
> 
> Under some circumstances, an incremental send operation can issue wrong
> paths for unlink commands related to files that have multiple hard links
> and some (or all) of those links were renamed between the parent and send
> snapshots. Consider the following example:
> 
> Parent snapshot
> 
>  .                                                      (ino 256)
>  |---- a/                                               (ino 257)
>  |     |---- b/                                         (ino 259)
>  |     |     |---- c/                                   (ino 260)
>  |     |     |---- f2                                   (ino 261)
>  |     |
>  |     |---- f2l1                                       (ino 261)
>  |
>  |---- d/                                               (ino 262)
>        |---- f1l1_2                                     (ino 258)
>        |---- f2l2                                       (ino 261)
>        |---- f1_2                                       (ino 258)
> 
> Send snapshot
> 
>  .                                                      (ino 256)
>  |---- a/                                               (ino 257)
>  |     |---- f2l1/                                      (ino 263)
>  |             |---- b2/                                (ino 259)
>  |                   |---- c/                           (ino 260)
>  |                   |     |---- d3                     (ino 262)
>  |                   |           |---- f1l1_2           (ino 258)
>  |                   |           |---- f2l2_2           (ino 261)
>  |                   |           |---- f1_2             (ino 258)
>  |                   |
>  |                   |---- f2                           (ino 261)
>  |                   |---- f1l2                         (ino 258)
>  |
>  |---- d                                                (ino 261)
> 
> When computing the incremental send stream the following steps happen:
> 
> 1) When processing inode 261, a rename operation is issued that renames
>    inode 262, which currently as a path of "d", to an orphan name of
>    "o262-7-0". This is done because in the send snapshot, inode 261 has
>    of its hard links with a path of "d" as well.
> 
> 2) Two link operations are issued that create the new hard links for
>    inode 261, whose names are "d" and "f2l2_2", at paths "/" and
>    "o262-7-0/" respectively.
> 
> 3) Still while processing inode 261, unlink operations are issued to
>    remove the old hard links of inode 261, with names "f2l1" and "f2l2",
>    at paths "a/" and "d/". However path "d/" does not correspond anymore
>    to the directory inode 262 but corresponds instead to a hard link of
>    inode 261 (link command issued in the previous step). This makes the
>    receiver fail with a ENOTDIR error when attempting the unlink
>    operation.
> 
> The problem happens because before sending the unlink operation, we failed
> to detect that inode 262 was one of ancestors for inode 261 in the parent
> snapshot, and therefore we didn't recompute the path for inode 262 before
> issuing the unlink operation for the link named "f2l2" of inode 262. The
> detection failed because the function "is_ancestor()" only follows the
> first hard link it finds for an inode instead of all of its hard links
> (as it was originally created for being used with directories only, for
> which only one hard link exists). So fix this by making "is_ancestor()"
> follow all hard links of the input inode.
> 
> A test case for fstests follows soon.
> 
> Signed-off-by: Filipe Manana <fdman...@suse.com>

FYI, added to the rc2 pull.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to