return ret;
 }
 
+static struct fs_path *get_cur_inode_path(struct send_ctx *sctx)
+{
+       if (fs_path_len(&sctx->cur_inode_path) == 0) {
+               int ret;
+
+               ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen,
+                                  &sctx->cur_inode_path);
+               if (ret < 0)
+                       return ERR_PTR(ret);
+       }
+
+       return &sctx->cur_inode_path;
+}
+
+static struct fs_path *get_path_for_command(struct send_ctx *sctx, u64 ino, u64 gen)
+{
+       struct fs_path *path;
+       int ret;
+
+       if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen)
+               return get_cur_inode_path(sctx);
+
+       path = fs_path_alloc();
+       if (!path)
+               return ERR_PTR(-ENOMEM);
+
+       ret = get_cur_path(sctx, ino, gen, path);
+       if (ret < 0) {
+               fs_path_free(path);
+               return ERR_PTR(ret);
+       }
+
+       return path;
+}
+
+static void free_path_for_command(const struct send_ctx *sctx, struct fs_path *path)
+{
+       if (path != &sctx->cur_inode_path)
+               fs_path_free(path);
+}
+
 static int send_truncate(struct send_ctx *sctx, u64 ino, u64 gen, u64 size)
 {
        struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
 
        btrfs_debug(fs_info, "send_truncate %llu size=%llu", ino, size);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_path_for_command(sctx, ino, gen);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_TRUNCATE);
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, ino, gen, p);
-       if (ret < 0)
-               goto out;
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_SIZE, size);
 
 
 tlv_put_failure:
 out:
-       fs_path_free(p);
+       free_path_for_command(sctx, p);
        return ret;
 }
 
 
        btrfs_debug(fs_info, "send_chmod %llu mode=%llu", ino, mode);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_path_for_command(sctx, ino, gen);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_CHMOD);
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, ino, gen, p);
-       if (ret < 0)
-               goto out;
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_MODE, mode & 07777);
 
 
 tlv_put_failure:
 out:
-       fs_path_free(p);
+       free_path_for_command(sctx, p);
        return ret;
 }
 
 
        btrfs_debug(fs_info, "send_fileattr %llu fileattr=%llu", ino, fileattr);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_path_for_command(sctx, ino, gen);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_FILEATTR);
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, ino, gen, p);
-       if (ret < 0)
-               goto out;
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_FILEATTR, fileattr);
 
 
 tlv_put_failure:
 out:
-       fs_path_free(p);
+       free_path_for_command(sctx, p);
        return ret;
 }
 
        btrfs_debug(fs_info, "send_chown %llu uid=%llu, gid=%llu",
                    ino, uid, gid);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_path_for_command(sctx, ino, gen);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_CHOWN);
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, ino, gen, p);
-       if (ret < 0)
-               goto out;
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_UID, uid);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_GID, gid);
 
 tlv_put_failure:
 out:
-       fs_path_free(p);
+       free_path_for_command(sctx, p);
        return ret;
 }
 
 
        btrfs_debug(fs_info, "send_utimes %llu", ino);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_path_for_command(sctx, ino, gen);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        path = alloc_path_for_send();
        if (!path) {
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, ino, gen, p);
-       if (ret < 0)
-               goto out;
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_ATIME, eb, &ii->atime);
        TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_MTIME, eb, &ii->mtime);
 
 tlv_put_failure:
 out:
-       fs_path_free(p);
+       free_path_for_command(sctx, p);
        btrfs_free_path(path);
        return ret;
 }
        struct fs_path *path;
        int ret;
 
-       path = fs_path_alloc();
-       if (!path)
-               return -ENOMEM;
-
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, path);
-       if (ret < 0)
-               goto out;
+       path = get_cur_inode_path(sctx);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
        if (ret < 0)
 
 tlv_put_failure:
 out:
-       fs_path_free(path);
-
        return ret;
 }
 
                                   const char *name, int name_len,
                                   const char *data, int data_len, void *ctx)
 {
-       int ret;
        struct send_ctx *sctx = ctx;
        struct fs_path *p;
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
-
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-       if (ret < 0)
-               goto out;
-
-       ret = send_remove_xattr(sctx, p, name, name_len);
+       p = get_cur_inode_path(sctx);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
-out:
-       fs_path_free(p);
-       return ret;
+       return send_remove_xattr(sctx, p, name, name_len);
 }
 
 static int process_new_xattr(struct send_ctx *sctx)
        if (ret < 0)
                goto iput;
 
