Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Feb 2003 15:44:24 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Terry Lambert <tlambert2@mindspring.com>
Cc:        David Syphers <dsyphers@uchicago.edu>, Kirk McKusick <mckusick@beastie.mckusick.com>, <freebsd-current@FreeBSD.ORG>
Subject:   Re: BOOT2_UFS=UFS1_ONLY works for today's current
Message-ID:  <20030224144742.L5105-100000@gamplex.bde.org>
In-Reply-To: <3E5975D0.417C88A@mindspring.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 23 Feb 2003, Terry Lambert wrote:

> David Syphers wrote:
> > Okay, I've verified that the problem is due to rev. 1.39 of
> > /usr/src/sys/ufs/ffs/fs.h. Peter Wemm pointed out that the problem is not the
> > commit, but gcc's bad handling of 64-bit operations. Nonetheless, this commit
> > does break world for a lot of people... is there some official solution? The
> > make.conf line only works for UFS1 - if it's set to UFS2, buildworld still
> > fails. (Am I correct in assuming a 5.0-R install defaults to UFS2?)
>
> Yes.  And 4.x upgrades, which are far more common, default to UFS.
>
> Personally, I think the changes should be #ifdef'ed the current
> version of GCC; when GCC rev's, hopefully its 64 bit operations
> handling will have improved.

This would wrong, since ufs2 depends on the changes to actually work
for file systems larger than about 1TB.

Blaming gcc's 64-bit operations seems to be wrong anyway.  gcc actually
has good handling of (32, 32) -> 64 bit operations which are the only
types involved here in at least fs.h, boot2 still fits for me when it
is compiled the previous version of gcc.  It has 19 bytes to spare:

%%%
   text	   data	    bss	    dec	    hex	filename
    512	      0	      0	    512	    200	obj-UFS1_AND_UFS2/boot1.o
    512	      0	      0	    512	    200	obj-UFS1_AND_UFS2/boot1.out
   5228	     25	   2120	   7373	   1ccd	obj-UFS1_AND_UFS2/boot2.o
   5439	     25	   2196	   7660	   1dec	obj-UFS1_AND_UFS2/boot2.out
     91	      0	      0	     91	     5b	obj-UFS1_AND_UFS2/sio.o
    512	      0	      0	    512	    200	obj-UFS1_ONLY/boot1.o
    512	      0	      0	    512	    200	obj-UFS1_ONLY/boot1.out
   4999	     25	   1864	   6888	   1ae8	obj-UFS1_ONLY/boot2.o
   5211	     25	   1940	   7176	   1c08	obj-UFS1_ONLY/boot2.out
     91	      0	      0	     91	     5b	obj-UFS1_ONLY/sio.o
    512	      0	      0	    512	    200	obj-UFS2_ONLY/boot1.o
    512	      0	      0	    512	    200	obj-UFS2_ONLY/boot1.out
   5046	     25	   1992	   7063	   1b97	obj-UFS2_ONLY/boot2.o
   5255	     25	   2068	   7348	   1cb4	obj-UFS2_ONLY/boot2.out
     91	      0	      0	     91	     5b	obj-UFS2_ONLY/sio.o
%%%

The fixes in fs.h are:

% Index: fs.h
% ===================================================================
% RCS file: /home/ncvs/src/sys/ufs/ffs/fs.h,v
% retrieving revision 1.38
% retrieving revision 1.39
% diff -u -1 -r1.38 -r1.39
% --- fs.h	10 Jan 2003 06:59:34 -0000	1.38
% +++ fs.h	22 Feb 2003 00:19:26 -0000	1.39
% @@ -33,3 +33,3 @@
%   *	@(#)fs.h	8.13 (Berkeley) 3/21/95
% - * $FreeBSD: src/sys/ufs/ffs/fs.h,v 1.38 2003/01/10 06:59:34 marcel Exp $
% + * $FreeBSD: src/sys/ufs/ffs/fs.h,v 1.39 2003/02/22 00:19:26 mckusick Exp $
%   */
% @@ -498,3 +498,3 @@
%   */
% -#define	cgbase(fs, c)	((ufs2_daddr_t)((fs)->fs_fpg * (c)))
% +#define	cgbase(fs, c)	(((ufs2_daddr_t)(fs)->fs_fpg) * (c))
%  #define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */

This changes a (32, 32) -> 32 bit (possibly overflowing) operation to a
(32, 32) -> 64 bit (never overflowing) operation.  The 1386 hardware
already does the wider operation so all gcc has to do is not discard the
high 32-bits, which it does reasonably well.

% @@ -543,5 +543,5 @@
%  #define lfragtosize(fs, frag)	/* calculates ((off_t)frag * fs->fs_fsize) */ \
% -	((off_t)(frag) << (fs)->fs_fshift)
% +	(((off_t)(frag)) << (fs)->fs_fshift)
%  #define lblktosize(fs, blk)	/* calculates ((off_t)blk * fs->fs_bsize) */ \
% -	((off_t)(blk) << (fs)->fs_bshift)
% +	(((off_t)(blk)) << (fs)->fs_bshift)
%  /* Use this only when `blk' is known to be small, e.g., < NDADDR. */

These changes have no effect except to add style bugs (see below).
The casts were inserted in the correct place in rev.1.7 to fix similar
overflow bugs for _files_ larger than 2GB.  Now we're fixing overflow
for block numbers larger than 2G.

% @@ -573,3 +573,3 @@
%  	(fs)->fs_cstotal.cs_nffree - \
% -	((off_t)((fs)->fs_dsize) * (percentreserved) / 100))
% +	(((off_t)((fs)->fs_dsize)) * (percentreserved) / 100))
%

This change has no effect for many reasons:
- it just adds style bugs (see below).
- the macro is not used in the boot blocks.
- fs_dsize already  happens to have the same type as off_t (both have type
  int64_t).  off_t is a bogus type to cast to anyway.  We start with a
  block count and multiply by a percentage.  This is unrelated to file
  sizes, but overflow happens to be prevented by the maxiumum percentage
  (100) being smaller than the minimum block size (4096).

All of these changes add style bugs IMO.  Except for the change to
cgbase(), they add redundant parentheses around "(cast)(foo)->bar",
but properly parenthesized macros are hard enough to read with only
non-redundant parentheses.  The change to cgbase() moves parentheses
so that they are redundant instead of just wrong.

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?20030224144742.L5105-100000>