When rebuilding from upper to lower, a whiteout below an already
recreated directory should keep that directory but stop older lower
entries from being merged into it.

Only treat the lower whiteout as an opaque marker when the upper entry
is a directory.  If the upper entry is not a directory, keep the normal
upper-exists behavior and ignore the lower entry.

Closes: https://github.com/erofs/erofs-utils/issues/49
Assisted-by: Codex:GPT-5.5
Signed-off-by: Yifan Zhao <[email protected]>
---
 lib/rebuild.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/rebuild.c b/lib/rebuild.c
index 51dfe18..108a464 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -401,7 +401,13 @@ static int erofs_rebuild_dirent_iter(struct 
erofs_dir_context *ctx)
                        .nid = ctx->de_nid
                };
                ret = erofs_read_inode_from_disk(&src);
-               if (ret || !S_ISDIR(src.i_mode))
+               if (ret)
+                       goto out;
+               if (erofs_inode_is_whiteout(&src)) {
+                       d->inode->opaque = true;
+                       goto out;
+               }
+               if (!S_ISDIR(src.i_mode))
                        goto out;
                mergedir = d->inode;
                inode = dir = &src;
-- 
2.47.3


Reply via email to