Just record all parent directories to address this issue as a trivial solution for now.
Closes: https://github.com/erofs/erofs-utils/issues/15 Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- fsck/main.c | 17 +++++++++++++++-- lib/dir.c | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/fsck/main.c b/fsck/main.c index 372fee6..0e8b944 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -20,7 +20,13 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid); +struct erofsfsck_dirstack { + erofs_nid_t dirs[PATH_MAX]; + int top; +}; + struct erofsfsck_cfg { + struct erofsfsck_dirstack dirstack; u64 physical_blocks; u64 logical_blocks; char *extract_path; @@ -967,7 +973,7 @@ verify: static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid) { - int ret; + int ret, i; struct erofs_inode inode; erofs_dbg("check inode: nid(%llu)", nid | 0ULL); @@ -999,7 +1005,6 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid) return ret; } - /* XXXX: the dir depth should be restricted in order to avoid loops */ if (S_ISDIR(inode.i_mode)) { struct erofs_dir_context ctx = { .flags = EROFS_READDIR_VALID_PNID, @@ -1008,7 +1013,15 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid) .cb = erofsfsck_dirent_iter, }; + /* XXX: support the deeper cases later */ + if (fsckcfg.dirstack.top >= ARRAY_SIZE(fsckcfg.dirstack.dirs)) + return -ENAMETOOLONG; + for (i = 0; i < fsckcfg.dirstack.top; ++i) + if (inode.nid == fsckcfg.dirstack.dirs[i]) + return -ELOOP; + fsckcfg.dirstack.dirs[fsckcfg.dirstack.top++] = pnid; ret = erofs_iterate_dir(&ctx, true); + --fsckcfg.dirstack.top; } if (!ret && !erofs_is_packed_inode(&inode)) diff --git a/lib/dir.c b/lib/dir.c index 1223cbc..d786a5b 100644 --- a/lib/dir.c +++ b/lib/dir.c @@ -179,7 +179,7 @@ int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck) } if (fsck && (ctx->flags & EROFS_READDIR_ALL_SPECIAL_FOUND) != - EROFS_READDIR_ALL_SPECIAL_FOUND) { + EROFS_READDIR_ALL_SPECIAL_FOUND && !err) { erofs_err("`.' or `..' dirent is missing @ nid %llu", dir->nid | 0ULL); return -EFSCORRUPTED; -- 2.43.5