Subject: newfs: determining file system parameters
To: None <tech-kern@NetBSD.org>
From: Greg 'groggy' Lehey <grog@NetBSD.org>
List: tech-kern
Date: 10/11/2003 13:53:46
--mhOzvPhkurUs4vA9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

As a result of a somewhat hasty commit of fixes for Vinum, the
question has arisen as to how to determine file system size and type.
Currently, newfs retrieves a volume label with a DIOCGDINFO ioctl
call.  This fails if the storage device doesn't have an associated
partition table.

The current version of newfs includes an -F flag for this eventuality,
but it requires the size to be specified (correctly).  This makes it
inconvenient and subject to error.  I'd like to investigate what needs
to be done to automatically build a file system on a file or device
which doesn't have a partition table.

=46rom the man page, newfs uses the following information to build a
file system.  I'm omitting flags which don't change the way the file
system is built.

     -a maxcontig
                 This specifies the maximum number of contiguous blocks that
                 will be laid out before forcing a rotational delay (see the
                 -d option).  The default value is 8.  See tunefs(8) for mo=
re
                 details on how to set this option.

	=3D=3D> not relevant to this discussion.

     -B byte-order
                 Specify the metadata byte order of the file system to be c=
re-
                 ated.  Valid byte orders are `be' and `le'.  If no byte or=
der
                 is specified, the file system is created in host byte orde=
r.

	=3D=3D> not relevant to this discussion.

     -b block-size
                 The block size of the file system, in bytes.  It must be a
                 power of two.  The smallest allowable size is 4096 bytes.
                 The default size depends upon the size of the file system:

                       file system size  block-size
                       < 20 MB           4 KB
                       < 1024 MB         8 KB
                       >=3D 1024 MB        16 KB

	=3D=3D> Currently taken from the partition table by default.  If it's 0
	    in the partition table, newfs provides its own default.

     -e maxbpg   This indicates the maximum number of blocks any single file
                 can allocate out of a cylinder group before it is forced to
                 begin allocating blocks from another cylinder group.  The
                 default is about one quarter of the total blocks in a cyli=
n-
                 der group.  See tunefs(8) for more details on how to set t=
his
                 option.

	=3D=3D> newfs provides a default.

     -F          Create a file system image in special.  The file system si=
ze
                 needs to be specified with ``-s size''.  No attempts to use
                 or update the partition table will be made.

	=3D=3D> As discussed above

     -f frag-size
                 The fragment size of the file system in bytes.  It must be=
 a
                 power of two ranging in value between block-size/8 and
                 block-size.  The optimal block-size:frag-size ratio is 8:1.
                 Other ratios are possible, but are not recommended, and may
                 produce unpredictable results.  The default size depends u=
pon
                 the size of the file system:

                       file system size  frag-size
                       < 20 MB           0.5 KB
                       < 1024 MB         1 KB
                       >=3D 1024 MB        2 KB

	=3D=3D> Currently taken from the partition table by default.  If it's 0
	    in the partition table, newfs provides its own default.

     -g avgfilesize
                 The expected average file size for the file system.

	=3D=3D> newfs provides a default.

     -h avgfpdir
                 The expected average number of files per directory on the
                 file system.

	=3D=3D> newfs provides a default.

     -I          Do not require that the file system type listed in the disk
                 label is `4.2BSD' or `Apple UFS'.

	=3D=3D> not relevant here

     -i bytes-per-inode
                 This specifies the density of inodes in the file system.  =
If
                 fewer inodes are desired, a larger number should be used; =
to
                 create more inodes a smaller number should be given.  The
                 default is to create an inode for every (4 * frag-size) by=
tes
                 of data space:

                       file system size  bytes-per-inode
                       < 20 MB           2 KB
                       < 1024 MB         4 KB
                       >=3D 1024 MB        8 KB

	=3D=3D> newfs provides a default.

     -m free-space
                 The percentage of space reserved from normal users; the mi=
ni-
                 mum free space threshold.  The default value used is 5%.  =
See
                 tunefs(8) for more details on how to set this option.

	=3D=3D> newfs provides a default.

     -n inodes   This specifies the number of inodes for the filesystem.  If
                 both -i and -n are specified then -n takes precedence.

	=3D=3D> newfs provides a default.

     -O filesystem-format
                 Select the filesystem-format

	=3D=3D> newfs defaults to UFS1.

     -o optimization
                 Optimization preference; either ``space'' or ``time''...

	=3D=3D> newfs calculates a default.

     -s size     The size of the file system in sectors.  An `s' suffix will
                 be interpreted as the number of sectors (the default).  All
                 other suffixes are interpreted as per other numeric argu-
                 ments, except that the number is converted into sectors by
                 dividing by the sector size (as specified by -S secsize)
                 after suffix interpretation.

	=3D=3D> defaults to value in the partition table.

Of all these parameters, only the following require information from
the partition table: block size, frag size, file system size.  Of
these, only the file system size doesn't have a default.

In addition to these parameters, newfs interprets the last letter of
the device name as a partition identifier.  This can fail badly if a
device has a name like 'baz'.

I'd suggest that the following method would solve the "problem":

- implement an ioctl DIOCGMEDIASIZE to return the size of a special
  device. =20

- newfs should not require a partition table, but should attempt to
  find one first.  If it doesn't find one, it uses defaults for block
  and frag size, effectively unchanged from the current situation
  where a partition doesn't contain any block or frag size
  information.

- In such a case, newfs should obtain the sector size from the
  DIOCGMEDIASIZE ioctl.

- If for any reason the DIOCGMEDIASIZE fails, the user must supply the
  size manually.

- newfs should not attach any special importance to the name of a
  device without a partition table.

I'm sure I've forgotten something here, but I think this looks
reasonably clean.  It maintains compatibility with the existing
partitioning scheme and allows gradual implementation of the
DIOCGMEDIASIZE ioctl.

Thoughts?

Greg
--
See complete headers for address and phone numbers.

--mhOzvPhkurUs4vA9
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.0 (FreeBSD)

iD8DBQE/h4XSIubykFB6QiMRAu7eAKCInSMtzwUFHxH1je1xQry2/K1I6gCdFub6
cjWLse2eRyYtznvs3MjUbcg=
=UiGT
-----END PGP SIGNATURE-----

--mhOzvPhkurUs4vA9--