Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 May 2002 00:03:25 +0200 (CEST)
From:      Martin Kraemer <Martin.Kraemer@Fujitsu-Siemens.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   i386/38703: disklabel initializes fragment size to be == blksize
Message-ID:  <200205292203.g4TM3PrV060079@deejai2.mch.fsc.net>

next in thread | raw e-mail | index | archive | help

>Number:         38703
>Category:       i386
>Synopsis:       disklabel initializes fragment size to be == blksize
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 29 15:10:01 PDT 2002
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:

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




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