On 2025/12/29 15:49, Gao Xiang wrote:
Allows users to specify a predefined prefix for xattr names.

Signed-off-by: Gao Xiang <[email protected]>

Reviewed-by: Hongbo Li <[email protected]>

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;

Reply via email to