From owner-freebsd-hackers Tue Nov 12 17:20:22 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id RAA16373 for hackers-outgoing; Tue, 12 Nov 1996 17:20:22 -0800 (PST) Received: from whistle.com (s205m131.whistle.com [207.76.205.131]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id RAA16368 for ; Tue, 12 Nov 1996 17:20:20 -0800 (PST) Received: (from smap@localhost) by whistle.com (8.7.5/8.6.12) id RAA18362; Tue, 12 Nov 1996 17:19:45 -0800 (PST) Received: from bubba.whistle.com(207.76.205.7) by whistle.com via smap (V1.3) id sma018360; Tue Nov 12 17:19:43 1996 Received: (from archie@localhost) by bubba.whistle.com (8.7.5/8.6.12) id RAA08629; Tue, 12 Nov 1996 17:19:42 -0800 (PST) From: Archie Cobbs Message-Id: <199611130119.RAA08629@bubba.whistle.com> Subject: kernel and/or fsck(8) bug To: freebsd-hackers@freebsd.org Date: Tue, 12 Nov 1996 17:19:41 -0800 (PST) X-Mailer: ELM [version 2.4ME+ PL25 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 */