Linux-EROFS Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Yifan Zhao <stopire@gmail.com>
To: linux-erofs@lists.ozlabs.org
Cc: Yifan Zhao <stopire@gmail.com>
Subject: [PATCH] erofs-utils: mkfs: strip overlay origin xattrs with --ovlfs-strip
Date: Thu, 12 Nov 2026 20:47:14 +0800	[thread overview]
Message-ID: <20261112124714.2774025-1-stopire@gmail.com> (raw)

Fix --ovlfs-strip failing to remove trusted.overlay.origin from output
inodes. Also consolidate the opaque and origin xattr helpers.

Fixes: dd40232ee060 ("erofs-utils: mkfs: add `--ovlfs-strip` option")
Fixes: 8286289d1959 ("erofs-utils: lib: avoid duplicate overlay origin xattrs")
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Yifan Zhao <stopire@gmail.com>
---
 include/erofs/xattr.h | 16 ++++++++-----
 lib/inode.c           |  9 ++++----
 lib/rebuild.c         |  3 ++-
 lib/tar.c             |  9 ++++----
 lib/xattr.c           | 53 +++++++++++++++++++++----------------------
 5 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 2aecf7d..c74f0ae 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -23,6 +23,11 @@ static inline unsigned int inlinexattr_header_size(struct erofs_inode *vi)
 
 struct erofs_importer;
 
+enum erofs_ovl_xattr {
+	EROFS_OVL_XATTR_OPAQUE,
+	EROFS_OVL_XATTR_ORIGIN,
+};
+
 ssize_t erofs_sys_lsetxattr(const char *path, const char *name,
 			    void *value, size_t size);
 
@@ -45,12 +50,11 @@ int erofs_setxattr(struct erofs_inode *inode, int index, const char *name,
 		   const void *value, size_t size);
 int erofs_vfs_setxattr(struct erofs_inode *inode, const char *name,
 		       const void *value, size_t size);
-bool erofs_is_opaque_xattr(const char *name);
-int erofs_set_opaque_xattr(struct erofs_inode *inode);
-void erofs_clear_opaque_xattr(struct erofs_inode *inode);
-bool erofs_get_opaque_from_disk(struct erofs_inode *inode);
-bool erofs_is_origin_xattr(const char *name);
-int erofs_set_origin_xattr(struct erofs_inode *inode);
+bool erofs_is_ovl_xattr(const char *name, enum erofs_ovl_xattr type);
+int erofs_set_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type,
+			const void *value, size_t size);
+void erofs_clear_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type);
+bool erofs_has_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type);
 int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
 
 bool erofs_xattr_prefix_matches(const char *key, unsigned int *index,
diff --git a/lib/inode.c b/lib/inode.c
index e4809e9..3108aa0 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -2139,10 +2139,11 @@ static int erofs_mkfs_handle_inode(const struct erofs_mkfs_btctx *ctx,
 	}
 
 	/* strip all unnecessary overlayfs xattrs when ovlfs_strip is enabled */
-	if (params->ovlfs_strip)
-		erofs_clear_opaque_xattr(inode);
-	else if (inode->whiteouts) {
-		ret = erofs_set_origin_xattr(inode);
+	if (params->ovlfs_strip) {
+		erofs_clear_ovl_xattr(inode, EROFS_OVL_XATTR_OPAQUE);
+		erofs_clear_ovl_xattr(inode, EROFS_OVL_XATTR_ORIGIN);
+	} else if (inode->whiteouts) {
+		ret = erofs_set_ovl_xattr(inode, EROFS_OVL_XATTR_ORIGIN, NULL, 0);
 		if (ret)
 			return ret;
 	}
diff --git a/lib/rebuild.c b/lib/rebuild.c
index 45826ff..94dc66d 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -486,7 +486,8 @@ static int erofs_rebuild_dirent_iter(struct erofs_dir_context *ctx)
 		}
 		if (!S_ISDIR(src.i_mode))
 			goto out;
-		mergedir->opaque |= erofs_get_opaque_from_disk(&src);
+		mergedir->opaque |= erofs_has_ovl_xattr(&src,
+							EROFS_OVL_XATTR_OPAQUE);
 		erofs_inode_free_xattrs(&src);
 		inode = dir = &src;
 	} else {
diff --git a/lib/tar.c b/lib/tar.c
index 116dbfd..f5034da 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -419,11 +419,12 @@ int tarerofs_apply_xattrs(struct erofs_inode *inode, struct list_head *xattrs)
 		erofs_dbg("Recording xattr(%s)=\"%.*s\" (of %u bytes) to file %s",
 			  item->kv, vsz, v, vsz, inode->i_srcpath);
 		/* a .wh..wh..opq preceds trusted.overlay.opaque xattr  */
-		if (inode->opaque && erofs_is_opaque_xattr(item->kv))
+		if (inode->opaque &&
+		    erofs_is_ovl_xattr(item->kv, EROFS_OVL_XATTR_OPAQUE))
 			continue;
-		if (erofs_is_origin_xattr(item->kv))
+		if (erofs_is_ovl_xattr(item->kv, EROFS_OVL_XATTR_ORIGIN))
 			inode->origin = true;
-		if (erofs_is_opaque_xattr(item->kv))
+		if (erofs_is_ovl_xattr(item->kv, EROFS_OVL_XATTR_OPAQUE))
 			inode->opaque |= S_ISDIR(inode->i_mode);
 		ret = erofs_vfs_setxattr(inode, item->kv, v, vsz);
 		if (ret == -ENODATA)
@@ -1087,7 +1088,7 @@ out_eot:
 		 * needed if the tar tree is used soon, thus we have no chance
 		 * to generate it from xattrs.  No impact to mergefs.
 		 */
-		ret = erofs_set_opaque_xattr(d->inode);
+		ret = erofs_set_ovl_xattr(d->inode, EROFS_OVL_XATTR_OPAQUE, "y", 1);
 		goto out;
 	} else if (th->typeflag == '1') {	/* hard link cases */
 		struct erofs_dentry *d2;
diff --git a/lib/xattr.c b/lib/xattr.c
index 8e98c1e..5086ee3 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -508,9 +508,9 @@ static int read_xattrs_from_file(struct erofs_sb_info *sbi, const char *path,
 		}
 
 		if (inode) {
-			if (erofs_is_origin_xattr(key))
+			if (erofs_is_ovl_xattr(key, EROFS_OVL_XATTR_ORIGIN))
 				inode->origin = true;
-			if (erofs_is_opaque_xattr(key))
+			if (erofs_is_ovl_xattr(key, EROFS_OVL_XATTR_OPAQUE))
 				inode->opaque |= S_ISDIR(inode->i_mode);
 			ret = erofs_inode_xattr_add(&inode->i_xattrs, item);
 			if (ret < 0)
@@ -597,41 +597,40 @@ static void erofs_removexattr(struct erofs_inode *inode, const char *key)
 	}
 }
 
