On Thu, Feb 26, 2026 at 10:50 AM Gao Xiang <[email protected]> wrote: > > Hi Inseob, > > On 2026/2/26 08:59, Inseob Kim wrote: > > Add --nid and --path options to fsck.erofs to allow users to check > > or extract specific sub-directories or files instead of the entire > > filesystem. > > > > This is useful for targeted data recovery or verifying specific > > image components without the overhead of a full traversal. > > Thanks for the patch!
Thank *you* for quick response! > > > > > Signed-off-by: Inseob Kim <[email protected]> > > --- > > fsck/main.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- > > 1 file changed, 40 insertions(+), 10 deletions(-) > > > > diff --git a/fsck/main.c b/fsck/main.c > > index ab697be..a7d9f46 100644 > > --- a/fsck/main.c > > +++ b/fsck/main.c > > @@ -39,6 +39,8 @@ struct erofsfsck_cfg { > > bool preserve_owner; > > bool preserve_perms; > > bool dump_xattrs; > > + erofs_nid_t nid; > > + const char *inode_path; > > bool nosbcrc; > > }; > > static struct erofsfsck_cfg fsckcfg; > > @@ -59,6 +61,8 @@ static struct option long_options[] = { > > {"offset", required_argument, 0, 12}, > > {"xattrs", no_argument, 0, 13}, > > {"no-xattrs", no_argument, 0, 14}, > > + {"nid", required_argument, 0, 15}, > > + {"path", required_argument, 0, 16}, > > {"no-sbcrc", no_argument, 0, 512}, > > {0, 0, 0, 0}, > > }; > > @@ -110,6 +114,8 @@ static void usage(int argc, char **argv) > > " --extract[=X] check if all files are well encoded, > > optionally\n" > > " extract to X\n" > > " --offset=# skip # bytes at the beginning of > > IMAGE\n" > > + " --nid=# check or extract from the target > > inode of nid #\n" > > + " --path=X check or extract from the target > > inode of path X\n" > > " --no-sbcrc bypass the superblock checksum > > verification\n" > > " --[no-]xattrs whether to dump extended attributes > > (default off)\n" > > "\n" > > @@ -245,6 +251,12 @@ static int erofsfsck_parse_options_cfg(int argc, char > > **argv) > > case 14: > > fsckcfg.dump_xattrs = false; > > break; > > + case 15: > > + fsckcfg.nid = (erofs_nid_t)atoll(optarg); > > + break; > > + case 16: > > + fsckcfg.inode_path = optarg; > > + break; > > case 512: > > fsckcfg.nosbcrc = true; > > break; > > @@ -981,7 +993,8 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, > > erofs_nid_t nid) > > > > if (S_ISDIR(inode.i_mode)) { > > struct erofs_dir_context ctx = { > > - .flags = EROFS_READDIR_VALID_PNID, > > + .flags = (pnid == nid && nid != g_sbi.root_nid) ? > > Does it relax the validatation check? > > and does (nid == pnid && nid == fsckcfg.nid) work? It shouldn't relax the existing validation check. `erofsfsck_check_inode` is called with `err = erofsfsck_check_inode(fsckcfg.nid, fsckcfg.nid);`. * If a given path is not the root, `nid`'s parent `..` will differ from `pnid`, causing failure. This condition only relaxes the starting directory. * In the case of the root, `nid`'s parent `..` should indeed be itself. So we can still validate. If you have any better suggestions, I'll follow them. > > > + 0 : EROFS_READDIR_VALID_PNID, > > .pnid = pnid, > > .dir = &inode, > > .cb = erofsfsck_dirent_iter, > > @@ -1033,6 +1046,8 @@ int main(int argc, char *argv[]) > > fsckcfg.preserve_owner = fsckcfg.superuser; > > fsckcfg.preserve_perms = fsckcfg.superuser; > > fsckcfg.dump_xattrs = false; > > + fsckcfg.nid = 0; > > + fsckcfg.inode_path = NULL; > > > > err = erofsfsck_parse_options_cfg(argc, argv); > > if (err) { > > @@ -1068,22 +1083,37 @@ int main(int argc, char *argv[]) > > if (fsckcfg.extract_path) > > erofsfsck_hardlink_init(); > > > > - if (erofs_sb_has_fragments(&g_sbi) && g_sbi.packed_nid > 0) { > > - err = erofs_packedfile_init(&g_sbi, false); > > + if (fsckcfg.inode_path) { > > + struct erofs_inode inode = { .sbi = &g_sbi }; > > + > > + err = erofs_ilookup(fsckcfg.inode_path, &inode); > > if (err) { > > - erofs_err("failed to initialize packedfile: %s", > > - erofs_strerror(err)); > > + erofs_err("failed to lookup %s", fsckcfg.inode_path); > > goto exit_hardlink; > > } > > It would be better to check if it's a directory. My intention was that we support both directories and files. Or should I create a separate flag like `--cat` in dump.erofs? > > Thanks, > Gao Xiang > > > + fsckcfg.nid = inode.nid; > > + } else if (!fsckcfg.nid) { > > + fsckcfg.nid = g_sbi.root_nid; > > + } > > > > - err = erofsfsck_check_inode(g_sbi.packed_nid, > > g_sbi.packed_nid); > > - if (err) { > > - erofs_err("failed to verify packed file"); > > - goto exit_packedinode; > > + if (!fsckcfg.inode_path && fsckcfg.nid == g_sbi.root_nid) { > > + if (erofs_sb_has_fragments(&g_sbi) && g_sbi.packed_nid > 0) { > > + err = erofs_packedfile_init(&g_sbi, false); > > + if (err) { > > + erofs_err("failed to initialize packedfile: > > %s", > > + erofs_strerror(err)); > > + goto exit_hardlink; > > + } > > + > > + err = erofsfsck_check_inode(g_sbi.packed_nid, > > g_sbi.packed_nid); > > + if (err) { > > + erofs_err("failed to verify packed file"); > > + goto exit_packedinode; > > + } > > } > > } > > > > - err = erofsfsck_check_inode(g_sbi.root_nid, g_sbi.root_nid); > > + err = erofsfsck_check_inode(fsckcfg.nid, fsckcfg.nid); > > if (fsckcfg.corrupted) { > > if (!fsckcfg.extract_path) > > erofs_err("Found some filesystem corruption"); > -- Inseob Kim | Software Engineer | [email protected]
