[PATCH 1/2] erofs-utils: lib: introduce prefix-aware erofs_setxattr()
Hongbo Li
lihongbo22 at huawei.com
Mon Dec 29 23:52:39 AEDT 2025
On 2025/12/29 15:49, Gao Xiang wrote:
> Allows users to specify a predefined prefix for xattr names.
>
> Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
Reviewed-by: Hongbo Li <lihongbo22 at huawei.com>
Thanks,
Hongbo
> ---
> include/erofs/xattr.h | 5 +++--
> lib/tar.c | 2 +-
> lib/xattr.c | 45 +++++++++++++++++++++++++++++++++----------
> 3 files changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
> index 83aca44f8e44..941bed778956 100644
> --- a/include/erofs/xattr.h
> +++ b/include/erofs/xattr.h
> @@ -36,9 +36,10 @@ int erofs_xattr_insert_name_prefix(const char *prefix);
> void erofs_xattr_cleanup_name_prefixes(void);
> int erofs_xattr_flush_name_prefixes(struct erofs_importer *im, bool plain);
> int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi);
> -
> -int erofs_setxattr(struct erofs_inode *inode, char *key,
> +int erofs_setxattr(struct erofs_inode *inode, int index, const char *name,
> const void *value, size_t size);
> +int erofs_vfs_setxattr(struct erofs_inode *inode, const char *name,
> + const void *value, size_t size);
> int erofs_set_opaque_xattr(struct erofs_inode *inode);
> void erofs_clear_opaque_xattr(struct erofs_inode *inode);
> int erofs_set_origin_xattr(struct erofs_inode *inode);
> diff --git a/lib/tar.c b/lib/tar.c
> index 16da593c3df1..8aa90c7dc0d4 100644
> --- a/lib/tar.c
> +++ b/lib/tar.c
> @@ -411,7 +411,7 @@ int tarerofs_apply_xattrs(struct erofs_inode *inode, struct list_head *xattrs)
> item->kv[item->namelen] = '\0';
> erofs_dbg("Recording xattr(%s)=\"%s\" (of %u bytes) to file %s",
> item->kv, v, vsz, inode->i_srcpath);
> - ret = erofs_setxattr(inode, item->kv, v, vsz);
> + ret = erofs_vfs_setxattr(inode, item->kv, v, vsz);
> if (ret == -ENODATA)
> erofs_err("Failed to set xattr(%s)=%s to file %s",
> item->kv, v, inode->i_srcpath);
> diff --git a/lib/xattr.c b/lib/xattr.c
> index 96be0b1bede5..b6b1a5e600fb 100644
> --- a/lib/xattr.c
> +++ b/lib/xattr.c
> @@ -179,7 +179,7 @@ static struct erofs_xattr_prefix {
> const char *prefix;
> unsigned int prefix_len;
> } xattr_types[] = {
> - [EROFS_XATTR_INDEX_USER] = {
> + [0] = {""}, [EROFS_XATTR_INDEX_USER] = {
> XATTR_USER_PREFIX,
> XATTR_USER_PREFIX_LEN
> }, [EROFS_XATTR_INDEX_POSIX_ACL_ACCESS] = {
> @@ -501,22 +501,41 @@ err:
> return ret;
> }
>
> -int erofs_setxattr(struct erofs_inode *inode, char *key,
> - const void *value, size_t size)
> +int erofs_setxattr(struct erofs_inode *inode, int index,
> + const char *name, const void *value, size_t size)
> {
> struct erofs_sb_info *sbi = inode->sbi;
> - char *kvbuf;
> - unsigned int len[2];
> struct erofs_xattritem *item;
> + struct erofs_xattr_prefix *prefix = NULL;
> + struct ea_type_node *tnode;
> + unsigned int len[2];
> + int prefix_len;
> + char *kvbuf;
>
> - len[0] = strlen(key);
> + if (index & EROFS_XATTR_LONG_PREFIX) {
> + list_for_each_entry(tnode, &ea_name_prefixes, list) {
> + if (index == tnode->index) {
> + prefix = &tnode->type;
> + break;
> + }
> + }
> + } else if (index < ARRAY_SIZE(xattr_types)) {
> + prefix = &xattr_types[index];
> + }
> +
> + if (!prefix)
> + return -EINVAL;
> +
> + prefix_len = prefix->prefix_len;
> + len[0] = prefix_len + strlen(name);
> len[1] = size;
>
> kvbuf = malloc(EROFS_XATTR_KVSIZE(len));
> if (!kvbuf)
> return -ENOMEM;
>
> - memcpy(kvbuf, key, EROFS_XATTR_KSIZE(len));
> + memcpy(kvbuf, prefix->prefix, prefix_len);
> + memcpy(kvbuf + prefix_len, name, EROFS_XATTR_KSIZE(len) - prefix_len);
> memcpy(kvbuf + EROFS_XATTR_KSIZE(len), value, size);
>
> item = get_xattritem(sbi, kvbuf, len);
> @@ -528,6 +547,12 @@ int erofs_setxattr(struct erofs_inode *inode, char *key,
> return erofs_inode_xattr_add(&inode->i_xattrs, item);
> }
>
> +int erofs_vfs_setxattr(struct erofs_inode *inode, const char *name,
> + const void *value, size_t size)
> +{
> + return erofs_setxattr(inode, 0, name, value, size);
> +}
> +
> static void erofs_removexattr(struct erofs_inode *inode, const char *key)
> {
> struct erofs_inode_xattr_node *node, *n;
> @@ -543,7 +568,7 @@ static void erofs_removexattr(struct erofs_inode *inode, const char *key)
>
> int erofs_set_opaque_xattr(struct erofs_inode *inode)
> {
> - return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
> + return erofs_vfs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
> }
>
> void erofs_clear_opaque_xattr(struct erofs_inode *inode)
> @@ -553,7 +578,7 @@ void erofs_clear_opaque_xattr(struct erofs_inode *inode)
>
> int erofs_set_origin_xattr(struct erofs_inode *inode)
> {
> - return erofs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
> + return erofs_vfs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
> }
>
> #ifdef WITH_ANDROID
> @@ -671,7 +696,7 @@ int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
> continue;
> }
>
> - ret = erofs_setxattr(inode, key, value, size);
> + ret = erofs_vfs_setxattr(inode, key, value, size);
> free(value);
> if (ret)
> break;
More information about the Linux-erofs
mailing list