erofs-utils: rebuild: set the appropriate `dev` field for dirs
authorHongzhen Luo <hongzhen@linux.alibaba.com>
Wed, 27 Nov 2024 11:13:46 +0000 (19:13 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 29 Nov 2024 07:27:12 +0000 (15:27 +0800)
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 <hongzhen@linux.alibaba.com>
Link: https://lore.kernel.org/r/20241127111346.49290-1-hongzhen@linux.alibaba.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
lib/rebuild.c
lib/tar.c

index b37823e4885832e33192ff03dc3de886a470a408..3e58f00e0b2c30ad200bbb06cd36b4f1f7813bd1 100644 (file)
@@ -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);
index 990c6cb1b3729e2aaf02db11c768cfc8fe2f9ed8..0dd990ea077dfd4d1f8813a8558acc4ced33034d 100644 (file)
--- 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)