Linux-EROFS Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Wenyuan Xu <sereno.xu@deepseek.com>
To: xiang@kernel.org, linux-erofs@lists.ozlabs.org
Cc: sereno.xu@deepseek.com
Subject: [RFC 3/7] erofs-utils: lib: add erofs_build_shared_xattrs() helper
Date: Wed,  4 Nov 2026 04:07:21 +0000	[thread overview]
Message-ID: <20261104040725.2473313-4-sereno.xu@deepseek.com> (raw)
In-Reply-To: <20261104040725.2473313-1-sereno.xu@deepseek.com>

Extract shared xattr serialization from the local-directory scan so it
can also be used with xattrs already attached to inodes.

Add erofs_build_shared_xattrs() to select shared entries  without
freeing inline entries. Retain an extra reference to shared entries
until xattr manager cleanup.

Assisted-by: LLM
Signed-off-by: Wenyuan Xu <sereno.xu@deepseek.com>
---
 include/erofs/xattr.h |  2 ++
 lib/xattr.c           | 52 +++++++++++++++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 0016ad2..1388a6f 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -32,6 +32,8 @@ int erofs_prepare_xattr_ibody(struct erofs_inode *inode, bool noroom);
 char *erofs_export_xattr_ibody(struct erofs_inode *inode);
 int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path,
 				       long inlinexattr_tolerance);
+int erofs_build_shared_xattrs(struct erofs_sb_info *sbi,
+			      long inlinexattr_tolerance);
 int erofs_xattr_insert_name_prefix(const char *prefix);
 int erofs_xattr_set_ishare_prefix(struct erofs_sb_info *sbi,
 				  const char *prefix);
diff --git a/lib/xattr.c b/lib/xattr.c
index a0ac76f..4e7ac8b 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -995,27 +995,18 @@ static void erofs_write_xattr_entry(char *buf, struct erofs_xattritem *item)
 			item->prefix, item->kvbuf + item->prefix_len);
 }
 
-int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path,
-				       long inlinexattr_tolerance)
+static int erofs_write_shared_xattrs(struct erofs_sb_info *sbi,
+				     unsigned int sharedxattr_count)
 {
 	struct erofs_xattrmgr *xamgr = sbi->xamgr;
 	struct erofs_xattritem *item, *n, **sorted_n;
-	unsigned int sharedxattr_count, p, i;
+	unsigned int p, i;
 	struct erofs_buffer_head *bh;
 	char *buf;
 	int ret;
 	erofs_off_t off;
 	erofs_off_t shared_xattrs_size = 0;
 
-	/* check if xattr or shared xattr is disabled */
-	if (inlinexattr_tolerance < 0 || inlinexattr_tolerance >= INT_MAX)
-		return 0;
-
-	ret = erofs_count_all_xattrs_from_path(sbi, path);
-	if (ret)
-		return ret;
-
-	sharedxattr_count = erofs_cleanxattrs(xamgr, inlinexattr_tolerance);
 	if (!sharedxattr_count)
 		return 0;
 
@@ -1071,6 +1062,43 @@ int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *pa
 	return ret;
 }
 
+int erofs_load_shared_xattrs_from_path(struct erofs_sb_info *sbi, const char *path,
+				       long inlinexattr_tolerance)
+{
+	int ret;
+
+	if (inlinexattr_tolerance < 0 || inlinexattr_tolerance >= INT_MAX)
+		return 0;
+	ret = erofs_count_all_xattrs_from_path(sbi, path);
+	if (ret)
+		return ret;
+	return erofs_write_shared_xattrs(sbi,
+			erofs_cleanxattrs(sbi->xamgr, inlinexattr_tolerance));
+}
+
+int erofs_build_shared_xattrs(struct erofs_sb_info *sbi,
+			      long inlinexattr_tolerance)
+{
+	struct erofs_xattrmgr *xamgr = sbi->xamgr;
+	struct erofs_xattritem *item;
+	unsigned int i, count = 0;
+
+	if (inlinexattr_tolerance < 0 || inlinexattr_tolerance >= INT_MAX)
+		return 0;
+	for (i = 0; i < ARRAY_SIZE(xamgr->hash); ++i) {
+		list_for_each_entry(item, xamgr->hash + i, node) {
+			if (item->count > inlinexattr_tolerance) {
+				/* keep shared items alive after inode references drop */
+				++item->count;
+				item->next_shared_xattr = xamgr->shared_xattrs;
+				xamgr->shared_xattrs = item;
+				++count;
+			}
+		}
+	}
+	return erofs_write_shared_xattrs(sbi, count);
+}
+
 char *erofs_export_xattr_ibody(struct erofs_inode *inode)
 {
 	struct list_head *ixattrs = &inode->i_xattrs;
-- 
2.43.0



  parent reply	other threads:[~2026-11-04  4:12 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  4:07 [RFC 0/7] erofs-utils: add manifest input support Wenyuan Xu
2026-11-04  4:07 ` [RFC 1/7] erofs-utils: mkfs: init root inode in local source mode Wenyuan Xu
2026-11-04  4:07 ` [RFC 2/7] erofs-utils: lib: add erofs_inode_has_xattr helper Wenyuan Xu
2026-11-04  4:07 ` Wenyuan Xu [this message]
2026-11-04  4:07 ` [RFC 4/7] erofs-utils: mkfs: add manifest input mode Wenyuan Xu
2026-11-04  4:07 ` [RFC 5/7] erofs-utils: mkfs: support two-field manifest records Wenyuan Xu
2026-11-04  4:07 ` [RFC 6/7] erofs-utils: man: document manifest input formats Wenyuan Xu
2026-11-04  4:07 ` [RFC 7/7] erofs-utils: tests: cover manifest input Wenyuan Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261104040725.2473313-4-sereno.xu@deepseek.com \
    --to=sereno.xu@deepseek.com \
    --cc=linux-erofs@lists.ozlabs.org \
    --cc=xiang@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox