missing fsbtodb!
[unix-history] / usr / src / sbin / fsck / pass5.c
index 8b6754f..0e5bf4e 100644 (file)
@@ -1,6 +1,12 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char version[] = "@(#)pass5.c   3.2 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)pass5.c    5.5 (Berkeley) %G%";
+#endif not lint
 
 #include <sys/param.h>
 #include <sys/inode.h>
 
 #include <sys/param.h>
 #include <sys/inode.h>
@@ -9,152 +15,190 @@ static char version[] = "@(#)pass5.c       3.2 (Berkeley) %G%";
 
 pass5()
 {
 
 pass5()
 {
-       register int c, n, i, b, d;
-       short bo[MAXCPG][NRPOS];
-       long botot[MAXCPG];
-       long frsum[MAXFRAG];
-       int blk;
-       daddr_t cbase;
-       int blockbits = (1<<sblock.fs_frag)-1;
+       int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
+       register struct fs *fs = &sblock;
+       register struct cg *cg = &cgrp;
+       daddr_t dbase, dmax;
+       register daddr_t d;
+       register long i, j;
+       struct csum *cs;
+       time_t now;
+       struct csum cstotal;
+       struct inodesc idesc;
+       char buf[MAXBSIZE];
+       register struct cg *newcg = (struct cg *)buf;
+       struct ocg *ocg = (struct ocg *)buf;
 
 
-       bcopy(blockmap, freemap, (unsigned)bmapsz);
-       dupblk = 0;
-       n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0));
-       for (c = 0; c < sblock.fs_ncg; c++) {
-               cbase = cgbase(&sblock, c);
-               bzero((char *)botot, sizeof (botot));
-               bzero((char *)bo, sizeof (bo));
-               bzero((char *)frsum, sizeof (frsum));
-               /*
-                * need to account for the super blocks
-                * which appear (inaccurately) bad
-                */
-               n_bad += cgtod(&sblock, c) - cgsblock(&sblock, c);
-               if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0)
-                       continue;
-               if (cgrp.cg_magic != CG_MAGIC) {
+       bzero((char *)newcg, fs->fs_cgsize);
+       newcg->cg_niblk = fs->fs_ipg;
+       switch (fs->fs_postblformat) {
+
+       case FS_42POSTBLFMT:
+               basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
+               sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
+               mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
+                       (u_char *)&ocg->cg_iused[0];
+               ocg->cg_magic = CG_MAGIC;
+               savednrpos = fs->fs_nrpos;
+               fs->fs_nrpos = 8;
+               break;
+
+       case FS_DYNAMICPOSTBLFMT:
+               newcg->cg_btotoff =
+                       &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
+               newcg->cg_boff =
+                       newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
+               newcg->cg_iusedoff = newcg->cg_boff + 
+                       fs->fs_cpg * fs->fs_nrpos * sizeof(short);
+               newcg->cg_freeoff =
+                       newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
+               newcg->cg_nextfreeoff = newcg->cg_freeoff +
+                       howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
+                               NBBY);
+               newcg->cg_magic = CG_MAGIC;
+               basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
+               sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
+               mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
+               break;
+
+       default:
+               errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n",
+                       fs->fs_postblformat);
+       }
+       bzero((char *)&idesc, sizeof(struct inodesc));
+       idesc.id_type = ADDR;
+       bzero((char *)&cstotal, sizeof(struct csum));
+       (void)time(&now);
+       for (i = fs->fs_size; i < fragroundup(fs, fs->fs_size); i++)
+               setbmap(i);
+       for (c = 0; c < fs->fs_ncg; c++) {
+               getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
+               if (!cg_chkmagic(cg))
                        pfatal("CG %d: BAD MAGIC NUMBER\n", c);
                        pfatal("CG %d: BAD MAGIC NUMBER\n", c);
-                       bzero((char *)&cgrp, (int)sblock.fs_cgsize);
-               }
-               for (i = 0, n = 0; i < sblock.fs_ipg; i += NBBY, n++)
-                       if (cgrp.cg_iused[n] != 0xff)
+               dbase = cgbase(fs, c);
+               dmax = dbase + fs->fs_fpg;
+               if (dmax > fs->fs_size)
+                       dmax = fs->fs_size;
+               if (now > cg->cg_time)
+                       newcg->cg_time = cg->cg_time;
+               else
+                       newcg->cg_time = now;
+               newcg->cg_cgx = c;
+               if (c == fs->fs_ncg - 1)
+                       newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
+               else
+                       newcg->cg_ncyl = fs->fs_cpg;
+               newcg->cg_ndblk = dmax - dbase;
+               newcg->cg_cs.cs_ndir = 0;
+               newcg->cg_cs.cs_nffree = 0;
+               newcg->cg_cs.cs_nbfree = 0;
+               newcg->cg_cs.cs_nifree = fs->fs_ipg;
+               if (cg->cg_rotor < newcg->cg_ndblk)
+                       newcg->cg_rotor = cg->cg_rotor;
+               else
+                       newcg->cg_rotor = 0;
+               if (cg->cg_frotor < newcg->cg_ndblk)
+                       newcg->cg_frotor = cg->cg_frotor;
+               else
+                       newcg->cg_frotor = 0;
+               if (cg->cg_irotor < newcg->cg_niblk)
+                       newcg->cg_irotor = cg->cg_irotor;
+               else
+                       newcg->cg_irotor = 0;
+               bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum);
+               bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize);
+               if (fs->fs_postblformat == FS_42POSTBLFMT)
+                       ocg->cg_magic = CG_MAGIC;
+               j = fs->fs_ipg * c;
+               for (i = 0; i < fs->fs_ipg; j++, i++) {
+                       switch (statemap[j]) {
+
+                       case USTATE:
+                               break;
+
+                       case DSTATE:
+                       case DCLEAR:
+                       case DFOUND:
+                               newcg->cg_cs.cs_ndir++;
+                               /* fall through */
+
+                       case FSTATE:
+                       case FCLEAR:
+                               newcg->cg_cs.cs_nifree--;
+                               setbit(cg_inosused(newcg), i);
                                break;
                                break;
-               for ( ; i < sblock.fs_ipg; i++) {
-                       if (isclr(cgrp.cg_iused, i)) {
-                               if (i < cgrp.cg_irotor) {
-                                       if (debug) printf(
-                                           "cg %d, first free %d, irotor %d\n",
-                                            c, i, cgrp.cg_irotor);
-                                       cgrp.cg_irotor = i;
-                                       cgdirty();
+
+                       default:
+                               if (j < ROOTINO)
                                        break;
                                        break;
-                               }
+                               errexit("BAD STATE %d FOR INODE I=%d",
+                                   statemap[j], j);
                        }
                }
                        }
                }
