User-level changes corrseponding to my latest kernel changes.

newfs_lfs gives lfs_minfreeseg a value of 1/8 of the total segments on
the disk, based on rough empirical data, but this should be refined in
the future.
This commit is contained in:
perseant 2000-07-03 01:49:11 +00:00
parent 01bd2a3496
commit 9a38f49c57
3 changed files with 44 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cleanerd.c,v 1.19 2000/06/21 01:58:52 perseant Exp $ */
/* $NetBSD: cleanerd.c,v 1.20 2000/07/03 01:49:16 perseant Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,7 +40,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
#if 0
static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95";
#else
__RCSID("$NetBSD: cleanerd.c,v 1.19 2000/06/21 01:58:52 perseant Exp $");
__RCSID("$NetBSD: cleanerd.c,v 1.20 2000/07/03 01:49:16 perseant Exp $");
#endif
#endif /* not lint */
@ -312,17 +312,19 @@ clean_loop(fsp, nsegs, options)
int nsegs;
long options;
{
struct lfs *lfsp;
double loadavg[MAXLOADS];
time_t now;
u_long max_free_segs;
u_long db_per_seg;
lfsp = &fsp->fi_lfs;
/*
* Compute the maximum possible number of free segments, given the
* number of free blocks.
*/
db_per_seg = fragstodb(&fsp->fi_lfs, fsp->fi_lfs.lfs_ssize);
max_free_segs = (fsp->fi_statfsp->f_bfree / fsp->fi_lfs.lfs_ssize) >> fsp->fi_lfs.lfs_fbshift;
db_per_seg = fsbtodb(lfsp, lfsp->lfs_ssize);
max_free_segs = lfsp->lfs_bfree / db_per_seg + lfsp->lfs_minfreeseg;
/*
* We will clean if there are not enough free blocks or total clean
@ -331,23 +333,24 @@ clean_loop(fsp, nsegs, options)
now = time((time_t *)NULL);
if(debug > 1) {
syslog(LOG_DEBUG, "db_per_seg = %lu max_free_segs = %lu, bfree = %u avail = %d ",
db_per_seg, max_free_segs, fsp->fi_lfs.lfs_bfree,
fsp->fi_lfs.lfs_avail);
syslog(LOG_DEBUG, "db_per_seg = %lu bfree = %u avail = %d ",
db_per_seg, lfsp->lfs_bfree,
lfsp->lfs_avail);
syslog(LOG_DEBUG, "clean segs = %d, max_free_segs = %ld",
fsp->fi_cip->clean, max_free_segs);
syslog(LOG_DEBUG, "clean = %d", fsp->fi_cip->clean);
}
if ((fsp->fi_lfs.lfs_bfree - fsp->fi_lfs.lfs_avail > db_per_seg &&
fsp->fi_lfs.lfs_avail < db_per_seg) ||
if ((lfsp->lfs_bfree - lfsp->lfs_avail > db_per_seg &&
lfsp->lfs_avail < (long)db_per_seg) ||
(fsp->fi_cip->clean < max_free_segs &&
(fsp->fi_cip->clean <= MIN_SEGS(&fsp->fi_lfs) ||
(fsp->fi_cip->clean <= lfsp->lfs_minfreeseg ||
fsp->fi_cip->clean < max_free_segs * BUSY_LIM)))
{
if(debug)
syslog(LOG_DEBUG, "Cleaner Running at %s (%d of %lu segments available)",
ctime(&now), fsp->fi_cip->clean, max_free_segs);
syslog(LOG_DEBUG, "Cleaner Running at %s "
"(%d of %lu segments available, avail = %d)",
ctime(&now), fsp->fi_cip->clean, max_free_segs,
lfsp->lfs_avail);
clean_fs(fsp, cost_benefit, nsegs, options);
if(do_quit) {
if(debug)
@ -448,8 +451,8 @@ clean_fs(fsp, cost_func, nsegs, options)
}
/* If we relly need to clean a lot, do it now */
if(fsp->fi_cip->clean < 2*MIN_FREE_SEGS)
nsegs = MAX(nsegs,MIN_FREE_SEGS);
if(fsp->fi_cip->clean < 2 * fsp->fi_lfs.lfs_minfreeseg)
nsegs = MAX(nsegs, fsp->fi_lfs.lfs_minfreeseg);
/* But back down if we haven't got that many free to clean into */
if(fsp->fi_cip->clean < nsegs)
nsegs = fsp->fi_cip->clean;

View File

@ -1,4 +1,4 @@
/* $NetBSD: config.h,v 1.2 2000/06/27 21:06:24 perseant Exp $ */
/* $NetBSD: config.h,v 1.3 2000/07/03 01:49:11 perseant Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -52,16 +52,19 @@
#define DFL_FRAGSIZE 1024
#define DFL_BLKSIZE 8192
/*
* 1/DFL_MIN_FREE_SEGS gives the fraction of segments to be reserved for
* the cleaner. Experimental data show this number should be around
* 5-10.
*/
#define DFL_MIN_FREE_SEGS 8
/*
* MINFREE gives the minimum acceptable percentage of file system
* blocks which may be free. If the freelist drops below this level
* only the superuser may continue to allocate blocks. This may
* be set to 0 if no reserve of free blocks is deemed necessary,
* however throughput drops by (how many?) percent if the file system
* is run at between 80% and 100% full; thus the default value of
* fs_minfree is 20%.
* only the superuser may continue to allocate blocks.
*/
#define MINFREE 20
#define MINFREE 10
/*
* The following constants set the default block and segment size for a log

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs.c,v 1.13 2000/06/27 21:06:25 perseant Exp $ */
/* $NetBSD: lfs.c,v 1.14 2000/07/03 01:49:12 perseant Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)lfs.c 8.5 (Berkeley) 5/24/95";
#else
__RCSID("$NetBSD: lfs.c,v 1.13 2000/06/27 21:06:25 perseant Exp $");
__RCSID("$NetBSD: lfs.c,v 1.14 2000/07/03 01:49:12 perseant Exp $");
#endif
#endif /* not lint */
@ -149,6 +149,7 @@ static struct lfs lfs_default = {
/* dlfs_fsmnt */ { 0 },
/* dlfs_clean */ 0,
/* dlfs_dmeta */ 0,
/* dlfs_minfreeseg */ 0,
/* dlfs_pad */ { 0 },
/* dlfs_cksum */ 0
@ -313,8 +314,11 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size)
lfsp->lfs_nseg = lfsp->lfs_dsize / lfsp->lfs_ssize;
lfsp->lfs_nclean = lfsp->lfs_nseg - 1;
lfsp->lfs_maxfilesize = maxtable[lfsp->lfs_bshift] << lfsp->lfs_bshift;
lfsp->lfs_minfreeseg = lfsp->lfs_nseg / DFL_MIN_FREE_SEGS;
if (lfsp->lfs_minfreeseg < MIN_FREE_SEGS)
lfsp->lfs_minfreeseg = MIN_FREE_SEGS;
if(lfsp->lfs_nseg < MIN_FREE_SEGS + 1
if(lfsp->lfs_nseg < lfsp->lfs_minfreeseg + 1
|| lfsp->lfs_nseg < LFS_MIN_SBINTERVAL + 1)
{
if(seg_size == 0 && ssize > (bsize<<1)) {
@ -333,12 +337,17 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size)
/*
* The number of free blocks is set from the number of segments
* times the segment size - MIN_FREE_SEGS (that we never write
* times the segment size - lfs_minfreesegs (that we never write
* because we need to make sure the cleaner can run). Then
* we'll subtract off the room for the superblocks ifile entries
* and segment usage table.
* and segment usage table, and half a block per segment that can't
* be written due to fragmentation.
*/
lfsp->lfs_dsize = fsbtodb(lfsp, (lfsp->lfs_nseg - MIN_FREE_SEGS) * lfsp->lfs_ssize);
lfsp->lfs_dsize = fsbtodb(lfsp, (lfsp->lfs_nseg -
lfsp->lfs_minfreeseg) *
lfsp->lfs_ssize);
lfsp->lfs_dsize -= fsbtodb(lfsp, lfsp->lfs_nseg / 2);
lfsp->lfs_bfree = lfsp->lfs_dsize;
lfsp->lfs_segtabsz = SEGTABSIZE_SU(lfsp);
lfsp->lfs_cleansz = CLEANSIZE_SU(lfsp);
@ -406,8 +415,7 @@ make_lfs(fd, lp, partp, minfree, block_size, frag_size, seg_size)
segp->su_flags = SEGUSE_SUPERBLOCK | SEGUSE_DIRTY;
lfsp->lfs_bfree -= LFS_SUMMARY_SIZE / lp->d_secsize;
lfsp->lfs_bfree -=
fsbtodb(lfsp, lfsp->lfs_cleansz + lfsp->lfs_segtabsz + 4 +
MIN_FREE_SEGS * lfsp->lfs_ssize);
fsbtodb(lfsp, lfsp->lfs_cleansz + lfsp->lfs_segtabsz + 4);
/*
* Now figure out the address of the ifile inode. The inode block