Currently, setting a default `dev` value (i.e., 0) for directories
during parsing tar files can lead to the following error:

<E> erofs: bogus i_mode (0) @ nid 0
<E> erofs: failed to read inode @ 0

Consider the following incremental build scenario, where the path
"dir1/dir2" is currently being parsed in tarerofs_parse_tar() and
the directory "dir1" has never appeared before. erofs_rebuild_get_dentry()
will call erofs_rebuild_mkdir() to allocate a new inode for "dir1",
with its `dev` field set to 0 by default.

During the dump tree phase, since `dir1->dev` matches `sbi->dev` (both are 0),
erofs_rebuild_load_basedir() will be called to read the contents of directory
"dir1" from the disk. However, since there is no information for the new 
directory
"dir1" on the disk, the above error occurs.

This patch resolves the above issue by setting the appropriate value
for the directory's `dev` field during the tar file parsing phase.

Fixes: f64d9d02576b ("erofs-utils: introduce incremental builds")
Signed-off-by: Hongzhen Luo <hongz...@linux.alibaba.com>
---
v2: Implement in a more concise manner.
v1: 
https://lore.kernel.org/all/20241127092856.4106149-2-hongz...@linux.alibaba.com/
---
 lib/rebuild.c | 1 +
 lib/tar.c     | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/rebuild.c b/lib/rebuild.c
index b37823e48858..3e58f00e0b2c 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -46,6 +46,7 @@ static struct erofs_dentry *erofs_rebuild_mkdir(struct 
erofs_inode *dir,
        inode->i_gid = getgid();
        inode->i_mtime = inode->sbi->build_time;
        inode->i_mtime_nsec = inode->sbi->build_time_nsec;
+       inode->dev = dir->dev;
        erofs_init_empty_dir(inode);
 
        d = erofs_d_alloc(dir, s);
diff --git a/lib/tar.c b/lib/tar.c
index 990c6cb1b372..0dd990ea077d 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -667,6 +667,7 @@ int tarerofs_parse_tar(struct erofs_inode *root, struct 
erofs_tarfile *tar)
        unsigned int j, csum, cksum;
        int ckksum, ret, rem;
 
+       root->dev = tar->dev;
        if (eh.path)
                eh.path = strdup(eh.path);
        if (eh.link)
-- 
2.43.5

Reply via email to