From owner-freebsd-bugs Wed May 29 15:11:17 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id AC29A37B41E for ; Wed, 29 May 2002 15:10:01 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g4TMA1e10208; Wed, 29 May 2002 15:10:01 -0700 (PDT) (envelope-from gnats) Received: from naxos.pdb.sbs.de (naxos.pdb.sbs.de [192.109.3.5]) by hub.freebsd.org (Postfix) with ESMTP id 5F85537B407 for ; 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 ; 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 ; 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 ; 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 Reply-To: Martin Kraemer To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: i386/38703: disklabel initializes fragment size to be == blksize Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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