[PATCH 1/3] erofs-utils: lib: get rid of erofs_init_empty_dir()
Gao Xiang
hsiangkao at linux.alibaba.com
Thu Jul 31 13:16:40 AEST 2025
... and defer insertion of `.` and `..` entries when preparing
directory inodes.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
include/erofs/inode.h | 1 -
lib/inode.c | 52 +++++++++++++++++++++----------------------
lib/rebuild.c | 4 ++--
lib/tar.c | 4 +---
4 files changed, 28 insertions(+), 33 deletions(-)
diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index fe86101d..b0ac5bee 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -37,7 +37,6 @@ struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks);
bool erofs_dentry_is_wht(struct erofs_sb_info *sbi, struct erofs_dentry *d);
int erofs_rebuild_dump_tree(struct erofs_inode *dir, bool incremental);
-int erofs_init_empty_dir(struct erofs_inode *dir);
int __erofs_fill_inode(struct erofs_inode *inode, struct stat *st,
const char *path);
struct erofs_inode *erofs_new_inode(struct erofs_sb_info *sbi);
diff --git a/lib/inode.c b/lib/inode.c
index 4f6715af..cbce712b 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -226,9 +226,14 @@ static int comp_subdir(const void *a, const void *b)
return cmpsgn(da->namelen, db->namelen);
}
-int erofs_init_empty_dir(struct erofs_inode *dir)
+static int erofs_prepare_dir_file(struct erofs_inode *dir,
+ unsigned int nr_subdirs)
{
- struct erofs_dentry *d;
+ struct erofs_sb_info *sbi = dir->sbi;
+ struct erofs_dentry *d, *n, **sorted_d;
+ bool dot_omitted = cfg.c_dot_omitted;
+ unsigned int i;
+ unsigned int d_size = 0;
/* dot is pointed to the current dir inode */
d = erofs_d_alloc(dir, ".");
@@ -244,18 +249,7 @@ int erofs_init_empty_dir(struct erofs_inode *dir)
d->inode = erofs_igrab(erofs_parent_inode(dir));
d->type = EROFS_FT_DIR;
- dir->i_nlink = 2;
- return 0;
-}
-
-static int erofs_prepare_dir_file(struct erofs_inode *dir,
- unsigned int nr_subdirs)
-{
- struct erofs_sb_info *sbi = dir->sbi;
- struct erofs_dentry *d, *n, **sorted_d;
- bool dot_omitted = cfg.c_dot_omitted;
- unsigned int i;
- unsigned int d_size = 0;
+ nr_subdirs += 2;
sorted_d = malloc(nr_subdirs * sizeof(d));
if (!sorted_d)
@@ -1564,11 +1558,7 @@ static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
}
closedir(_dir);
- ret = erofs_init_empty_dir(dir);
- if (ret)
- return ret;
-
- ret = erofs_prepare_dir_file(dir, nr_subdirs + 2); /* sort subdirs */
+ ret = erofs_prepare_dir_file(dir, nr_subdirs); /* sort subdirs */
if (ret)
return ret;
@@ -1615,6 +1605,13 @@ bool erofs_dentry_is_wht(struct erofs_sb_info *sbi, struct erofs_dentry *d)
return false;
}
+static void erofs_dentry_kill(struct erofs_dentry *d)
+{
+ list_del(&d->d_child);
+ erofs_d_invalidate(d);
+ free(d);
+}
+
static int erofs_rebuild_handle_directory(struct erofs_inode *dir,
bool incremental)
{
@@ -1625,22 +1622,23 @@ static int erofs_rebuild_handle_directory(struct erofs_inode *dir,
int ret;
nr_subdirs = 0;
- i_nlink = 0;
+ i_nlink = 2;
list_for_each_entry_safe(d, n, &dir->i_subdirs, d_child) {
+ if (is_dot_dotdot(d->name)) {
+ DBG_BUGON(1);
+ erofs_dentry_kill(d);
+ continue;
+ }
if (delwht && erofs_dentry_is_wht(sbi, d)) {
erofs_dbg("remove whiteout %s", d->inode->i_srcpath);
- list_del(&d->d_child);
- erofs_d_invalidate(d);
- free(d);
+ erofs_dentry_kill(d);
continue;
}
i_nlink += (d->type == EROFS_FT_DIR);
++nr_subdirs;
}
-
- DBG_BUGON(i_nlink < 2); /* should have `.` and `..` */
- DBG_BUGON(nr_subdirs < i_nlink);
+ DBG_BUGON(nr_subdirs + 2 < i_nlink);
ret = erofs_prepare_dir_file(dir, nr_subdirs);
if (ret)
return ret;
@@ -2134,6 +2132,6 @@ struct erofs_inode *erofs_rebuild_make_root(struct erofs_sb_info *sbi)
root->i_parent = root;
root->i_mtime = root->sbi->epoch + root->sbi->build_time;
root->i_mtime_nsec = root->sbi->fixed_nsec;
- erofs_init_empty_dir(root);
+ root->i_nlink = 2;
return root;
}
diff --git a/lib/rebuild.c b/lib/rebuild.c
index c580f81f..26bc9aca 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -59,7 +59,7 @@ static struct erofs_dentry *erofs_rebuild_mkdir(struct erofs_inode *dir,
inode->i_mtime = dir->i_mtime;
inode->i_mtime_nsec = dir->i_mtime_nsec;
inode->dev = dir->dev;
- erofs_init_empty_dir(inode);
+ inode->i_nlink = 2;
d = erofs_d_alloc(dir, s);
if (IS_ERR(d)) {
@@ -241,7 +241,7 @@ static int erofs_rebuild_update_inode(struct erofs_sb_info *dst_sb,
inode->u.i_rdev = erofs_new_encode_dev(inode->u.i_rdev);
break;
case S_IFDIR:
- err = erofs_init_empty_dir(inode);
+ inode->i_nlink = 2;
break;
case S_IFLNK:
inode->i_link = malloc(inode->i_size + 1);
diff --git a/lib/tar.c b/lib/tar.c
index 72c12ed0..3146fc9d 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -1122,9 +1122,7 @@ new_inode:
}
inode->i_nlink++;
} else if (!inode->i_nlink) {
- ret = erofs_init_empty_dir(inode);
- if (ret)
- goto out;
+ inode->i_nlink = 2;
}
ret = tarerofs_merge_xattrs(&eh.xattrs, &tar->global.xattrs);
--
2.43.5
More information about the Linux-erofs
mailing list