diff options
-rw-r--r-- | fs/btrfs/send.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index d3f3b43cae0b..0efc2e2f253c 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1668,6 +1668,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
1668 | u64 *who_ino, u64 *who_gen) | 1668 | u64 *who_ino, u64 *who_gen) |
1669 | { | 1669 | { |
1670 | int ret = 0; | 1670 | int ret = 0; |
1671 | u64 gen; | ||
1671 | u64 other_inode = 0; | 1672 | u64 other_inode = 0; |
1672 | u8 other_type = 0; | 1673 | u8 other_type = 0; |
1673 | 1674 | ||
@@ -1678,6 +1679,24 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
1678 | if (ret <= 0) | 1679 | if (ret <= 0) |
1679 | goto out; | 1680 | goto out; |
1680 | 1681 | ||
1682 | /* | ||
1683 | * If we have a parent root we need to verify that the parent dir was | ||
1684 | * not delted and then re-created, if it was then we have no overwrite | ||
1685 | * and we can just unlink this entry. | ||
1686 | */ | ||
1687 | if (sctx->parent_root) { | ||
1688 | ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, | ||
1689 | NULL, NULL, NULL); | ||
1690 | if (ret < 0 && ret != -ENOENT) | ||
1691 | goto out; | ||
1692 | if (ret) { | ||
1693 | ret = 0; | ||
1694 | goto out; | ||
1695 | } | ||
1696 | if (gen != dir_gen) | ||
1697 | goto out; | ||
1698 | } | ||
1699 | |||
1681 | ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, | 1700 | ret = lookup_dir_item_inode(sctx->parent_root, dir, name, name_len, |
1682 | &other_inode, &other_type); | 1701 | &other_inode, &other_type); |
1683 | if (ret < 0 && ret != -ENOENT) | 1702 | if (ret < 0 && ret != -ENOENT) |