-       p = fs_path_alloc();
-       if (!p) {
-               ret = -ENOMEM;
+       p = get_cur_inode_path(sctx);
+       if (IS_ERR(p)) {
+               ret = PTR_ERR(p);
                goto iput;
        }
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-       if (ret < 0)
-               goto free_path;
 
        ret = send_verity(sctx, p, sctx->verity_descriptor);
-       if (ret < 0)
-               goto free_path;
-
-free_path:
-       fs_path_free(p);
 iput:
        iput(inode);
        return ret;
        int ret = 0;
        struct fs_path *p;
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
-
        btrfs_debug(fs_info, "send_write offset=%llu, len=%d", offset, len);
 
-       ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
-       if (ret < 0)
-               goto out;
+       p = get_cur_inode_path(sctx);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
+       ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
        if (ret < 0)
-               goto out;
+               return ret;
 
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
        ret = put_file_data(sctx, offset, len);
        if (ret < 0)
-               goto out;
+               return ret;
 
        ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-       fs_path_free(p);
        return ret;
 }
 
 {
        int ret = 0;
        struct fs_path *p;
+       struct fs_path *cur_inode_path;
        u64 gen;
 
        btrfs_debug(sctx->send_root->fs_info,
                    offset, len, btrfs_root_id(clone_root->root),
                    clone_root->ino, clone_root->offset);
 
+       cur_inode_path = get_cur_inode_path(sctx);
+       if (IS_ERR(cur_inode_path))
+               return PTR_ERR(cur_inode_path);
+
        p = fs_path_alloc();
        if (!p)
                return -ENOMEM;
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-       if (ret < 0)
-               goto out;
-
        TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
-       TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
+       TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, cur_inode_path);
 
        if (clone_root->root == sctx->send_root) {
                ret = get_inode_gen(sctx->send_root, clone_root->ino, &gen);
        int ret = 0;
        struct fs_path *p;
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
+       p = get_cur_inode_path(sctx);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
 
        ret = begin_cmd(sctx, BTRFS_SEND_C_UPDATE_EXTENT);
        if (ret < 0)
-               goto out;
-
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-       if (ret < 0)
-               goto out;
+               return ret;
 
        TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
        TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
        ret = send_cmd(sctx);
 
 tlv_put_failure:
-out:
-       fs_path_free(p);
        return ret;
 }
 
        if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
                return send_update_extent(sctx, offset, end - offset);
 
-       p = fs_path_alloc();
-       if (!p)
-               return -ENOMEM;
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
-       if (ret < 0)
-               goto tlv_put_failure;
+       p = get_cur_inode_path(sctx);
+       if (IS_ERR(p))
+               return PTR_ERR(p);
+
        while (offset < end) {
                u64 len = min(end - offset, read_size);
 
        }
        sctx->cur_inode_next_write_offset = offset;
 tlv_put_failure:
-       fs_path_free(p);
        return ret;
 }
 
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
-       fspath = fs_path_alloc();
-       if (!fspath) {
-               ret = -ENOMEM;
+       fspath = get_cur_inode_path(sctx);
+       if (IS_ERR(fspath)) {
+               ret = PTR_ERR(fspath);
                goto out;
        }
 
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-       if (ret < 0)
-               goto out;
-
        btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
        ram_bytes = btrfs_file_extent_ram_bytes(leaf, ei);
 
 tlv_put_failure:
 out:
-       fs_path_free(fspath);
        iput(inode);
        return ret;
 }
        if (IS_ERR(inode))
                return PTR_ERR(inode);
 
-       fspath = fs_path_alloc();
-       if (!fspath) {
-               ret = -ENOMEM;
+       fspath = get_cur_inode_path(sctx);
+       if (IS_ERR(fspath)) {
+               ret = PTR_ERR(fspath);
                goto out;
        }
 
        if (ret < 0)
                goto out;
 
-       ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
-       if (ret < 0)
-               goto out;
-
        btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
        disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, ei);
 
 tlv_put_failure:
 out:
-       fs_path_free(fspath);
        iput(inode);
        return ret;
 }