[PATCH 4/5] erofs-utils: lib: migrate `c_inline_xattr_tolerance`
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Sep 30 16:38:46 AEST 2025
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
include/erofs/config.h | 2 -
include/erofs/importer.h | 1 +
include/erofs/xattr.h | 4 +-
lib/config.c | 1 -
lib/inode.c | 2 +-
lib/xattr.c | 82 +++++++++++++++-------------------------
mkfs/main.c | 23 ++++++++---
7 files changed, 51 insertions(+), 64 deletions(-)
diff --git a/include/erofs/config.h b/include/erofs/config.h
index 153315b..1685adf 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -56,8 +56,6 @@ struct erofs_configure {
struct erofs_compr_opts c_compr_opts[EROFS_MAX_COMPR_CFGS];
char c_force_chunkformat;
u8 c_mkfs_metabox_algid;
- /* < 0, xattr disabled and INT_MAX, always use inline xattrs */
- int c_inline_xattr_tolerance;
u32 c_max_decompressed_extent_bytes;
u64 c_unix_timestamp;
const char *mount_point;
diff --git a/include/erofs/importer.h b/include/erofs/importer.h
index dbb87be..48fe47e 100644
--- a/include/erofs/importer.h
+++ b/include/erofs/importer.h
@@ -41,6 +41,7 @@ struct erofs_importer_params {
bool hard_dereference;
bool ovlfs_strip;
bool dot_omitted;
+ bool no_xattrs; /* don't store extended attributes */
bool no_zcompact;
bool no_lz4_0padding;
bool ztailpacking;
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 67f6199..ef80123 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -49,8 +49,8 @@ int erofs_xattr_init(struct erofs_sb_info *sbi);
int erofs_scan_file_xattrs(struct erofs_inode *inode);
int erofs_prepare_xattr_ibody(struct erofs_inode *inode, bool noroom);
char *erofs_export_xattr_ibody(struct erofs_inode *inode);
-int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path);
-
+int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path,
+ long inlinexattr_tolerance);
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);
diff --git a/lib/config.c b/lib/config.c
index 1da5354..16b34fa 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -29,7 +29,6 @@ void erofs_init_configure(void)
cfg.c_dbg_lvl = EROFS_WARN;
cfg.c_version = PACKAGE_VERSION;
cfg.c_dry_run = false;
- cfg.c_inline_xattr_tolerance = 2;
cfg.c_unix_timestamp = -1;
cfg.c_max_decompressed_extent_bytes = -1;
erofs_stdout_tty = isatty(STDOUT_FILENO);
diff --git a/lib/inode.c b/lib/inode.c
index 237ba31..4a834b4 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1848,7 +1848,7 @@ static int erofs_mkfs_handle_inode(struct erofs_importer *im,
return ret;
}
- if (!rebuild) {
+ if (!rebuild && !params->no_xattrs) {
ret = erofs_scan_file_xattrs(inode);
if (ret < 0)
return ret;
diff --git a/lib/xattr.c b/lib/xattr.c
index 6e1958b..e02e8cb 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -127,7 +127,6 @@ struct erofs_inode_xattr_node {
struct erofs_xattrmgr {
struct list_head hash[1 << 14];
struct erofs_xattritem *shared_xattrs;
- unsigned int sharedxattr_count;
};
int erofs_xattr_init(struct erofs_sb_info *sbi)
@@ -374,10 +373,12 @@ static struct erofs_xattritem *erofs_get_selabel_xattr(struct erofs_sb_info *sbi
return NULL;
}
-static int inode_xattr_add(struct list_head *hlist, struct erofs_xattritem *item)
+static int erofs_inode_xattr_add(struct list_head *hlist,
+ struct erofs_xattritem *item)
{
- struct erofs_inode_xattr_node *node = malloc(sizeof(*node));
+ struct erofs_inode_xattr_node *node;
+ node = malloc(sizeof(*node));
if (!node)
return -ENOMEM;
init_list_head(&node->list);
@@ -386,22 +387,6 @@ static int inode_xattr_add(struct list_head *hlist, struct erofs_xattritem *item
return 0;
}
-static int erofs_xattr_add(struct erofs_sb_info *sbi, struct list_head *ixattrs,
- struct erofs_xattritem *item)
-{
- struct erofs_xattrmgr *xamgr = sbi->xamgr;
-
- if (ixattrs)
- return inode_xattr_add(ixattrs, item);
-
- if (item->count == cfg.c_inline_xattr_tolerance + 1) {
- item->next_shared_xattr = xamgr->shared_xattrs;
- xamgr->shared_xattrs = item;
- ++xamgr->sharedxattr_count;
- }
- return 0;
-}
-
static bool erofs_is_skipped_xattr(const char *key)
{
#ifdef HAVE_LIBSELINUX
@@ -468,9 +453,11 @@ static int read_xattrs_from_file(struct erofs_sb_info *sbi, const char *path,
goto err;
}
- ret = erofs_xattr_add(sbi, ixattrs, item);
- if (ret < 0)
- goto err;
+ if (ixattrs) {
+ ret = erofs_inode_xattr_add(ixattrs, item);
+ if (ret < 0)
+ goto err;
+ }
}
free(keylst);
@@ -479,8 +466,8 @@ out:
item = erofs_get_selabel_xattr(sbi, path, mode);
if (IS_ERR(item))
return PTR_ERR(item);
- if (item)
- ret = erofs_xattr_add(sbi, ixattrs, item);
+ if (item && ixattrs)
+ ret = erofs_inode_xattr_add(ixattrs, item);
return ret;
err:
@@ -512,8 +499,7 @@ int erofs_setxattr(struct erofs_inode *inode, char *key,
return PTR_ERR(item);
}
DBG_BUGON(!item);
-
- return erofs_xattr_add(sbi, &inode->i_xattrs, item);
+ return erofs_inode_xattr_add(&inode->i_xattrs, item);
}
static void erofs_removexattr(struct erofs_inode *inode, const char *key)
@@ -578,8 +564,7 @@ static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
return PTR_ERR(item);
}
DBG_BUGON(!item);
-
- return erofs_xattr_add(sbi, &inode->i_xattrs, item);
+ return erofs_inode_xattr_add(&inode->i_xattrs, item);
}
#else
static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
@@ -593,10 +578,6 @@ int erofs_scan_file_xattrs(struct erofs_inode *inode)
int ret;
struct list_head *ixattrs = &inode->i_xattrs;
- /* check if xattr is disabled */
- if (cfg.c_inline_xattr_tolerance < 0)
- return 0;
-
ret = read_xattrs_from_file(inode->sbi, inode->i_srcpath,
inode->i_mode, ixattrs);
if (ret < 0)
@@ -788,24 +769,27 @@ fail:
return ret;
}
-static void erofs_cleanxattrs(struct erofs_xattrmgr *xamgr, bool sharedxattrs)
+static unsigned int erofs_cleanxattrs(struct erofs_xattrmgr *xamgr,
+ unsigned int inlinexattr_tolerance)
{
struct erofs_xattritem *item, *n;
- unsigned int i;
+ unsigned int i, count;
+ count = 0;
for (i = 0; i < ARRAY_SIZE(xamgr->hash); ++i) {
list_for_each_entry_safe(item, n, xamgr->hash + i, node) {
- if (sharedxattrs && item->shared_xattr_id >= 0)
+ if (item->count > inlinexattr_tolerance) {
+ item->next_shared_xattr = xamgr->shared_xattrs;
+ xamgr->shared_xattrs = item;
+ ++count;
continue;
+ }
list_del(&item->node);
free((void *)item->kvbuf);
free(item);
}
}
-
- if (sharedxattrs)
- return;
- xamgr->sharedxattr_count = 0;
+ return count;
}
static int comp_shared_xattritem(const void *a, const void *b)
@@ -937,7 +921,8 @@ static void erofs_write_xattr_entry(char *buf, struct erofs_xattritem *item)
item->prefix, item->kvbuf + item->prefix_len);
}
-int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path)
+int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path,
+ long inlinexattr_tolerance)
{
struct erofs_xattrmgr *xamgr = sbi->xamgr;
struct erofs_xattritem *item, *n, **sorted_n;
@@ -949,21 +934,16 @@ int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *p
erofs_off_t shared_xattrs_size = 0;
/* check if xattr or shared xattr is disabled */
- if (cfg.c_inline_xattr_tolerance < 0 ||
- cfg.c_inline_xattr_tolerance == INT_MAX)
+ if (inlinexattr_tolerance < 0 || inlinexattr_tolerance >= INT_MAX)
return 0;
- if (xamgr->sharedxattr_count) {
- DBG_BUGON(1);
- return -EINVAL;
- }
-
ret = erofs_count_all_xattrs_from_path(sbi, path);
if (ret)
return ret;
- sharedxattr_count = xamgr->sharedxattr_count;
+
+ sharedxattr_count = erofs_cleanxattrs(xamgr, inlinexattr_tolerance);
if (!sharedxattr_count)
- goto out;
+ return 0;
sorted_n = malloc((sharedxattr_count + 1) * sizeof(n));
if (!sorted_n)
@@ -1014,8 +994,6 @@ int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *p
ret = erofs_dev_write(sbi, buf, erofs_btell(bh, false), shared_xattrs_size);
free(buf);
erofs_bdrop(bh, false);
-out:
- erofs_cleanxattrs(xamgr, true);
return ret;
}
@@ -1753,7 +1731,7 @@ void erofs_xattr_exit(struct erofs_sb_info *sbi)
erofs_xattr_prefixes_cleanup(sbi);
if (!xamgr)
return;
- erofs_cleanxattrs(xamgr, false);
+ (void)erofs_cleanxattrs(xamgr, UINT_MAX);
sbi->xamgr = NULL;
free(xamgr);
}
diff --git a/mkfs/main.c b/mkfs/main.c
index 25f28ee..1c37576 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -264,6 +264,13 @@ static void version(void)
print_available_compressors(stdout, ", ");
}
+static struct erofsmkfs_cfg {
+ /* < 0, xattr disabled and >= INT_MAX, always use inline xattrs */
+ long inlinexattr_tolerance;
+} mkfscfg = {
+ .inlinexattr_tolerance = 2,
+};
+
static unsigned int pclustersize_packed, pclustersize_max;
static int pclustersize_metabox = -1;
static struct erofs_tarfile erofstar = {
@@ -1011,10 +1018,11 @@ static int mkfs_parse_sources(int argc, char *argv[], int optind)
static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
int argc, char *argv[])
{
- char *endptr;
- int opt, i, err;
- bool quiet = false;
bool has_timestamp = false;
+ bool quiet = false;
+ char *endptr;
+ int opt, err;
+ long i;
while ((opt = getopt_long(argc, argv, "C:E:L:T:U:b:d:m:x:z:Vh",
long_options, NULL)) != -1) {
@@ -1049,7 +1057,7 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
erofs_err("invalid xattr tolerance %s", optarg);
return -EINVAL;
}
- cfg.c_inline_xattr_tolerance = i;
+ mkfscfg.inlinexattr_tolerance = i;
break;
case 'E':
@@ -1782,6 +1790,8 @@ int main(int argc, char **argv)
goto exit;
}
+ if (mkfscfg.inlinexattr_tolerance < 0)
+ importer_params.no_xattrs = true;
importer_params.source = cfg.c_src_path;
importer_params.no_datainline = mkfs_no_datainline;
importer_params.dot_omitted = mkfs_dot_omitted;
@@ -1819,9 +1829,10 @@ int main(int argc, char **argv)
}
if (source_mode == EROFS_MKFS_SOURCE_LOCALDIR) {
- err = erofs_build_shared_xattrs_from_path(&g_sbi, cfg.c_src_path);
+ err = erofs_load_shared_xattrs_from_path(&g_sbi, cfg.c_src_path,
+ mkfscfg.inlinexattr_tolerance);
if (err) {
- erofs_err("failed to build shared xattrs: %s",
+ erofs_err("failed to load shared xattrs: %s",
erofs_strerror(err));
goto exit;
}
--
2.43.5
More information about the Linux-erofs
mailing list