Subject: bin/15449: fsck_ffs FS_42POSTBLFMT compatibility bug
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dbj@netbsd.org>
List: netbsd-bugs
Date: 01/31/2002 18:55:20
>Number: 15449
>Category: bin
>Synopsis: fsck_ffs FS_42POSTBLFMT compatibility bug
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jan 31 15:57:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Darrin B. Jewell
>Release: NetBSD 1.5ZA 20020131
>Organization:
>Environment:
System: NetBSD quiteria 1.5ZA NetBSD 1.5ZA (QUITERIA) #1: Thu Jan 17 23:58:17 EST 2002 dbj@quiteria:/usr/src/sys/arch/macppc/compile/QUITERIA macppc
Architecture: powerpc
Machine: macppc
>Description:
fsck_ffs, when run on old filesystems that set FS_42POSTBLFMT,
will check the sblock->fs_interleave and sblock->fs_npsect fields,
for validity, even though these fields were not used by that
filesystem version.
>How-To-Repeat:
Try to fsck an old filesystem that sets FS_42POSTBLFMT.
>Fix:
Please review the following fix. I plan to commit this patch unless I
get negative feedback.
Darrin
Index: pass5.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/pass5.c,v
retrieving revision 1.27
diff -u -r1.27 pass5.c
--- pass5.c 2001/08/17 02:18:47 1.27
+++ pass5.c 2002/01/31 23:43:23
@@ -64,6 +64,7 @@
pass5()
{
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
+ int32_t savednpsect, savedinterleave;
int inomapsize, blkmapsize;
struct fs *fs = sblock;
ufs_daddr_t dbase, dmax;
@@ -136,7 +137,11 @@
inomapsize = &ocg->cg_free[0] - (u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC;
savednrpos = fs->fs_nrpos;
+ savednpsect = fs->fs_npsect;
+ savedinterleave = fs->fs_interleave;
fs->fs_nrpos = 8;
+ fs->fs_npsect = fs->fs_nsect;
+ fs->fs_interleave = 1;
break;
case FS_DYNAMICPOSTBLFMT:
@@ -409,8 +414,11 @@
cgdirty();
}
}
- if (fs->fs_postblformat == FS_42POSTBLFMT)
+ if (fs->fs_postblformat == FS_42POSTBLFMT) {
fs->fs_nrpos = savednrpos;
+ fs->fs_npsect = savednpsect;
+ fs->fs_interleave = savedinterleave;
+ }
if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0) {
if (dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
Index: setup.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/setup.c,v
retrieving revision 1.52
diff -u -r1.52 setup.c
--- setup.c 2001/12/19 10:05:20 1.52
+++ setup.c 2002/01/31 23:43:23
@@ -199,8 +199,9 @@
sbdirty();
}
}
- if (sblock->fs_interleave < 1 ||
- sblock->fs_interleave > sblock->fs_nsect) {
+ if (sblock->fs_postblformat != FS_42POSTBLFMT &&
+ (sblock->fs_interleave < 1 ||
+ sblock->fs_interleave > sblock->fs_nsect)) {
pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK",
sblock->fs_interleave);
sblock->fs_interleave = 1;
@@ -211,8 +212,9 @@
dirty(&asblk);
}
}
- if (sblock->fs_npsect < sblock->fs_nsect ||
- sblock->fs_npsect > sblock->fs_nsect*2) {
+ if (sblock->fs_postblformat != FS_42POSTBLFMT &&
+ (sblock->fs_npsect < sblock->fs_nsect ||
+ sblock->fs_npsect > sblock->fs_nsect*2)) {
pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK",
sblock->fs_npsect);
sblock->fs_npsect = sblock->fs_nsect;
@@ -324,6 +326,10 @@
doinglevel1++;
sblock->fs_postblformat = FS_DYNAMICPOSTBLFMT;
sblock->fs_nrpos = 8;
+ if (sblock->fs_npsect < sblock->fs_nsect)
+ sblock->fs_npsect = sblock->fs_nsect;
+ if (sblock->fs_interleave < 1)
+ sblock->fs_interleave = 1;
sblock->fs_postbloff =
(char *)(&sblock->fs_opostbl[0][0]) -
(char *)(&sblock->fs_firstfield);
>Release-Note:
>Audit-Trail:
>Unformatted: