[PATCH 2/7] erofs-utils: mkfs: separate pnid fixup for incremental builds from `validnid`

Gao Xiang hsiangkao at linux.alibaba.com
Thu Oct 16 13:48:10 AEDT 2025


This ensures they are not buried in the `validnid` dump.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/internal.h |  8 +++++---
 lib/inode.c              | 13 +++++++------
 lib/rebuild.c            |  6 ++++--
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index e8d8667..4de6563 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -338,15 +338,17 @@ static inline struct erofs_inode *erofs_parent_inode(struct erofs_inode *inode)
 #define IS_ROOT(x)	((x) == erofs_parent_inode(x))
 
 #define EROFS_DENTRY_NAME_ALIGNMENT	4
+
+#define EROFS_DENTRY_FLAG_VALIDNID	0x01
+#define EROFS_DENTRY_FLAG_FIXUP_PNID	0x02
 struct erofs_dentry {
 	struct list_head d_child;	/* child of parent list */
 	union {
 		struct erofs_inode *inode;
 		erofs_nid_t nid;
 	};
-	u8 namelen;
-	u8 type;
-	bool validnid;
+	u8 namelen, type;
+	u8 flags;
 	char name[];
 };
 
diff --git a/lib/inode.c b/lib/inode.c
index 4a834b4..d16468d 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -187,7 +187,7 @@ struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
 	d->inode = NULL;
 	d->namelen = namelen;
 	d->type = EROFS_FT_UNKNOWN;
-	d->validnid = false;
+	d->flags = 0;
 	list_add_tail(&d->d_child, &parent->i_subdirs);
 	return d;
 }
@@ -425,10 +425,10 @@ static void erofs_d_invalidate(struct erofs_dentry *d)
 {
 	struct erofs_inode *const inode = d->inode;
 
-	if (d->validnid)
+	if (d->flags & EROFS_DENTRY_FLAG_VALIDNID)
 		return;
 	d->nid = erofs_lookupnid(inode);
-	d->validnid = true;
+	d->flags |= EROFS_DENTRY_FLAG_VALIDNID;
 	erofs_iput(inode);
 }
 
@@ -536,7 +536,7 @@ static int erofs_write_dir_file(struct erofs_inode *dir)
 		unsigned int len = d->namelen + sizeof(struct erofs_dirent);
 
 		/* XXX: a bit hacky, but to avoid another traversal */
-		if (d->validnid && d->type == EROFS_FT_DIR) {
+		if (d->flags & EROFS_DENTRY_FLAG_FIXUP_PNID) {
 			ret = erofs_rebuild_inode_fix_pnid(dir, d->nid);
 			if (ret)
 				return ret;
@@ -1690,7 +1690,7 @@ err_closedir:
 
 bool erofs_dentry_is_wht(struct erofs_sb_info *sbi, struct erofs_dentry *d)
 {
-	if (!d->validnid)
+	if (!(d->flags & EROFS_DENTRY_FLAG_VALIDNID))
 		return erofs_inode_is_whiteout(d->inode);
 	if (d->type == EROFS_FT_CHRDEV) {
 		struct erofs_inode ei = { .sbi = sbi, .nid = d->nid };
@@ -1933,7 +1933,8 @@ static int erofs_mkfs_dump_tree(struct erofs_importer *im, bool rebuild,
 		list_for_each_entry(d, &dir->i_subdirs, d_child) {
 			struct erofs_inode *inode = d->inode;
 
-			if (is_dot_dotdot(d->name) || d->validnid)
+			if (is_dot_dotdot(d->name) ||
+			    (d->flags & EROFS_DENTRY_FLAG_VALIDNID))
 				continue;
 
 			if (!erofs_inode_visited(inode)) {
diff --git a/lib/rebuild.c b/lib/rebuild.c
index c5b44d5..f89a17c 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -484,12 +484,14 @@ static int erofs_rebuild_basedir_dirent_iter(struct erofs_dir_context *ctx)
 	if (d->type == EROFS_FT_UNKNOWN) {
 		d->nid = ctx->de_nid;
 		d->type = ctx->de_ftype;
-		d->validnid = true;
+		d->flags |= EROFS_DENTRY_FLAG_VALIDNID;
+		if (d->type == EROFS_FT_DIR)
+			d->flags |= EROFS_DENTRY_FLAG_FIXUP_PNID;
 		if (!mergedir->whiteouts && erofs_dentry_is_wht(dir->sbi, d))
 			mergedir->whiteouts = true;
 		*rctx->i_nlink += (ctx->de_ftype == EROFS_FT_DIR);
 		++*rctx->nr_subdirs;
-	} else if (__erofs_unlikely(d->validnid)) {
+	} else if (__erofs_unlikely(d->flags & EROFS_DENTRY_FLAG_VALIDNID)) {
 		/* The base image appears to be corrupted */
 		DBG_BUGON(1);
 		ret = -EFSCORRUPTED;
-- 
2.43.5



More information about the Linux-erofs mailing list