|
@@ -3559,6 +3559,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
|
|
|
{
|
|
|
int ret = 0;
|
|
|
u64 ino = parent_ref->dir;
|
|
|
+ u64 ino_gen = parent_ref->dir_gen;
|
|
|
u64 parent_ino_before, parent_ino_after;
|
|
|
struct fs_path *path_before = NULL;
|
|
|
struct fs_path *path_after = NULL;
|
|
@@ -3579,6 +3580,8 @@ static int wait_for_parent_move(struct send_ctx *sctx,
|
|
|
* at get_cur_path()).
|
|
|
*/
|
|
|
while (ino > BTRFS_FIRST_FREE_OBJECTID) {
|
|
|
+ u64 parent_ino_after_gen;
|
|
|
+
|
|
|
if (is_waiting_for_move(sctx, ino)) {
|
|
|
/*
|
|
|
* If the current inode is an ancestor of ino in the
|
|
@@ -3601,7 +3604,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
|
|
|
fs_path_reset(path_after);
|
|
|
|
|
|
ret = get_first_ref(sctx->send_root, ino, &parent_ino_after,
|
|
|
- NULL, path_after);
|
|
|
+ &parent_ino_after_gen, path_after);
|
|
|
if (ret < 0)
|
|
|
goto out;
|
|
|
ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before,
|
|
@@ -3618,10 +3621,20 @@ static int wait_for_parent_move(struct send_ctx *sctx,
|
|
|
if (ino > sctx->cur_ino &&
|
|
|
(parent_ino_before != parent_ino_after || len1 != len2 ||
|
|
|
memcmp(path_before->start, path_after->start, len1))) {
|
|
|
- ret = 1;
|
|
|
- break;
|
|
|
+ u64 parent_ino_gen;
|
|
|
+
|
|
|
+ ret = get_inode_info(sctx->parent_root, ino, NULL,
|
|
|
+ &parent_ino_gen, NULL, NULL, NULL,
|
|
|
+ NULL);
|
|
|
+ if (ret < 0)
|
|
|
+ goto out;
|
|
|
+ if (ino_gen == parent_ino_gen) {
|
|
|
+ ret = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
ino = parent_ino_after;
|
|
|
+ ino_gen = parent_ino_after_gen;
|
|
|
}
|
|
|
|
|
|
out:
|