Skip site navigation (1)Skip section navigation (2)
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>