Date: Tue, 18 Sep 2001 18:06:45 -0700 (PDT) From: Matt Dillon <dillon@earth.backplane.com> To: freebsd-stable@freebsd.org Cc: Mike Silbersack <silby@silby.com>, Ian Dowse <iedowse@maths.tcd.ie>, Kirk McKusick <mckusick@mckusick.com>, Grigoriy Orlov <gluk@ptci.ru> Subject: dirpref MFC to -stable: patch set to test Message-ID: <200109190106.f8J16jv50999@earth.backplane.com>
next in thread | raw e-mail | index | archive | help
Ok folks, here is a patchset that MFC's the dirpref code from -current to -stable. I have done some very simple testing, but I need a couple more eyes on the code. I want to make sure that I have MFC'd all necessary rcs pieces. This is what I have MFC'd: 1.36 src/sbin/newfs/mkfs.c 1.35 src/sbin/newfs/newfs.c 1.16 src/sbin/tunefs/tunefs.c 1.75 src/sys/ufs/ffs/ffs_alloc.c 1.144, 1.148, 1.159 src/sys/ufs/ffs/ffs_vfsops.c 1.20 src/sys/ufs/ffs/fs.h 1.37 src/sbin/newfs/newfs.8 1.15 src/sbin/tunefs/tunefs.8 1.22, 1.25 src/sbin/fsck_ffs/setup.c (note: fsck/setup.c in -stable) I have also incorporated the snapshot changes to the superblock (fs.h) and some of the initialization code for fsck (setup.c) to try to make the -stable fsck compatible with a -current filesystem. I intend to commit this patchset to -stable on Friday if no issues come up. testers testers... -Matt Index: sbin/fsck/setup.c =================================================================== RCS file: /home/ncvs/src/sbin/fsck/Attic/setup.c,v retrieving revision 1.17.2.2 diff -u -r1.17.2.2 setup.c --- sbin/fsck/setup.c 2001/02/06 20:39:09 1.17.2.2 +++ sbin/fsck/setup.c 2001/09/19 00:29:36 @@ -380,6 +380,11 @@ memmove(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp); altsblock.fs_csp = sblock.fs_csp; altsblock.fs_maxcluster = sblock.fs_maxcluster; + altsblock.fs_contigdirs = sblock.fs_contigdirs; + altsblock.fs_avgfilesize = sblock.fs_avgfilesize; + altsblock.fs_avgfpdir = sblock.fs_avgfpdir; + altsblock.fs_pendingblocks = sblock.fs_pendingblocks; + altsblock.fs_pendinginodes = sblock.fs_pendinginodes; memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt); memmove(altsblock.fs_sparecon, sblock.fs_sparecon, sizeof sblock.fs_sparecon); Index: sbin/newfs/mkfs.c =================================================================== RCS file: /home/ncvs/src/sbin/newfs/mkfs.c,v retrieving revision 1.29.2.5 diff -u -r1.29.2.5 mkfs.c --- sbin/newfs/mkfs.c 2001/08/01 08:41:02 1.29.2.5 +++ sbin/newfs/mkfs.c 2001/09/19 00:07:12 @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95"; #endif static const char rcsid[] = - "$FreeBSD: src/sbin/newfs/mkfs.c,v 1.29.2.5 2001/08/01 08:41:02 obrien Exp $"; + "$FreeBSD: src/sbin/newfs/mkfs.c,v 1.36 2001/04/10 08:38:52 mckusick Exp $"; #endif /* not lint */ #include <err.h> @@ -119,6 +119,8 @@ extern int nrpos; /* # of distinguished rotational positions */ extern int bbsize; /* boot block size */ extern int sbsize; /* superblock size */ +extern int avgfilesize; /* expected average file size */ +extern int avgfilesperdir; /* expected number of files per directory */ extern u_long memleft; /* virtual memory available */ extern caddr_t membase; /* start address of memory based filesystem */ extern char * filename; @@ -273,6 +275,17 @@ printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(14); if (sblock.fs_nsect <= 0) printf("preposterous nsect %d\n", sblock.fs_nsect), exit(15); + /* + * collect and verify the filesystem density info + */ + sblock.fs_avgfilesize = avgfilesize; + sblock.fs_avgfpdir = avgfilesperdir; + if (sblock.fs_avgfilesize <= 0) + printf("illegal expected average file size %d\n", + sblock.fs_avgfilesize), exit(14); + if (sblock.fs_avgfpdir <= 0) + printf("illegal expected number of files per directory %d\n", + sblock.fs_avgfpdir), exit(15); /* * collect and verify the block and fragment sizes */ Index: sbin/newfs/newfs.8 =================================================================== RCS file: /home/ncvs/src/sbin/newfs/newfs.8,v retrieving revision 1.26.2.7 diff -u -r1.26.2.7 newfs.8 --- sbin/newfs/newfs.8 2001/07/22 11:32:31 1.26.2.7 +++ sbin/newfs/newfs.8 2001/09/19 00:27:33 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 -.\" $FreeBSD: src/sbin/newfs/newfs.8,v 1.26.2.7 2001/07/22 11:32:31 dd Exp $ +.\" $FreeBSD: src/sbin/newfs/newfs.8,v 1.37 2001/04/10 10:36:43 nik Exp $ .\" .Dd December 19, 2000 .Dt NEWFS 8 @@ -50,6 +50,8 @@ .Op Fl d Ar rotdelay .Op Fl e Ar maxbpg .Op Fl f Ar frag-size +.Op Fl g Ar avgfilesize +.Op Fl h Ar avfpdir .Op Fl i Ar bytes .Op Fl k Ar skew .Op Fl l Ar interleave @@ -196,6 +198,10 @@ and .Ar blocksize . The default is 1024 bytes. +.It Fl g Ar avgfilesize +The expected average file size for the file system. +.It Fl h Ar avgfpdir +The expected average number of files per directory on the file system. .It Fl i Ar number of bytes per inode Specify the density of inodes in the file system. The default is to create an inode for every Index: sbin/newfs/newfs.c =================================================================== RCS file: /home/ncvs/src/sbin/newfs/newfs.c,v retrieving revision 1.30.2.4 diff -u -r1.30.2.4 newfs.c --- sbin/newfs/newfs.c 2001/05/28 02:34:31 1.30.2.4 +++ sbin/newfs/newfs.c 2001/09/19 00:07:36 @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$FreeBSD: src/sbin/newfs/newfs.c,v 1.30.2.4 2001/05/28 02:34:31 obrien Exp $"; + "$FreeBSD: src/sbin/newfs/newfs.c,v 1.35 2001/04/10 08:38:52 mckusick Exp $"; #endif /* not lint */ /* @@ -162,9 +162,7 @@ * The number of sectors are used to determine the size of a cyl-group. * Kirk suggested one or two meg per "cylinder" so we say two. */ - #define NTRACKS 1 /* number of heads */ - #define NSECTORS 4096 /* number of sectors */ int mfs; /* run as the memory based filesystem */ @@ -198,6 +196,8 @@ int rotdelay = ROTDELAY; /* rotational delay between blocks */ int maxbpg; /* maximum blocks per file in a cyl group */ int nrpos = NRPOS; /* # of distinguished rotational positions */ +int avgfilesize = AVFILESIZ;/* expected average file size */ +int avgfilesperdir = AFPDIR;/* expected number of files per directory */ int bbsize = BBSIZE; /* boot block size */ int sbsize = SBSIZE; /* superblock size */ int mntflags = MNT_ASYNC; /* flags to be passed to mount */ @@ -249,8 +249,8 @@ } opstring = mfs ? - "NF:T:Ua:b:c:d:e:f:i:m:o:s:" : - "NOS:T:Ua:b:c:d:e:f:i:k:l:m:n:o:p:r:s:t:u:vx:"; + "NF:T:Ua:b:c:d:e:f:g:h:i:m:o:s:" : + "NOS:T:Ua:b:c:d:e:f:g:h:i:k:l:m:n:o:p:r:s:t:u:vx:"; while ((ch = getopt(argc, argv, opstring)) != -1) switch (ch) { case 'N': @@ -301,6 +301,14 @@ if ((fsize = atoi(optarg)) <= 0) fatal("%s: bad fragment size", optarg); break; + case 'g': + if ((avgfilesize = atoi(optarg)) <= 0) + fatal("%s: bad average file size", optarg); + break; + case 'h': + if ((avgfilesperdir = atoi(optarg)) <= 0) + fatal("%s: bad average files per dir", optarg); + break; case 'i': if ((density = atoi(optarg)) <= 0) fatal("%s: bad bytes per inode", optarg); @@ -761,6 +769,8 @@ fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); fprintf(stderr, "\t-f frag size\n"); + fprintf(stderr, "\t-g average file size\n"); + fprintf(stderr, "\t-h average files per directory\n"); fprintf(stderr, "\t-i number of bytes per inode\n"); fprintf(stderr, "\t-k sector 0 skew, per track\n"); fprintf(stderr, "\t-l hardware sector interleave\n"); Index: sbin/tunefs/tunefs.8 =================================================================== RCS file: /home/ncvs/src/sbin/tunefs/tunefs.8,v retrieving revision 1.11.2.1 diff -u -r1.11.2.1 tunefs.8 --- sbin/tunefs/tunefs.8 2000/12/08 14:04:21 1.11.2.1 +++ sbin/tunefs/tunefs.8 2001/09/19 00:27:17 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)tunefs.8 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/sbin/tunefs/tunefs.8,v 1.11.2.1 2000/12/08 14:04:21 ru Exp $ +.\" $FreeBSD: src/sbin/tunefs/tunefs.8,v 1.15 2001/04/10 10:36:44 nik Exp $ .\" .Dd December 11, 1993 .Dt TUNEFS 8 @@ -44,11 +44,13 @@ .Op Fl a Ar maxcontig .Op Fl d Ar rotdelay .Op Fl e Ar maxbpg +.Op Fl f Ar avgfilesize .Op Fl m Ar minfree .Bk -words .Op Fl n Ar enable | disable .Op Fl o Ar optimize_preference .Op Fl p +.Op Fl s Ar avgfpdir .Ek .Op Ar special | Ar filesystem .Sh DESCRIPTION @@ -92,6 +94,8 @@ in a cylinder group before seeking elsewhere. For file systems with exclusively large files, this parameter should be set higher. +.It Fl f Ar avgfilezsize +Specify the expected average file size. .It Fl m Ar minfree Specify the percentage of space held back from normal users; the minimum free space threshold. @@ -122,6 +126,8 @@ obtained in the .Xr dumpfs 8 manual page. +.It Fl s Ar avgfpdir +Specify the expected number of files per directory. .El .Sh ERRORS If Index: sbin/tunefs/tunefs.c =================================================================== RCS file: /home/ncvs/src/sbin/tunefs/tunefs.c,v retrieving revision 1.11.2.3 diff -u -r1.11.2.3 tunefs.c --- sbin/tunefs/tunefs.c 2001/08/01 23:13:18 1.11.2.3 +++ sbin/tunefs/tunefs.c 2001/09/19 00:50:46 @@ -180,6 +180,24 @@ sblock.fs_maxbpg = i; continue; + case 'f': + name = "average file size"; + if (argc < 1) + errx(10, "-a: missing %s", name); + argc--, argv++; + i = atoi(*argv); + if (i < 1) + errx(10, "%s must be >= 1 (was %s)", name, *argv); + if (sblock.fs_avgfilesize == i) { + warnx("%s remains unchanged as %d", + name, i); + } else { + warnx("%s changes from %d to %d", + name, sblock.fs_avgfilesize, i); + sblock.fs_avgfilesize = i; + } + break; + case 'm': name = "minimum percentage of free space"; if (argc < 1) @@ -247,6 +265,24 @@ warnx(OPTWARN, "space", "<", MINFREE); continue; + case 's': + name = "expected number of files per directory"; + if (argc < 1) + errx(10, "-a: missing %s", name); + argc--, argv++; + i = atoi(*argv); + if (i < 1) + errx(10, "%s must be >= 1 (was %s)", name, *argv); + if (sblock.fs_avgfpdir == i) { + warnx("%s remains unchanged as %d", + name, i); + } else { + warnx("%s changes from %d to %d", + name, sblock.fs_avgfpdir, i); + sblock.fs_avgfpdir = i; + } + break; + default: usage(); } @@ -268,9 +304,9 @@ usage() { fprintf(stderr, "%s\n%s\n%s\n", -"usage: tunefs [-A] [-a maxcontig] [-d rotdelay] [-e maxbpg] [-m minfree]", -" [-p] [-n enable | disable] [-o optimize_preference]", -" [special | filesystem]"); +"usage: tunefs [-A] [-a maxcontig] [-d rotdelay] [-e maxbpg] [-f avgfilesize]", +" [-m minfree] [-p] [-n enable | disable] [-o space | time]", +" [-s filesperdir] [special | filesystem]"); exit(2); } @@ -327,6 +363,10 @@ sblock.fs_rotdelay); warnx("maximum blocks per file in a cylinder group: (-e) %d", sblock.fs_maxbpg); + warnx("average file size: (-f) %d", + sblock.fs_avgfilesize); + warnx("average number of files in a directory: (-s) %d", + sblock.fs_avgfpdir); warnx("minimum percentage of free space: (-m) %d%%", sblock.fs_minfree); warnx("optimization preference: (-o) %s", Index: sys/ufs/ffs/ffs_alloc.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.64.2.1 diff -u -r1.64.2.1 ffs_alloc.c --- sys/ufs/ffs/ffs_alloc.c 2000/03/16 08:15:53 1.64.2.1 +++ sys/ufs/ffs/ffs_alloc.c 2001/09/19 00:33:51 @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_alloc.c 8.18 (Berkeley) 5/26/95 - * $FreeBSD: src/sys/ufs/ffs/ffs_alloc.c,v 1.64.2.1 2000/03/16 08:15:53 ps Exp $ + * $FreeBSD: src/sys/ufs/ffs/ffs_alloc.c,v 1.75 2001/04/10 08:38:59 mckusick Exp $ */ #include "opt_quota.h" @@ -68,7 +68,7 @@ int)); static ufs_daddr_t ffs_clusteralloc __P((struct inode *, int, ufs_daddr_t, int)); -static ino_t ffs_dirpref __P((struct fs *)); +static ino_t ffs_dirpref __P((struct inode *)); static ufs_daddr_t ffs_fragextend __P((struct inode *, int, long, int, int)); static void ffs_fserr __P((struct fs *, u_int, char *)); static u_long ffs_hashalloc @@ -587,12 +587,23 @@ goto noinodes; if ((mode & IFMT) == IFDIR) - ipref = ffs_dirpref(fs); + ipref = ffs_dirpref(pip); else ipref = pip->i_number; if (ipref >= fs->fs_ncg * fs->fs_ipg) ipref = 0; cg = ino_to_cg(fs, ipref); + /* + * Track number of dirs created one after another + * in a same cg without intervening by files. + */ + if ((mode & IFMT) == IFDIR) { + if (fs->fs_contigdirs[cg] < 255) + fs->fs_contigdirs[cg]++; + } else { + if (fs->fs_contigdirs[cg] > 0) + fs->fs_contigdirs[cg]--; + } ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, (allocfcn_t *)ffs_nodealloccg); if (ino == 0) @@ -627,28 +638,112 @@ } /* - * Find a cylinder to place a directory. + * Find a cylinder group to place a directory. + * + * The policy implemented by this algorithm is to allocate a + * directory inode in the same cylinder group as its parent + * directory, but also to reserve space for its files inodes + * and data. Restrict the number of directories which may be + * allocated one after another in the same cylinder group + * without intervening allocation of files. * - * The policy implemented by this algorithm is to select from - * among those cylinder groups with above the average number of - * free inodes, the one with the smallest number of directories. + * If we allocate a first level directory then force allocation + * in another cylinder group. */ static ino_t -ffs_dirpref(fs) - register struct fs *fs; +ffs_dirpref(pip) + struct inode *pip; { - int cg, minndir, mincg, avgifree; + register struct fs *fs; + int cg, prefcg, dirsize, cgsize; + int avgifree, avgbfree, avgndir, curdirsize; + int minifree, minbfree, maxndir; + int mincg, minndir; + int maxcontigdirs; + fs = pip->i_fs; + avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg; - minndir = fs->fs_ipg; - mincg = 0; - for (cg = 0; cg < fs->fs_ncg; cg++) - if (fs->fs_cs(fs, cg).cs_ndir < minndir && - fs->fs_cs(fs, cg).cs_nifree >= avgifree) { - mincg = cg; - minndir = fs->fs_cs(fs, cg).cs_ndir; + avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; + avgndir = fs->fs_cstotal.cs_ndir / fs->fs_ncg; + + /* + * Force allocation in another cg if creating a first level dir. + */ + if (ITOV(pip)->v_flag & VROOT) { + prefcg = arc4random() % fs->fs_ncg; + mincg = prefcg; + minndir = fs->fs_ipg; + for (cg = prefcg; cg < fs->fs_ncg; cg++) + if (fs->fs_cs(fs, cg).cs_ndir < minndir && + fs->fs_cs(fs, cg).cs_nifree >= avgifree && + fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + mincg = cg; + minndir = fs->fs_cs(fs, cg).cs_ndir; + } + for (cg = 0; cg < prefcg; cg++) + if (fs->fs_cs(fs, cg).cs_ndir < minndir && + fs->fs_cs(fs, cg).cs_nifree >= avgifree && + fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + mincg = cg; + minndir = fs->fs_cs(fs, cg).cs_ndir; + } + return ((ino_t)(fs->fs_ipg * mincg)); + } + + /* + * Count various limits which used for + * optimal allocation of a directory inode. + */ + maxndir = min(avgndir + fs->fs_ipg / 16, fs->fs_ipg); + minifree = avgifree - fs->fs_ipg / 4; + if (minifree < 0) + minifree = 0; + minbfree = avgbfree - fs->fs_fpg / fs->fs_frag / 4; + if (minbfree < 0) + minbfree = 0; + cgsize = fs->fs_fsize * fs->fs_fpg; + dirsize = fs->fs_avgfilesize * fs->fs_avgfpdir; + curdirsize = avgndir ? (cgsize - avgbfree * fs->fs_bsize) / avgndir : 0; + if (dirsize < curdirsize) + dirsize = curdirsize; + maxcontigdirs = min(cgsize / dirsize, 255); + if (fs->fs_avgfpdir > 0) + maxcontigdirs = min(maxcontigdirs, + fs->fs_ipg / fs->fs_avgfpdir); + if (maxcontigdirs == 0) + maxcontigdirs = 1; + + /* + * Limit number of dirs in one cg and reserve space for + * regular files, but only if we have no deficit in + * inodes or space. + */ + prefcg = ino_to_cg(fs, pip->i_number); + for (cg = prefcg; cg < fs->fs_ncg; cg++) + if (fs->fs_cs(fs, cg).cs_ndir < maxndir && + fs->fs_cs(fs, cg).cs_nifree >= minifree && + fs->fs_cs(fs, cg).cs_nbfree >= minbfree) { + if (fs->fs_contigdirs[cg] < maxcontigdirs) + return ((ino_t)(fs->fs_ipg * cg)); } - return ((ino_t)(fs->fs_ipg * mincg)); + for (cg = 0; cg < prefcg; cg++) + if (fs->fs_cs(fs, cg).cs_ndir < maxndir && + fs->fs_cs(fs, cg).cs_nifree >= minifree && + fs->fs_cs(fs, cg).cs_nbfree >= minbfree) { + if (fs->fs_contigdirs[cg] < maxcontigdirs) + return ((ino_t)(fs->fs_ipg * cg)); + } + /* + * This is a backstop when we have deficit in space. + */ + for (cg = prefcg; cg < fs->fs_ncg; cg++) + if (fs->fs_cs(fs, cg).cs_nifree >= avgifree) + return ((ino_t)(fs->fs_ipg * cg)); + for (cg = 0; cg < prefcg; cg++) + if (fs->fs_cs(fs, cg).cs_nifree >= avgifree) + break; + return ((ino_t)(fs->fs_ipg * cg)); } /* Index: sys/ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.117.2.3 diff -u -r1.117.2.3 ffs_vfsops.c --- sys/ufs/ffs/ffs_vfsops.c 2001/07/26 20:37:31 1.117.2.3 +++ sys/ufs/ffs/ffs_vfsops.c 2001/09/19 00:35:03 @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 - * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.3 2001/07/26 20:37:31 iedowse Exp $ + * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.159 2001/09/09 23:48:28 iedowse Exp $ */ #include "opt_quota.h" @@ -470,12 +470,18 @@ */ newfs->fs_csp = fs->fs_csp; newfs->fs_maxcluster = fs->fs_maxcluster; + newfs->fs_contigdirs = fs->fs_contigdirs; bcopy(newfs, fs, (u_int)fs->fs_sbsize); if (fs->fs_sbsize < SBSIZE) bp->b_flags |= B_INVAL; brelse(bp); mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; ffs_oldfscompat(fs); + /* An old fsck may have zeroed these fields, so recheck them. */ + if (fs->fs_avgfilesize <= 0) /* XXX */ + fs->fs_avgfilesize = AVFILESIZ; /* XXX */ + if (fs->fs_avgfpdir <= 0) /* XXX */ + fs->fs_avgfpdir = AFPDIR; /* XXX */ /* * Step 3: re-read summary information from disk. @@ -674,6 +680,7 @@ blks = howmany(size, fs->fs_fsize); if (fs->fs_contigsumsize > 0) size += fs->fs_ncg * sizeof(int32_t); + size += fs->fs_ncg * sizeof(u_int8_t); space = malloc((u_long)size, M_UFSMNT, M_WAITOK); fs->fs_csp = space; for (i = 0; i < blks; i += fs->fs_frag) { @@ -694,7 +701,16 @@ fs->fs_maxcluster = lp = space; for (i = 0; i < fs->fs_ncg; i++) *lp++ = fs->fs_contigsumsize; + space = lp; } + size = fs->fs_ncg * sizeof(u_int8_t); + fs->fs_contigdirs = (u_int8_t *)space; + bzero(fs->fs_contigdirs, size); + /* Compatibility for old filesystems XXX */ + if (fs->fs_avgfilesize <= 0) /* XXX */ + fs->fs_avgfilesize = AVFILESIZ; /* XXX */ + if (fs->fs_avgfpdir <= 0) /* XXX */ + fs->fs_avgfpdir = AFPDIR; /* XXX */ mp->mnt_data = (qaddr_t)ump; mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0]; mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; Index: sys/ufs/ffs/fs.h =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/fs.h,v retrieving revision 1.14.2.2 diff -u -r1.14.2.2 fs.h --- sys/ufs/ffs/fs.h 2001/01/22 18:10:28 1.14.2.2 +++ sys/ufs/ffs/fs.h 2001/09/19 00:32:13 @@ -108,15 +108,17 @@ /* * There is a 128-byte region in the superblock reserved for in-core * pointers to summary information. Originally this included an array - * of pointers to blocks of struct csum; now there are just two + * of pointers to blocks of struct csum; now there are just three * pointers and the remaining space is padded with fs_ocsp[]. * * NOCSPTRS determines the size of this padding. One pointer (fs_csp) * is taken away to point to a contiguous array of struct csum for * all cylinder groups; a second (fs_maxcluster) points to an array - * of cluster sizes that is computed as cylinder groups are inspected. + * of cluster sizes that is computed as cylinder groups are inspected, + * and the third points to an array that tracks the creation of new + * directories. */ -#define NOCSPTRS ((128 / sizeof(void *)) - 2) +#define NOCSPTRS ((128 / sizeof(void *)) - 3) /* * A summary of contiguous blocks of various sizes is maintained @@ -142,6 +144,31 @@ #define DEFAULTOPT FS_OPTTIME /* + * Grigoriy Orlov <gluk@ptci.ru> has done some extensive work to fine + * tune the layout preferences for directories within a filesystem. + * His algorithm can be tuned by adjusting the following parameters + * which tell the system the average file size and the average number + * of files per directory. These defaults are well selected for typical + * filesystems, but may need to be tuned for odd cases like filesystems + * being used for sqiud caches or news spools. + */ +#define AVFILESIZ 16384 /* expected average file size */ +#define AFPDIR 64 /* expected number of files per directory */ + +/* + * The maximum number of snapshot nodes that can be associated + * with each filesystem. This limit affects only the number of + * snapshot files that can be recorded within the superblock so + * that they can be found when the filesystem is mounted. However, + * maintaining too many will slow the filesystem performance, so + * having this limit is a good idea. + * + * VALUE NOT IMPLEMENTED IN 4.x YET, RESERVED FROM -CURRENT SO SUPERBLOCKS + * REMAIN COMPATIBLE. + */ +#define FSMAXSNAP 20 + +/* * Per cylinder group information; summarized in blocks allocated * from first cylinder group data blocks. These blocks have to be * read in from fs_csaddr (size fs_cssize) in addition to the @@ -227,11 +254,17 @@ /* these fields retain the current block allocation info */ int32_t fs_cgrotor; /* last cg searched */ void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */ + u_int8_t *fs_contigdirs; /* # of contiguously allocated dirs */ struct csum *fs_csp; /* cg summary info buffer for fs_cs */ int32_t *fs_maxcluster; /* max cluster in each cyl group */ int32_t fs_cpc; /* cyl per cycle in postbl */ int16_t fs_opostbl[16][8]; /* old rotation block list head */ - int32_t fs_sparecon[50]; /* reserved for future constants */ + int32_t fs_snapinum[FSMAXSNAP];/* RESERVED FROM 5.x */ + int32_t fs_avgfilesize; /* expected average file size */ + int32_t fs_avgfpdir; /* expected # of files per directory */ + int32_t fs_sparecon[26]; /* reserved for future constants */ + int32_t fs_pendingblocks; /* RESERVED FROM 5.x */ + int32_t fs_pendinginodes; /* RESERVED FROM 5.x */ int32_t fs_contigsumsize; /* size of cluster summary array */ int32_t fs_maxsymlinklen; /* max length of an internal symlink */ int32_t fs_inodefmt; /* format of on-disk inodes */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200109190106.f8J16jv50999>