Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Oct 2000 22:14:50 -0400
From:      "John W. De Boskey" <jwd@bsdwins.com>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        Tor.Egge@fast.no, jwd@FreeBSD.ORG, freebsd-current@FreeBSD.ORG, peter@FreeBSD.ORG
Subject:   Re: newfs/fsck problem (bad superblocks)
Message-ID:  <20001023221450.A46780@bsdwins.com>
In-Reply-To: <Pine.BSF.4.21.0010241241280.2027-100000@besplex.bde.org>; from bde@zeta.org.au on Tue, Oct 24, 2000 at 12:54:29PM %2B1100
References:  <200010220822.KAA59278@midten.fast.no> <Pine.BSF.4.21.0010241241280.2027-100000@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
See below..

----- Bruce Evans's Original Message -----

> On Sun, 22 Oct 2000 Tor.Egge@fast.no wrote:
> 
> > > Reverting src/sbin/newfs/mkfs.c to revision 1.29 fixes
> > > the problem.
> > > 
> > > With just a quick review of the patch, I'm not sure I
> > > understand what forces the last dirty buffer to be
> > > written.
> 
> This worried me too.
> 
> > Try the enclosed patch.  It flushes the dirty buffer before
> > program exit and before reading blocks.
> 
> There are still some serious (?) overflow bugs.
> 
> Index: mkfs.c
> ===================================================================
> RCS file: /home/ncvs/src/sbin/newfs/mkfs.c,v
> retrieving revision 1.29
> retrieving revision 1.30
> diff -c -2 -r1.29 -r1.30
> *** mkfs.c	1999/08/28 00:13:50	1.29
> --- mkfs.c	2000/10/17 00:41:36	1.30
> ...
> ***************
> *** 1341,1344 ****
> --- 1347,1381 ----
>   	}
>   	if (Nflag)
> + 		return;
> + 	done = 0;
> + 	if (wc_end == 0 && size <= WCSIZE) {
> + 		wc_sect = bno;
> + 		bcopy(bf, wc, size);
> + 		wc_end = size;
> + 		if (wc_end < WCSIZE)
> + 			return;
> + 		done = 1;
> + 	}
> + 	if (wc_sect * sectorsize + wc_end == bno * sectorsize &&
>  	            ^ overflow                   ^ overflow

   I agree it's an overflow, and I'll get a patch in for it. But
from a lucky point of view, since the overflow occurs on both sides
of the test, it's a serendipidoues match which doesn't hurt, or
the match fails, which causes the cache to flush.

> + 	    wc_end + size <= WCSIZE) {
> + 		bcopy(bf, wc + wc_end, size);
> + 		wc_end += size;
> + 		if (wc_end < WCSIZE)
> + 			return;
> + 		done = 1;
> + 	}
> + 	if (wc_end) {
> + 		if (lseek(fso, (off_t)wc_sect * sectorsize, SEEK_SET) < 0) {
>  		               ^^^^^^^ must cast like this to prevent overflow

   Well, the above can overflow, but the probability of it overflowing
when things are working correctly approaches zero :-)

   Regardless, we could put in a test to make sure the final offset
computed is valid.

-john

> + 			printf("seek error: %ld\n", (long)wc_sect);
> + 			err(35, "wtfs - writecombine");
> + 		}
> + 		n = write(fso, wc, wc_end);
> + 		if (n != wc_end) {
> + 			printf("write error: %ld\n", (long)wc_sect);
> + 			err(36, "wtfs - writecombine");
> + 		}
> + 		wc_end = 0;
> + 	}
> + 	if (done)
>   		return;
>   	if (lseek(fso, (off_t)bno * sectorsize, SEEK_SET) < 0) {
> 
> Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001023221450.A46780>