aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/send.c19
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)