u64 cur_inode_rdev;
        u64 cur_inode_last_extent;
        u64 cur_inode_next_write_offset;
+       struct fs_path cur_inode_path;
        bool cur_inode_new;
        bool cur_inode_new_gen;
        bool cur_inode_deleted;
        *p->start = 0;
 }
 
+static void init_path(struct fs_path *p)
+{
+       p->reversed = 0;
+       p->buf = p->inline_buf;
+       p->buf_len = FS_PATH_INLINE_SIZE;
+       fs_path_reset(p);
+}
+
 static struct fs_path *fs_path_alloc(void)
 {
        struct fs_path *p;
        p = kmalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
                return NULL;
-       p->reversed = 0;
-       p->buf = p->inline_buf;
-       p->buf_len = FS_PATH_INLINE_SIZE;
-       fs_path_reset(p);
+       init_path(p);
        return p;
 }
 
        p->reversed = 0;
 }
 
+static inline bool is_current_inode_path(const struct send_ctx *sctx,
+                                        const struct fs_path *path)
+{
+       const struct fs_path *cur = &sctx->cur_inode_path;
+
+       return (strncmp(path->start, cur->start, fs_path_len(cur)) == 0);
+}
+
 static struct btrfs_path *alloc_path_for_send(void)
 {
        struct btrfs_path *path;
        u64 parent_inode = 0;
        u64 parent_gen = 0;
        int stop = 0;
+       const bool is_cur_inode = (ino == sctx->cur_ino && gen == sctx->cur_inode_gen);
+
+       if (is_cur_inode && fs_path_len(&sctx->cur_inode_path) > 0) {
+               if (dest != &sctx->cur_inode_path)
+                       return fs_path_copy(dest, &sctx->cur_inode_path);
+
+               return 0;
+       }
 
        name = fs_path_alloc();
        if (!name) {
 
 out:
        fs_path_free(name);
-       if (!ret)
+       if (!ret) {
                fs_path_unreverse(dest);
+               if (is_cur_inode && dest != &sctx->cur_inode_path)
+                       ret = fs_path_copy(&sctx->cur_inode_path, dest);
+       }
+
        return ret;
 }
 
                goto out;
 
        ret = send_rename(sctx, path, orphan);
+       if (ret < 0)
+               goto out;
+
+       if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+               ret = fs_path_copy(&sctx->cur_inode_path, orphan);
 
 out:
        fs_path_free(orphan);
        if (ret < 0)
                return ret;
 
+       ret = fs_path_copy(&sctx->cur_inode_path, new_path);
+       if (ret < 0)
+               return ret;
+
        return fs_path_copy(current_path, new_path);
 }
 
                                if (ret > 0) {
                                        orphanized_ancestor = true;
                                        fs_path_reset(valid_path);
+                                       fs_path_reset(&sctx->cur_inode_path);
                                        ret = get_cur_path(sctx, sctx->cur_ino,
                                                           sctx->cur_inode_gen,
                                                           valid_path);
                                ret = send_unlink(sctx, cur->full_path);
                                if (ret < 0)
                                        goto out;
+                               if (is_current_inode_path(sctx, cur->full_path))
+                                       fs_path_reset(&sctx->cur_inode_path);
                        }
                        ret = dup_ref(cur, &check_dirs);
                        if (ret < 0)
        sctx->cur_inode_last_extent = (u64)-1;
        sctx->cur_inode_next_write_offset = 0;
        sctx->ignore_cur_inode = false;
+       fs_path_reset(&sctx->cur_inode_path);
 
        /*
         * Set send_progress to current inode. This will tell all get_cur_xxx
                goto out;
        }
 
+       init_path(&sctx->cur_inode_path);
        INIT_LIST_HEAD(&sctx->new_refs);
        INIT_LIST_HEAD(&sctx->deleted_refs);
 
                btrfs_lru_cache_clear(&sctx->dir_created_cache);
                btrfs_lru_cache_clear(&sctx->dir_utimes_cache);
 
+               if (sctx->cur_inode_path.buf != sctx->cur_inode_path.inline_buf)
+                       kfree(sctx->cur_inode_path.buf);
+
                kfree(sctx);
        }