erofs-utils: fix `Not a directory` error for incremental builds
authorGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 22 Nov 2024 07:56:59 +0000 (15:56 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 22 Nov 2024 07:59:46 +0000 (15:59 +0800)
If an incremental layer contains a directory but the same path in
the base layer is a non-directory, it will fail unexpectedly.

Fix it now.

Reported-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
Co-developped-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
Fixes: f64d9d02576b ("erofs-utils: introduce incremental builds")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20241122075659.2869515-1-hsiangkao@linux.alibaba.com
lib/rebuild.c

index 08c1b86025cb08a64f9905a1d8d8f61534d29e7b..b37823e4885832e33192ff03dc3de886a470a408 100644 (file)
@@ -465,7 +465,9 @@ static int erofs_rebuild_basedir_dirent_iter(struct erofs_dir_context *ctx)
                struct erofs_inode *inode = d->inode;
 
                /* update sub-directories only for recursively loading */
-               if (S_ISDIR(inode->i_mode)) {
+               if (S_ISDIR(inode->i_mode) &&
+                   (ctx->de_ftype == EROFS_FT_DIR ||
+                    ctx->de_ftype == EROFS_FT_UNKNOWN)) {
                        list_del(&inode->i_hash);
                        inode->dev = dir->sbi->dev;
                        inode->i_ino[1] = ctx->de_nid;
@@ -497,6 +499,15 @@ int erofs_rebuild_load_basedir(struct erofs_inode *dir)
        if (__erofs_unlikely(IS_ROOT(dir)))
                dir->xattr_isize = fakeinode.xattr_isize;
 
+       /*
+        * May be triggered if ftype == EROFS_FT_UNKNOWN, which is impossible
+        * with the current mkfs.
+        */
+       if (__erofs_unlikely(!S_ISDIR(fakeinode.i_mode))) {
+               DBG_BUGON(1);
+               return 0;
+       }
+
        ctx = (struct erofs_rebuild_dir_context) {
                .ctx.dir = &fakeinode,
                .ctx.cb = erofs_rebuild_basedir_dirent_iter,