[PATCH v4 44/46] btrfs: deal with encrypted symlinks in send

Josef Bacik
2023-12-01T22:12:52Z

Send needs to send the decrypted value of the symlinks, handle the case
where the inode is encrypted and decrypt the symlink name into a buffer
and copy this buffer into our fs_path struct.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
fs/btrfs/send.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 3b929f0e8f04..ee5ea16423bb 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1732,9 +1732,8 @@ static int find_extent_clone(struct send_ctx *sctx,
return ret;
}

-static int read_symlink(struct btrfs_root *root,
- u64 ino,
- struct fs_path *dest)
+static int read_symlink_unencrypted(struct btrfs_root *root, u64 ino,
+ struct fs_path *dest)
{
int ret;
struct btrfs_path *path;
@@ -1800,6 +1799,48 @@ static int read_symlink(struct btrfs_root *root,
return ret;
}

+static int read_symlink_encrypted(struct btrfs_root *root, u64 ino,
+ struct fs_path *dest)
+{
+ DEFINE_DELAYED_CALL(done);
+ const char *buf;
+ struct page *page;
+ struct inode *inode;
+ int ret = 0;
+
+ inode = btrfs_iget(root->fs_info->sb, ino, root);
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+ page = read_mapping_page(inode->i_mapping, 0, NULL);
+ if (IS_ERR(page)) {
+ ret = PTR_ERR(page);
+ goto out;
+ }
+
+ buf = fscrypt_get_symlink(inode, page_address(page),
+ BTRFS_MAX_INLINE_DATA_SIZE(root->fs_info),
+ &done);
+ if (IS_ERR(buf))
+ goto out_page;
+ ret = fs_path_add(dest, buf, strlen(buf));
+out_page:
+ put_page(page);
+ do_delayed_call(&done);
+out:
+ iput(inode);
+ return ret;
+}
+
+
+static int read_symlink(struct btrfs_root *root, u64 ino,
+ struct fs_path *dest)
+{
+ if (btrfs_fs_incompat(root->fs_info, ENCRYPT))
+ return read_symlink_encrypted(root, ino, dest);
+ return read_symlink_unencrypted(root, ino, dest);
+}
+
/*
* Helper function to generate a file name that is unique in the root of
* send_root and parent_root. This is used to generate names for orphan inodes.
--
2.41.0