-bool erofs_is_opaque_xattr(const char *name)
-{
-	return !strcmp(name, OVL_XATTR_OPAQUE);
-}
+static const char * const erofs_ovl_xattr_names[] = {
+	[EROFS_OVL_XATTR_OPAQUE] = OVL_XATTR_OPAQUE,
+	[EROFS_OVL_XATTR_ORIGIN] = OVL_XATTR_ORIGIN,
+};
 
-int erofs_set_opaque_xattr(struct erofs_inode *inode)
+bool erofs_is_ovl_xattr(const char *name, enum erofs_ovl_xattr type)
 {
-	if (inode->opaque)
-		return 0;
-	inode->opaque = true;
-	return erofs_vfs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
+	return !strcmp(name, erofs_ovl_xattr_names[type]);
 }
 
-void erofs_clear_opaque_xattr(struct erofs_inode *inode)
+int erofs_set_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type,
+			const void *value, size_t size)
 {
-	erofs_removexattr(inode, OVL_XATTR_OPAQUE);
-	inode->opaque = false;
-}
+	bool *flag = type == EROFS_OVL_XATTR_OPAQUE ?
+			&inode->opaque : &inode->origin;
 
-bool erofs_get_opaque_from_disk(struct erofs_inode *inode)
-{
-	return (erofs_getxattr(inode, OVL_XATTR_OPAQUE, NULL, 0) >= 0);
+	if (*flag)
+		return 0;
+	*flag = true;
+	return erofs_vfs_setxattr(inode, erofs_ovl_xattr_names[type], value, size);
 }
 
-bool erofs_is_origin_xattr(const char *name)
+void erofs_clear_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type)
 {
-	return !strcmp(name, OVL_XATTR_ORIGIN);
+	bool *flag = type == EROFS_OVL_XATTR_OPAQUE ?
+			&inode->opaque : &inode->origin;
+
+	erofs_removexattr(inode, erofs_ovl_xattr_names[type]);
+	*flag = false;
 }
 
-int erofs_set_origin_xattr(struct erofs_inode *inode)
+bool erofs_has_ovl_xattr(struct erofs_inode *inode, enum erofs_ovl_xattr type)
 {
-	if (inode->origin)
-		return 0;
-	inode->origin = true;
-	return erofs_vfs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
+	return erofs_getxattr(inode, erofs_ovl_xattr_names[type], NULL, 0) >= 0;
 }
 
 #ifdef WITH_ANDROID
@@ -714,7 +713,7 @@ int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
 		void *value = NULL;
 		size_t size = 0;
 
-		if (!strcmp(key, OVL_XATTR_OPAQUE)) {
+		if (erofs_is_ovl_xattr(key, EROFS_OVL_XATTR_OPAQUE)) {
 			if (!S_ISDIR(inode->i_mode)) {
 				erofs_dbg("file %s: opaque xattr on non-dir",
 					  inode->i_srcpath);
@@ -743,7 +742,7 @@ int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
 			DBG_BUGON(ret != size);
 		}
 
-		if (erofs_is_origin_xattr(key))
+		if (erofs_is_ovl_xattr(key, EROFS_OVL_XATTR_ORIGIN))
 			inode->origin = true;
 		ret = erofs_vfs_setxattr(inode, key, value, size);
 		free(value);
-- 
2.56.0



                 reply	other threads:[~2026-11-12 12:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20261112124714.2774025-1-stopire@gmail.com \
    --to=stopire@gmail.com \
    --cc=linux-erofs@lists.ozlabs.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