From Martin.Kraemer@Fujitsu-Siemens.com  Wed May 29 15:03:32 2002
Return-Path: <Martin.Kraemer@Fujitsu-Siemens.com>
Received: from naxos.pdb.sbs.de (naxos.pdb.sbs.de [192.109.3.5])
	by hub.freebsd.org (Postfix) with ESMTP id 5F85537B407
	for <freebsd-gnats-submit@freebsd.org>; Wed, 29 May 2002 15:03:30 -0700 (PDT)
Received: from trolli.pdb.fsc.net (ThisAddressDoesNotExist [172.25.97.20] (may be forged))
	by naxos.pdb.sbs.de (8.11.2/8.11.2) with ESMTP id g4TM3R631870
	for <freebsd-gnats-submit@freebsd.org>; Thu, 30 May 2002 00:03:27 +0200
Received: from deejai2.mch.fsc.net (deejai2.mch.fsc.net [172.25.124.236])
	by trolli.pdb.fsc.net (8.9.3/8.9.3) with ESMTP id AAA28121
	for <freebsd-gnats-submit@freebsd.org>; Thu, 30 May 2002 00:03:26 +0200
Received: (from root@localhost)
	by deejai2.mch.fsc.net (8.12.3/8.12.2) id g4TM3S3R060088
	for freebsd-gnats-submit@freebsd.org; Thu, 30 May 2002 00:03:28 +0200 (CEST)
	(envelope-from martin@deejai2.mch.fsc.net)
Received: from deejai2.mch.fsc.net (localhost6 [IPv6:::1])
	by deejai2.mch.fsc.net (8.12.3/8.12.3) with ESMTP id g4TM3PL7060080
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 30 May 2002 00:03:25 +0200 (CEST)
	(envelope-from martin@deejai2.mch.fsc.net)
Received: (from martin@localhost)
	by deejai2.mch.fsc.net (8.12.3/8.12.3/Submit) id g4TM3PrV060079;
	Thu, 30 May 2002 00:03:25 +0200 (CEST)
Message-Id: <200205292203.g4TM3PrV060079@deejai2.mch.fsc.net>
Date: Thu, 30 May 2002 00:03:25 +0200 (CEST)
From: Martin Kraemer <Martin.Kraemer@Fujitsu-Siemens.com>
Reply-To: Martin Kraemer <Martin.Kraemer@Fujitsu-Siemens.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: disklabel initializes fragment size to be == blksize
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         38703
>Category:       i386
>Synopsis:       disklabel initializes fragment size to be == blksize
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    iedowse
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 29 15:10:01 PDT 2002
>Closed-Date:    Mon Aug 26 12:45:01 PDT 2002
>Last-Modified:  Mon Aug 26 12:45:01 PDT 2002
>Originator:     Martin Kraemer
>Release:        FreeBSD 4.6-RC i386
>Organization:
Fujitsu-Siemens Computers
>Environment:
System: FreeBSD deejai2.mch.fsc.net 4.6-RC FreeBSD 4.6-RC #3: Fri May 24 17:06:58 CEST 2002 martin@deejai2.mch.fsc.net:/usr/src/sys/compile/DEEJAI4B i386


