Date: Tue, 12 Nov 1996 17:19:41 -0800 (PST) From: Archie Cobbs <archie@whistle.com> To: freebsd-hackers@freebsd.org Subject: kernel and/or fsck(8) bug Message-ID: <199611130119.RAA08629@bubba.whistle.com>
next in thread | raw e-mail | index | archive | help
Hello We encountered an interesting situation where the superblock for a file system got written to disk with the "fs_fmod" flag set to one. It appears that this flag is normally supposed to be cleared during ffs_sync(), but we experienced a crash, or some other weird occurrence that left it on the disk set to 1. Later this partition was mounted read-only... and the fs_fmod field was never cleared, causing ffs_sync() to panic "rofs mod" when trying to unmount that filesystem (ffs_vfsops.c: line 790). Observation #1: As far as I can tell, the meaning of this field is ``this copy of the superblock has been modified from the real one on the disk.'' Therefore, the value of this field **in the actual superblock on the disk** should either: (a) ALWAYS be zero, in which case fsck(8) should be responsible for checking/fixing it; or (b) ALWAYS be ignored, in which case every time the superblock is read from disk this field should be set to zero. Observation #2: Currently, the only place this field is actually *used* for anything is to detect this panic condition. Presumably there is some intended future use for it; if not, it should just be taken out! Below are patches for both (a) and (b), either of which should (hopefully) address the problem. Thanks, -Archie ___________________________________________________________________________ Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com FSCK PATCH: Index: pass5.c =================================================================== RCS file: /cvs/freebsd/src/sbin/fsck/pass5.c,v retrieving revision 1.5 diff -c -r1.5 pass5.c *** 1.5 1995/05/30 06:09:06 --- pass5.c 1996/11/13 01:05:39 *************** *** 318,323 **** --- 318,332 ---- fs->fs_fmod = 0; sbdirty(); } + if (fs->fs_fmod != 0) { + pwarn("MODIFIED FLAG SET IN SUPERBLOCK"); + if (preen) + printf(" (FIXED)\n"); + if (preen || reply("FIX") == 1) { + fs->fs_fmod = 0; + sbdirty(); + } + } if (fs->fs_clean == 0) { pwarn("CLEAN FLAG NOT SET IN SUPERBLOCK"); if (preen) KERNEL PATCH: Index: ffs_vfsops.c =================================================================== RCS file: /cvs/freebsd/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.41 diff -c -r1.41 ffs_vfsops.c *** 1.41 1996/09/07 17:34:57 --- ffs_vfsops.c 1996/11/13 01:06:25 *************** *** 383,388 **** --- 383,389 ---- if (error) return (error); fs = (struct fs *)bp->b_data; + fs->fs_fmod = 0; if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) { brelse(bp); *************** *** 506,511 **** --- 507,513 ---- if (error) goto out; fs = (struct fs *)bp->b_data; + fs->fs_fmod = 0; if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) { error = EINVAL; /* XXX needs translation */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611130119.RAA08629>