[PATCH] erofs-utils: mkfs: don't clean cached xattr items prematurely

Jingbo Xu jefflexu at linux.alibaba.com
Wed Jul 5 12:10:40 AEST 2023


Extended attributes read from file are cached in a hash table when
building shared extended attributes.  However the cached xattr items
for inline xattrs are cleaned up from the hash table when the processing
for shared extended attributes has finished, while later the hash table
is reconstructed from scratch when building the inode tree (see
erofs_mkfs_build_tree_from_path()).

Don't clean up the xattr hash table halfway until mkfs exits.  Also move
the logic of cleaning long xattr name prefixes into erofs_cleanxattrs().

Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
---
 include/erofs/xattr.h |  2 +-
 lib/xattr.c           | 30 ++++++++----------------------
 mkfs/main.c           |  2 +-
 3 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 14fc081..b202f78 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -75,9 +75,9 @@ static inline unsigned int xattrblock_offset(unsigned int xattr_id)
 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);
+void erofs_cleanxattrs(void);
 
 int erofs_xattr_insert_name_prefix(const char *prefix);
-void erofs_xattr_cleanup_name_prefixes(void);
 int erofs_xattr_write_name_prefixes(FILE *f);
 
 #ifdef __cplusplus
diff --git a/lib/xattr.c b/lib/xattr.c
index 7d7dc54..8d0079f 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -547,24 +547,23 @@ fail:
 	return ret;
 }
 
-static void erofs_cleanxattrs(bool sharedxattrs)
+void erofs_cleanxattrs(void)
 {
 	unsigned int i;
 	struct xattr_item *item;
 	struct hlist_node *tmp;
+	struct ea_type_node *tnode, *n;
 
 	hash_for_each_safe(ea_hashtable, i, tmp, item, node) {
-		if (sharedxattrs && item->shared_xattr_id >= 0)
-			continue;
-
 		hash_del(&item->node);
 		free(item);
 	}
 
-	if (sharedxattrs)
-		return;
-
-	shared_xattrs_count = 0;
+	list_for_each_entry_safe(tnode, n, &ea_name_prefixes, list) {
+		list_del(&tnode->list);
+		free((void *)tnode->type.prefix);
+		free(tnode);
+	}
 }
 
 static int comp_shared_xattr_item(const void *a, const void *b)
@@ -676,7 +675,7 @@ int erofs_build_shared_xattrs_from_path(const char *path)
 		return ret;
 
 	if (!shared_xattrs_count)
-		goto out;
+		return 0;
 
 	sorted_n = malloc((shared_xattrs_count + 1) * sizeof(n));
 	if (!sorted_n)
@@ -735,8 +734,6 @@ int erofs_build_shared_xattrs_from_path(const char *path)
 	ret = dev_write(buf, erofs_btell(bh, false), shared_xattrs_size);
 	free(buf);
 	erofs_bdrop(bh, false);
-out:
-	erofs_cleanxattrs(true);
 	return ret;
 }
 
@@ -1340,14 +1337,3 @@ int erofs_xattr_insert_name_prefix(const char *prefix)
 	list_add_tail(&tnode->list, &ea_name_prefixes);
 	return 0;
 }
-
-void erofs_xattr_cleanup_name_prefixes(void)
-{
-	struct ea_type_node *tnode, *n;
-
-	list_for_each_entry_safe(tnode, n, &ea_name_prefixes, list) {
-		list_del(&tnode->list);
-		free((void *)tnode->type.prefix);
-		free(tnode);
-	}
-}
diff --git a/mkfs/main.c b/mkfs/main.c
index ac208e5..390ef17 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -942,7 +942,7 @@ exit:
 	if (cfg.c_fragments)
 		z_erofs_fragments_exit();
 	erofs_packedfile_exit();
-	erofs_xattr_cleanup_name_prefixes();
+	erofs_cleanxattrs();
 	erofs_exit_configure();
 
 	if (err) {
-- 
2.19.1.6.gb485710b



More information about the Linux-erofs mailing list