Introduce helpers for registering and cleaning up extra xattr name
prefix.

Signed-off-by: Jingbo Xu <[email protected]>
---
 include/erofs/xattr.h |  3 +++
 lib/xattr.c           | 58 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 9efadc5..1085908 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -70,6 +70,9 @@ int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
 char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size);
 int erofs_build_shared_xattrs_from_path(const char *path);
 
+int erofs_insert_ea_type(const char *prefix);
+void erofs_cleanup_ea_type(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/xattr.c b/lib/xattr.c
index a292f2c..ec40aad 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -61,6 +61,14 @@ static struct xattr_prefix {
        }
 };
 
+struct ea_type_node {
+       struct list_head list;
+       struct xattr_prefix type;
+       u8 index;
+};
+static LIST_HEAD(ea_types);
+static unsigned int ea_types_count;
+
 static unsigned int BKDRHash(char *str, unsigned int len)
 {
        const unsigned int seed = 131313;
@@ -1222,3 +1230,53 @@ int erofs_listxattr(struct erofs_inode *vi, char 
*buffer, size_t buffer_size)
                return ret;
        return shared_listxattr(vi, &it);
 }
+
+int erofs_insert_ea_type(const char *prefix)
+{
+       struct ea_type_node *tnode;
+       struct xattr_prefix *p;
+       bool matched = false;
+       char *s;
+
+       if (ea_types_count == EROFS_XATTR_EA_FLAG || strlen(prefix) > UINT8_MAX)
+               return -EOVERFLOW;
+
+       for (p = xattr_types; p < xattr_types + ARRAY_SIZE(xattr_types); ++p) {
+               if (!strncmp(p->prefix, prefix, p->prefix_len)) {
+                       matched = true;
+                       break;
+               }
+       }
+       if (!matched)
+               return -ENODATA;
+
+       s = strdup(prefix);
+       if (!s)
+               return -ENOMEM;
+
+       tnode = malloc(sizeof(*tnode));
+       if (!tnode) {
+               free(s);
+               return -ENOMEM;
+       }
+
+       tnode->type.prefix = s;
+       tnode->type.prefix_len = strlen(prefix);
+
+       tnode->index = EROFS_XATTR_EA_FLAG | ea_types_count;
+       ea_types_count++;
+       init_list_head(&tnode->list);
+       list_add_tail(&tnode->list, &ea_types);
+       return 0;
+}
+
+void erofs_cleanup_ea_type(void)
+{
+       struct ea_type_node *tnode, *n;
+
+       list_for_each_entry_safe(tnode, n, &ea_types, list) {
+               list_del(&tnode->list);
+               free(tnode->type.prefix);
+               free(tnode);
+       }
+}
-- 
2.19.1.6.gb485710b

Reply via email to