diff options
author | Gao Xiang <hsiangkao@linux.alibaba.com> | 2023-04-07 21:38:04 +0800 |
---|---|---|
committer | Gao Xiang <hsiangkao@linux.alibaba.com> | 2023-04-07 22:13:25 +0800 |
commit | 276e3504b7c07af68aec304938c4bed6192d59ad (patch) | |
tree | 6f2c1ad5e1193df40891f627d605344b4f782072 | |
parent | 750a105a5aa2c1720a912575edf5067e57ebefbc (diff) | |
download | erofs-utils-276e3504b7c07af68aec304938c4bed6192d59ad.tar.gz |
erofs-utils: xattr: avoid global variable shared_xattrs_size
Let's calculate shared_xattrs_size lazily instead.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230407133805.60975-2-hsiangkao@linux.alibaba.com
-rw-r--r-- | lib/xattr.c | 65 |
1 files changed, 27 insertions, 38 deletions
diff --git a/lib/xattr.c b/lib/xattr.c index a292f2c..5f11cbe 100644 --- a/lib/xattr.c +++ b/lib/xattr.c @@ -37,7 +37,7 @@ struct inode_xattr_node { static DECLARE_HASHTABLE(ea_hashtable, EA_HASHTABLE_BITS); static LIST_HEAD(shared_xattrs_list); -static unsigned int shared_xattrs_count, shared_xattrs_size; +static unsigned int shared_xattrs_count; static struct xattr_prefix { const char *prefix; @@ -269,10 +269,6 @@ static int shared_xattr_add(struct xattr_item *item) init_list_head(&node->list); node->item = item; list_add(&node->list, &shared_xattrs_list); - - shared_xattrs_size += sizeof(struct erofs_xattr_entry); - shared_xattrs_size = EROFS_XATTR_ALIGN(shared_xattrs_size + - item->len[0] + item->len[1]); return ++shared_xattrs_count; } @@ -543,24 +539,9 @@ static void erofs_cleanxattrs(bool sharedxattrs) if (sharedxattrs) return; - shared_xattrs_size = shared_xattrs_count = 0; -} - -static bool erofs_bh_flush_write_shared_xattrs(struct erofs_buffer_head *bh) -{ - void *buf = bh->fsprivate; - int err = dev_write(buf, erofs_btell(bh, false), shared_xattrs_size); - - if (err) - return false; - free(buf); - return erofs_bh_flush_generic_end(bh); + shared_xattrs_count = 0; } -static struct erofs_bhops erofs_write_shared_xattrs_bhops = { - .flush = erofs_bh_flush_write_shared_xattrs, -}; - static int comp_xattr_item(const void *a, const void *b) { const struct xattr_item *ia, *ib; @@ -587,13 +568,14 @@ int erofs_build_shared_xattrs_from_path(const char *path) char *buf; unsigned int p, i; erofs_off_t off; + 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) return 0; - if (shared_xattrs_size || shared_xattrs_count) { + if (shared_xattrs_count) { DBG_BUGON(1); return -EINVAL; } @@ -602,9 +584,26 @@ int erofs_build_shared_xattrs_from_path(const char *path) if (ret) return ret; - if (!shared_xattrs_size) + if (!shared_xattrs_count) goto out; + sorted_n = malloc(shared_xattrs_count * sizeof(n)); + if (!sorted_n) + return -ENOMEM; + + i = 0; + list_for_each_entry_safe(node, n, &shared_xattrs_list, list) { + list_del(&node->list); + sorted_n[i++] = node; + + shared_xattrs_size += sizeof(struct erofs_xattr_entry); + shared_xattrs_size = EROFS_XATTR_ALIGN(shared_xattrs_size + + node->item->len[0] + node->item->len[1]); + + } + DBG_BUGON(i != shared_xattrs_count); + qsort(sorted_n, shared_xattrs_count, sizeof(n), comp_xattr_item); + buf = calloc(1, shared_xattrs_size); if (!buf) return -ENOMEM; @@ -622,18 +621,6 @@ int erofs_build_shared_xattrs_from_path(const char *path) sbi.xattr_blkaddr = off / erofs_blksiz(); off %= erofs_blksiz(); p = 0; - - sorted_n = malloc(shared_xattrs_count * sizeof(n)); - if (!sorted_n) - return -ENOMEM; - i = 0; - list_for_each_entry_safe(node, n, &shared_xattrs_list, list) { - list_del(&node->list); - sorted_n[i++] = node; - } - DBG_BUGON(i != shared_xattrs_count); - qsort(sorted_n, shared_xattrs_count, sizeof(n), comp_xattr_item); - for (i = 0; i < shared_xattrs_count; i++) { struct inode_xattr_node *const tnode = sorted_n[i]; struct xattr_item *const item = tnode->item; @@ -654,11 +641,13 @@ int erofs_build_shared_xattrs_from_path(const char *path) } free(sorted_n); - bh->fsprivate = buf; - bh->op = &erofs_write_shared_xattrs_bhops; + bh->op = &erofs_drop_directly_bhops; + ret = dev_write(buf, erofs_btell(bh, false), shared_xattrs_size); + free(buf); + erofs_bdrop(bh, false); out: erofs_cleanxattrs(true); - return 0; + return ret; } char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size) |