[PATCH v2 1/4] erofs-utils: lib: introduce prefix-aware erofs_setxattr()
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Dec 30 05:06:43 AEDT 2025
Allows users to specify a predefined prefix for xattr names.
Reviewed-by: Hongbo Li <lihongbo22 at huawei.com>
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
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;
--
2.43.5
More information about the Linux-erofs
mailing list