[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