-               for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
-                       blk = blkmap(&sblock, cgrp.cg_free, b);
-                       if (blk == 0)
-                               continue;
-                       if (blk == blockbits) {
-                               if (pass5check(cbase+b, sblock.fs_frag) == STOP)
-                                       goto out5;
-                               /* this is clumsy ... */
-                               n_ffree -= sblock.fs_frag;
-                               n_bfree++;
-                               botot[cbtocylno(&sblock, b)]++;
-                               bo[cbtocylno(&sblock, b)]
-                                   [cbtorpos(&sblock, b)]++;
-                               continue;
+               if (c == 0)
+                       for (i = 0; i < ROOTINO; i++) {
+                               setbit(cg_inosused(newcg), i);
+                               newcg->cg_cs.cs_nifree--;
+                       }
+               for (i = 0, d = dbase;
+                    d < dmax;
+                    d += fs->fs_frag, i += fs->fs_frag) {
+                       frags = 0;
+                       for (j = 0; j < fs->fs_frag; j++) {
+                               if (getbmap(d + j))
+                                       continue;
+                               setbit(cg_blksfree(newcg), i + j);
+                               frags++;
+                       }
+                       if (frags == fs->fs_frag) {
+                               newcg->cg_cs.cs_nbfree++;
+                               j = cbtocylno(fs, i);
+                               cg_blktot(newcg)[j]++;
+                               cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
+                       } else if (frags > 0) {
+                               newcg->cg_cs.cs_nffree += frags;
+                               blk = blkmap(fs, cg_blksfree(newcg), i);
+                               fragacct(fs, blk, newcg->cg_frsum, 1);
                        }
                        }
-                       for (d = 0; d < sblock.fs_frag; d++)
-                               if ((blk & (1<<d)) &&
-                                   pass5check(cbase + b + d, (long)1) == STOP)
-                                       goto out5;
-                       fragacct(&sblock, blk, frsum, 1);
                }
                }
-               if (bcmp((char *)cgrp.cg_frsum, (char *)frsum, sizeof(frsum))) {
-                       if (debug)
-                       for (i = 0; i < sblock.fs_frag; i++)
-                               if (cgrp.cg_frsum[i] != frsum[i])
-                               printf("cg[%d].cg_frsum[%d] have %d calc %d\n",
-                                   c, i, cgrp.cg_frsum[i], frsum[i]);
-                       frsumbad++;
+               cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
+               cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
+               cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
+               cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
+               cs = &fs->fs_cs(fs, c);
+               if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 &&
+                   dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
+                       bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs);
+                       sbdirty();
                }
                }
