diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 95dccf0d672d..1c8b9169e590 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -466,7 +466,8 @@ void cgdirty(struct bufarea *); struct bufarea *cglookup(int cg); int changeino(ino_t dir, const char *name, ino_t newnum, int depth); void check_blkcnt(struct inode *ip); -int check_cgmagic(int cg, struct bufarea *cgbp, int requestrebuild); +int check_cgmagic(int cg, struct bufarea *cgbp); +void rebuild_cg(int cg, struct bufarea *cgbp); void check_dirdepth(struct inoinfo *inp); int chkrange(ufs2_daddr_t blk, int cnt); void ckfini(int markclean); diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c index 1df52b7cfdc9..48810954ba94 100644 --- a/sbin/fsck_ffs/fsutil.c +++ b/sbin/fsck_ffs/fsutil.c @@ -989,9 +989,7 @@ blzero(int fd, ufs2_daddr_t blk, long size) * Verify cylinder group's magic number and other parameters. If the * test fails, offer an option to rebuild the whole cylinder group. * - * Return 1 if the cylinder group is good or if repair is requested - * and is completed successfully. Return 0 if it is bad or if a repair - * has been requested but is not completed successfully. + * Return 1 if the cylinder group is good or return 0 if it is bad. */ #undef CHK #define CHK(lhs, op, rhs, fmt) \ @@ -1003,7 +1001,7 @@ blzero(int fd, ufs2_daddr_t blk, long size) error = 1; \ } int -check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild) +check_cgmagic(int cg, struct bufarea *cgbp) { struct cg *cgp = cgbp->b_un.b_cg; uint32_t cghash, calchash; @@ -1077,15 +1075,16 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild) return (0); prevfailcg = cg; pfatal("CYLINDER GROUP %d: INTEGRITY CHECK FAILED", cg); - if (!request_rebuild) { - printf("\n"); - return (0); - } - if (!reply("REBUILD CYLINDER GROUP")) { - printf("YOU WILL NEED TO RERUN FSCK.\n"); - rerun = 1; - return (0); - } + printf("\n"); + return (0); +} + +void +rebuild_cg(int cg, struct bufarea *cgbp) +{ + struct cg *cgp = cgbp->b_un.b_cg; + long start; + /* * Zero out the cylinder group and then initialize critical fields. * Bit maps and summaries will be recalculated by later passes. @@ -1127,7 +1126,6 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild) } cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize); cgdirty(cgbp); - return (1); } /* @@ -1191,7 +1189,7 @@ std_checkblkavail(ufs2_daddr_t blkno, long frags) cg = dtog(&sblock, blkno + j); cgbp = cglookup(cg); cgp = cgbp->b_un.b_cg; - if (!check_cgmagic(cg, cgbp, 0)) + if (!check_cgmagic(cg, cgbp)) return (-((cg + 1) * sblock.fs_fpg - sblock.fs_frag)); baseblk = dtogd(&sblock, blkno + j); for (k = 0; k < frags; k++) { diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c index b65589b5bd08..cd2c9df878a8 100644 --- a/sbin/fsck_ffs/gjournal.c +++ b/sbin/fsck_ffs/gjournal.c @@ -97,7 +97,7 @@ gjournal_check(const char *filesys) } cgbp = cglookup(cg); cgp = cgbp->b_un.b_cg; - if (!check_cgmagic(cg, cgbp, 0)) { + if (!check_cgmagic(cg, cgbp)) { rerun = 1; ckfini(0); return; diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index 2d563f617a56..04891447254e 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -1394,7 +1394,7 @@ retry: cg = ino_to_cg(&sblock, ino); cgbp = cglookup(cg); cgp = cgbp->b_un.b_cg; - if (!check_cgmagic(cg, cgbp, 0)) { + if (!check_cgmagic(cg, cgbp)) { if (anyino == 0) return (0); request = (cg + 1) * sblock.fs_ipg; diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 2bd61dda7030..566fbe5ccd15 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -492,7 +492,7 @@ checkfilesys(char *filesys) snapflush(std_checkblkavail); if (cgheader_corrupt) { printf("PHASE 5 SKIPPED DUE TO CORRUPT CYLINDER GROUP " - "HEADER(S)\n"); + "HEADER(S)\n\n"); } else { pass5(); IOstats("Pass5"); diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c index 55233e0bc4f4..e784fd29dc1c 100644 --- a/sbin/fsck_ffs/pass1.c +++ b/sbin/fsck_ffs/pass1.c @@ -100,11 +100,17 @@ pass1(void) cgbp = cglookup(c); cgp = cgbp->b_un.b_cg; rebuiltcg = 0; - if (!check_cgmagic(c, cgbp, 0)) { - if (!check_cgmagic(c, cgbp, 1)) + if (!check_cgmagic(c, cgbp)) { + if (!reply("REBUILD CYLINDER GROUP")) { cgheader_corrupt = 1; - else + if (!nflag) { + printf("YOU WILL NEED TO RERUN FSCK.\n"); + rerun = 1; + } + } else { + rebuild_cg(c, cgbp); rebuiltcg = 1; + } } if (!rebuiltcg && sblock.fs_magic == FS_UFS2_MAGIC) { inosused = cgp->cg_initediblk; diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c index 40bbe340bfc6..9c8e1322b801 100644 --- a/sbin/fsck_ffs/suj.c +++ b/sbin/fsck_ffs/suj.c @@ -183,7 +183,7 @@ cg_lookup(int cgx) if (lastcg && lastcg->sc_cgx == cgx) return (lastcg); cgbp = cglookup(cgx); - if (!check_cgmagic(cgx, cgbp, 0)) + if (!check_cgmagic(cgx, cgbp)) err_suj("UNABLE TO REBUILD CYLINDER GROUP %d", cgx); hd = &cghash[HASH(cgx)]; LIST_FOREACH(sc, hd, sc_next) @@ -396,7 +396,7 @@ suj_checkblkavail(ufs2_daddr_t blkno, long frags) cg = dtog(&sblock, blkno); cgbp = cglookup(cg); cgp = cgbp->b_un.b_cg; - if (!check_cgmagic(cg, cgbp, 0)) + if (!check_cgmagic(cg, cgbp)) return (-((cg + 1) * sblock.fs_fpg - sblock.fs_frag)); baseblk = dtogd(&sblock, blkno); for (j = 0; j <= sblock.fs_frag - frags; j++) {