diff options
author | mckusick <mckusick@FreeBSD.org> | 2002-04-07 05:16:33 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2002-04-07 05:16:33 +0000 |
commit | 1eec92e1b680f6618c533de8bde981b9a3059b9b (patch) | |
tree | ee192a98c2aa8b7ab3a452e7d7aace1011db8ce8 | |
parent | f7f35bd6ba0fafdffb8f209063c0991c5f39657a (diff) | |
download | FreeBSD-src-1eec92e1b680f6618c533de8bde981b9a3059b9b.zip FreeBSD-src-1eec92e1b680f6618c533de8bde981b9a3059b9b.tar.gz |
When checking the alternate superblock, we used to copy any fields
that might have changed, then did a byte-by-byte comparison with
the alternate. If any unused fields got used, they had to be added
to the exception list. Such changes caused too many false alarms.
So, I have changed the comparison algorithm to compare a selected
set of fields that are not expected to change. This new algorithm
causes far fewer false hits and still does a good job of detecting
problems when they have really occurred. In particular, this change
should ease the transition to kernels supporting UFS2 which make
some significant changes to the superblock.
Sponsored by: DARPA, NAI Labs
-rw-r--r-- | sbin/fsck_ffs/setup.c | 86 |
1 files changed, 25 insertions, 61 deletions
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 529945a..84fe0e5 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -376,9 +376,6 @@ readsb(int listerr) { badsb(listerr, "NCG OUT OF RANGE"); return (0); } if (sblock.fs_cpg < 1) { badsb(listerr, "CPG OUT OF RANGE"); return (0); } - if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || - (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) - { badsb(listerr, "NCYL LESS THAN NCG*CPG"); return (0); } if (sblock.fs_sbsize > SBSIZE) { badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); } /* @@ -394,69 +391,36 @@ readsb(int listerr) return (1); } /* - * Set all possible fields that could differ, then do check - * of whole super block against an alternate super block. + * Compare all fields that should not differ in alternate super block. * When an alternate super-block is specified this check is skipped. */ getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); if (asblk.b_errs) return (0); - altsblock.fs_firstfield = sblock.fs_firstfield; - altsblock.fs_unused_1 = sblock.fs_unused_1; - altsblock.fs_time = sblock.fs_time; - altsblock.fs_cstotal = sblock.fs_cstotal; - altsblock.fs_cgrotor = sblock.fs_cgrotor; - altsblock.fs_fmod = sblock.fs_fmod; - altsblock.fs_clean = sblock.fs_clean; - altsblock.fs_ronly = sblock.fs_ronly; - altsblock.fs_flags = sblock.fs_flags; - altsblock.fs_maxcontig = sblock.fs_maxcontig; - altsblock.fs_minfree = sblock.fs_minfree; - altsblock.fs_optim = sblock.fs_optim; - altsblock.fs_rotdelay = sblock.fs_rotdelay; - altsblock.fs_maxbpg = sblock.fs_maxbpg; - memmove(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp); - altsblock.fs_csp = sblock.fs_csp; - altsblock.fs_maxcluster = sblock.fs_maxcluster; - altsblock.fs_contigdirs = sblock.fs_contigdirs; - altsblock.fs_active = sblock.fs_active; - altsblock.fs_avgfilesize = sblock.fs_avgfilesize; - altsblock.fs_avgfpdir = sblock.fs_avgfpdir; - altsblock.fs_pendingblocks = sblock.fs_pendingblocks; - altsblock.fs_pendinginodes = sblock.fs_pendinginodes; - memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt); - memmove(altsblock.fs_snapinum, sblock.fs_snapinum, - sizeof sblock.fs_snapinum); - memmove(altsblock.fs_sparecon, - sblock.fs_sparecon, sizeof sblock.fs_sparecon); - /* - * The following should not have to be copied. - */ - altsblock.fs_fsbtodb = sblock.fs_fsbtodb; - altsblock.fs_interleave = sblock.fs_interleave; - altsblock.fs_npsect = sblock.fs_npsect; - altsblock.fs_nrpos = sblock.fs_nrpos; - altsblock.fs_state = sblock.fs_state; - altsblock.fs_qbmask = sblock.fs_qbmask; - altsblock.fs_qfmask = sblock.fs_qfmask; - altsblock.fs_state = sblock.fs_state; - altsblock.fs_maxfilesize = sblock.fs_maxfilesize; - if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) { - if (debug) { - long *nlp, *olp, *endlp; - - printf("superblock mismatches\n"); - nlp = (long *)&altsblock; - olp = (long *)&sblock; - endlp = olp + (sblock.fs_sbsize / sizeof *olp); - for ( ; olp < endlp; olp++, nlp++) { - if (*olp == *nlp) - continue; - printf( - "offset %d, original %ld, alternate %ld\n", - olp - (long *)&sblock, *olp, *nlp); - } - } + if (altsblock.fs_sblkno != sblock.fs_sblkno || + altsblock.fs_cblkno != sblock.fs_cblkno || + altsblock.fs_iblkno != sblock.fs_iblkno || + altsblock.fs_dblkno != sblock.fs_dblkno || + altsblock.fs_cgoffset != sblock.fs_cgoffset || + altsblock.fs_cgmask != sblock.fs_cgmask || + altsblock.fs_ncg != sblock.fs_ncg || + altsblock.fs_bsize != sblock.fs_bsize || + altsblock.fs_fsize != sblock.fs_fsize || + altsblock.fs_frag != sblock.fs_frag || + altsblock.fs_bmask != sblock.fs_bmask || + altsblock.fs_fmask != sblock.fs_fmask || + altsblock.fs_bshift != sblock.fs_bshift || + altsblock.fs_fshift != sblock.fs_fshift || + altsblock.fs_fragshift != sblock.fs_fragshift || + altsblock.fs_fsbtodb != sblock.fs_fsbtodb || + altsblock.fs_sbsize != sblock.fs_sbsize || + altsblock.fs_nindir != sblock.fs_nindir || + altsblock.fs_inopb != sblock.fs_inopb || + altsblock.fs_cssize != sblock.fs_cssize || + altsblock.fs_cpg != sblock.fs_cpg || + altsblock.fs_ipg != sblock.fs_ipg || + altsblock.fs_fpg != sblock.fs_fpg || + altsblock.fs_magic != sblock.fs_magic) { badsb(listerr, "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); return (0); |