From: Gao Xiang <xiang@kernel.org>
To: linux-erofs@lists.ozlabs.org
Cc: Yifan Zhao <zhaoyifan28@huawei.com>, Gao Xiang <xiang@kernel.org>,
cayoub-oai <cayoub@openai.com>,
Gao Xiang <hsiangkao@linux.alibaba.com>
Subject: [PATCH] erofs-utils: fix opaque handling for merged dirs in rebuild mode
Date: Sat, 25 Jul 2026 10:53:28 +0800 [thread overview]
Message-ID: <20260725025328.35113-1-xiang@kernel.org> (raw)
As cayoub-oai reports,
A three-layer opaque-directory case still fails (oldest to newest):
L1: dir/old.txt
L2: dir/.wh..wh..opq
L3: dir/new.txt
After converting each layer with `mkfs.erofs --tar=f --aufs` and
fsmerging with `--aufs --ovlfs-strip=1`, the expected result is
only `dir/new.txt`. However, `dir/old.txt` incorrectly reappears.
Reported-by: cayoub-oai <cayoub@openai.com>
Fixes: 7fbec7d32ce3 ("erofs-utils: lib: honor rebuild whiteouts for recreated dirs")
Fixes: 39147b48b76d ("erofs-utils: lib: add erofs_rebuild_load_tree() helper")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
include/erofs/xattr.h | 2 ++
lib/inode.c | 1 +
lib/rebuild.c | 6 ++++--
lib/xattr.c | 16 ++++++++++++++++
4 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 5fe3e91..d12c292 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -47,12 +47,14 @@ int erofs_vfs_setxattr(struct erofs_inode *inode, const char *name,
const void *value, size_t size);
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);
int erofs_set_origin_xattr(struct erofs_inode *inode);
int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
bool erofs_xattr_prefix_matches(const char *key, unsigned int *index,
unsigned int *len);
void erofs_xattr_exit(struct erofs_sb_info *sbi);
+void erofs_inode_free_xattrs(struct erofs_inode *inode);
#ifdef __cplusplus
}
diff --git a/lib/inode.c b/lib/inode.c
index 267694f..9f4d14c 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -166,6 +166,7 @@ unsigned int erofs_iput(struct erofs_inode *inode)
if (inode->datalayout == EROFS_INODE_CHUNK_BASED)
free(inode->chunkindexes);
+ erofs_inode_free_xattrs(inode);
free(inode);
return 0;
}
diff --git a/lib/rebuild.c b/lib/rebuild.c
index 108a464..a5308dc 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -403,13 +403,15 @@ static int erofs_rebuild_dirent_iter(struct erofs_dir_context *ctx)
ret = erofs_read_inode_from_disk(&src);
if (ret)
goto out;
+ mergedir = d->inode;
if (erofs_inode_is_whiteout(&src)) {
- d->inode->opaque = true;
+ mergedir->opaque = true;
goto out;
}
if (!S_ISDIR(src.i_mode))
goto out;
- mergedir = d->inode;
+ mergedir->opaque |= erofs_get_opaque_from_disk(&src);
+ erofs_inode_free_xattrs(&src);
inode = dir = &src;
} else {
u64 nid;
diff --git a/lib/xattr.c b/lib/xattr.c
index 051fdd8..a9486e4 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -576,6 +576,11 @@ void erofs_clear_opaque_xattr(struct erofs_inode *inode)
erofs_removexattr(inode, OVL_XATTR_OPAQUE);
}
+bool erofs_get_opaque_from_disk(struct erofs_inode *inode)
+{
+ return (erofs_getxattr(inode, OVL_XATTR_OPAQUE, NULL, 0) >= 0);
+}
+
int erofs_set_origin_xattr(struct erofs_inode *inode)
{
return erofs_vfs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
@@ -1123,6 +1128,17 @@ char *erofs_export_xattr_ibody(struct erofs_inode *inode)
return buf;
}
+void erofs_inode_free_xattrs(struct erofs_inode *inode)
+{
+ DBG_BUGON(inode->i_count > 0);
+
+ if (erofs_atomic_read(&inode->flags) & EROFS_I_EA_INITED) {
+ free(inode->xattr_shared_xattrs);
+ inode->xattr_shared_xattrs = NULL;
+ inode->xattr_shared_count = 0;
+ }
+}
+
struct erofs_xattr_iter {
struct erofs_sb_info *sbi;
struct erofs_buf buf;
--
2.47.3
reply other threads:[~2026-07-25 2:53 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=20260725025328.35113-1-xiang@kernel.org \
--to=xiang@kernel.org \
--cc=cayoub@openai.com \
--cc=hsiangkao@linux.alibaba.com \
--cc=linux-erofs@lists.ozlabs.org \
--cc=zhaoyifan28@huawei.com \
/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