-               if (bcmp((char *)cgrp.cg_btot, (char *)botot, sizeof (botot))) {
-                       if (debug)
-                       for (n = 0; n < sblock.fs_cpg; n++)
-                               if (botot[n] != cgrp.cg_btot[n])
-                               printf("cg[%d].cg_btot[%d] have %d calc %d\n",
-                                   c, n, cgrp.cg_btot[n], botot[n]);
-                       offsumbad++;
+               if (cvtflag) {
+                       bcopy((char *)newcg, (char *)cg, fs->fs_cgsize);
+                       cgdirty();
+                       continue;
                }
                }
-               if (bcmp((char *)cgrp.cg_b, (char *)bo, sizeof (bo))) {
-                       if (debug)
-                       for (i = 0; i < NRPOS; i++)
-                               if (bo[n][i] != cgrp.cg_b[n][i])
-                               printf("cg[%d].cg_b[%d][%d] have %d calc %d\n",
-                                   c, n, i, cgrp.cg_b[n][i], bo[n][i]);
-                       offsumbad++;
+               if (bcmp(cg_inosused(newcg),
+                        cg_inosused(cg), mapsize) != 0 &&
+                   dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) {
+                       bcopy(cg_inosused(newcg), cg_inosused(cg), mapsize);
+                       cgdirty();
                }
                }
-       }
-out5:
-       if (dupblk)
-               pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk);
-       if (fixcg == 0) {
-               if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) {
-                       pwarn("%ld BLK(S) MISSING\n", fmax - b);
-                       fixcg = 1;
-               } else if (inosumbad + offsumbad + frsumbad + sbsumbad) {
-                       pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n",
-                           inosumbad ? "(INODE FREE) " : "",
-                           offsumbad ? "(BLOCK OFFSETS) " : "",
-                           frsumbad ? "(FRAG SUMMARIES) " : "",
-                           sbsumbad ? "(SUPER BLOCK SUMMARIES) " : "");
-                       fixcg = 1;
-               } else if (n_ffree != sblock.fs_cstotal.cs_nffree ||
-                   n_bfree != sblock.fs_cstotal.cs_nbfree) {
-                       pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK");
-                       if (preen)
-                               printf(" (FIXED)\n");
-                       if (preen || reply("FIX") == 1) {
-                               sblock.fs_cstotal.cs_nffree = n_ffree;
-                               sblock.fs_cstotal.cs_nbfree = n_bfree;
-                               sbdirty();
-                       }
+               if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 ||
+                    bcmp((char *)&cg_blktot(newcg)[0],
+                         (char *)&cg_blktot(cg)[0], sumsize) != 0) &&
+                   dofix(&idesc, "SUMMARY INFORMATION BAD")) {
+                       bcopy((char *)newcg, (char *)cg, basesize);
+                       bcopy((char *)&cg_blktot(newcg)[0],
+                             (char *)&cg_blktot(cg)[0], sumsize);
+                       cgdirty();
                }
        }
                }
        }
-       if (fixcg) {
-               pwarn("BAD CYLINDER GROUPS");
-               if (preen)
-                       printf(" (SALVAGED)\n");
-               else if (reply("SALVAGE") == 0)
-                       fixcg = 0;
-       }
-}
-
-pass5check(blk, size)
-       daddr_t blk;
-       long size;
-{
-
-       if (outrange(blk, (int)size)) {
-               fixcg = 1;
-               if (preen)
-                       pfatal("BAD BLOCKS IN BIT MAPS.");
-               if (++badblk >= MAXBAD) {
-                       printf("EXCESSIVE BAD BLKS IN BIT MAPS.");
-                       if (reply("CONTINUE") == 0)
-                               errexit("");
-                       return (STOP);
-               }
+       if (fs->fs_postblformat == FS_42POSTBLFMT)
+               fs->fs_nrpos = savednrpos;
+       if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0
+           && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
+               bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs);
+               fs->fs_ronly = 0;
+               fs->fs_fmod = 0;
+               sbdirty();
        }
        }
-       for (; size > 0; blk++, size--)
-               if (getfmap(blk)) {
-                       fixcg = 1;
-                       ++dupblk;
-               } else {
-                       n_ffree++;
-                       setfmap(blk);
-               }
-       return (KEEPON);
 }
 }