btrfs: send: factor out common logic when sending xattrs

We always send xattrs for the current inode only and both callers of
send_set_xattr() pass a path for the current inode. So move the path
allocation and computation to send_set_xattr(), reducing duplicated
code. This also facilitates an upcoming patch.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2025-02-11 11:01:15 +00:00 committed by David Sterba
parent 91e9139e5b
commit 17f6a74d0b

View file

@ -4844,11 +4844,19 @@ static int process_all_refs(struct send_ctx *sctx,
}
static int send_set_xattr(struct send_ctx *sctx,
struct fs_path *path,
const char *name, int name_len,
const char *data, int data_len)
{
int ret = 0;
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;
ret = begin_cmd(sctx, BTRFS_SEND_C_SET_XATTR);
if (ret < 0)
@ -4862,6 +4870,8 @@ static int send_set_xattr(struct send_ctx *sctx,
tlv_put_failure:
out:
fs_path_free(path);
return ret;
}
@ -4889,19 +4899,13 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
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;
struct posix_acl_xattr_header dummy_acl;
/* Capabilities are emitted by finish_inode_if_needed */
if (!strncmp(name, XATTR_NAME_CAPS, name_len))
return 0;
p = fs_path_alloc();
if (!p)
return -ENOMEM;
/*
* This hack is needed because empty acls are stored as zero byte
* data in xattrs. Problem with that is, that receiving these zero byte
@ -4918,15 +4922,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
}
}
ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
if (ret < 0)
goto out;
ret = send_set_xattr(sctx, p, name, name_len, data, data_len);
out:
fs_path_free(p);
return ret;
return send_set_xattr(sctx, name, name_len, data, data_len);
}
static int __process_deleted_xattr(int num, struct btrfs_key *di_key,
@ -5803,7 +5799,6 @@ static int send_extent_data(struct send_ctx *sctx, struct btrfs_path *path,
*/
static int send_capabilities(struct send_ctx *sctx)
{
struct fs_path *fspath = NULL;
struct btrfs_path *path;
struct btrfs_dir_item *di;
struct extent_buffer *leaf;
@ -5829,25 +5824,19 @@ static int send_capabilities(struct send_ctx *sctx)
leaf = path->nodes[0];
buf_len = btrfs_dir_data_len(leaf, di);
fspath = fs_path_alloc();
buf = kmalloc(buf_len, GFP_KERNEL);
if (!fspath || !buf) {
if (!buf) {
ret = -ENOMEM;
goto out;
}
ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
if (ret < 0)
goto out;
data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
read_extent_buffer(leaf, buf, data_ptr, buf_len);
ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
ret = send_set_xattr(sctx, XATTR_NAME_CAPS,
strlen(XATTR_NAME_CAPS), buf, buf_len);
out:
kfree(buf);
fs_path_free(fspath);
btrfs_free_path(path);
return ret;
}