>Description:
After getting a new disk and doing fdisk -- disklabel -- newfs,
the default fragsize in newfs shows up to be 16kB now (identical
to blksize). :-((

However, this is a bug in disklabel, not in newfs.

In disklabel.c, a new disk is initialized thusly:
disklabel.c:
    83  /* FIX!  These are too low, but are traditional */
    84  #define DEFAULT_NEWFS_BLOCK  8192U
    85  #define DEFAULT_NEWFS_FRAG   1024U
    86  #define DEFAULT_NEWFS_CPG    16U
    87
    88  #define BIG_NEWFS_BLOCK  16384U
    89  #define BIG_NEWFS_FRAG   4096U
    90  #define BIG_NEWFS_CPG    64U
...
  1281                /*
  1282                 * FIX! poor attempt at
  1283                 * adaptive
  1284                 */
  1285                /* 1 GB */
  1286                if (pp->p_size < 1*1024*1024*1024/lp->d_secsize) {
  1287  /* FIX!  These are too low, but are traditional */
  1288                  pp->p_fsize = DEFAULT_NEWFS_BLOCK;
  1289                  pp->p_frag  = (unsigned char) DEFAULT_NEWFS_FRAG;
  1290                  pp->p_cpg   = DEFAULT_NEWFS_CPG;
  1291                } else {
  1292                  pp->p_fsize = BIG_NEWFS_BLOCK;
  1293                  pp->p_frag  = (unsigned char) BIG_NEWFS_FRAG;
  1294                  pp->p_cpg   = BIG_NEWFS_CPG;
  1295                }

But p_fsize is supposed to be the fragment size (not the blocksize
as initialized here, set to 8k/16k depending on the total
disk size by default).

IMHO a logic similar to this snippet from disklabel.c:
  1265                pp->p_frag = v / pp->p_fsize;
must be used instead, like (concept only, not checked):
>                /*
>                 * FIX! poor attempt at
>                 * adaptive
>                 */
>                /* 1 GB */
>                if (pp->p_size < 1*1024*1024*1024/lp->d_secsize) {
>  /* FIX!  These are too low, but are traditional */
-->                pp->p_fsize = DEFAULT_NEWFS_FRAG; /* @@@ was: DEFAULT_NEWFS_BLOCK */
-->                pp->p_frag  = (unsigned char) (DEFAULT_NEWFS_BLOCK / DEFAULT_NEWFS_FRAG); /* was: DEFAULT_NEWFS_FRAG */
>                  pp->p_cpg   = DEFAULT_NEWFS_CPG;
>                } else {
-->                pp->p_fsize = BIG_NEWFS_FRAG;    /* @@@ was: BIG_NEWFS_BLOCK */
-->                pp->p_frag  = (unsigned char) (BIG_NEWFS_BLOCK / BIG_NEWFS_FRAG); /* was: BIG_NEWFS_FRAG */
>                  pp->p_cpg   = BIG_NEWFS_CPG;
>                }

See also the comments in:
 /usr/include/sys/disklabel.h:  u_int32_t p_fsize;  /* filesystem basic fragment size */
 /usr/include/sys/disklabel.h:  u_int8_t p_frag;    /* filesystem fragments per block */
 /usr/include/disktab.h:        short   p_fsize;    /* frag size in bytes */

And newfs copies (in absense of an explicit switch) these values into
the new fs.
newfs.c:
   528    if (fsize == 0) {
   529      fsize = pp->p_fsize;
------------^^^^^^^^^^^^^^^^^^^^ Here.
   530      if (fsize <= 0)
   531        fsize = MAX(DFL_FRAGSIZE, lp->d_secsize);
   532    }

>How-To-Repeat:
BTW: This is how I got the strange values:

a) I had used "disklabel -e" and edited the ascii copy
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:       2G        *    4.2BSD
  b:       2G        *    4.2BSD
  .... etc. -- but I left the [fsize bsize bps/cpg] empty.

b) "disklabel -e" created this output from the empty input:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:  4194304        0    4.2BSD    16384 16384   389   # (Cyl.    0 - 4161*)
  b:  4194304  4194304    4.2BSD    16384 16384   389   # (Cyl. 4161*- 8322*)
  .... etc. Soo: it was disklabel that broke the frags.

c) newfs used the values that "disklabel" had left :-(

>Fix:
The default fragsize is supposed to be 2048
(1/8 of the blksize) and manually setting this value in "disklabel -e"
or in "newfs -f 2048" reverts to the expected behavior
(no wasted space, enough inodes).
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->iedowse 
Responsible-Changed-By: iedowse 
Responsible-Changed-When: Wed May 29 16:29:57 PDT 2002 
Responsible-Changed-Why:  

I'll take a look at this. This part of the disklabel code certainly 
seems very confused... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38703 
State-Changed-From-To: open->patched 
State-Changed-By: iedowse 
State-Changed-When: Wed May 29 18:44:54 PDT 2002 
State-Changed-Why:  

An initial fix has been committed to -current. Note that this bug 
is only triggered if you leave the last 3 fields blank when editing 
the disklabel. Even one extra "0" field after the "4.2BSD" is enough 
to avoid the problem, so it has probably not been seen by many 
people. 

I will merge this into -stable after 4.6-RELEASE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38703 
State-Changed-From-To: patched->closed 
State-Changed-By: iedowse 
State-Changed-When: Mon Aug 26 12:43:13 PDT 2002 
State-Changed-Why:  
Fixed in -STABLE now too. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=38703 
>Unformatted:
