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>
