summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorperseant <perseant@NetBSD.org>2000-11-11 22:40:13 +0000
committerperseant <perseant@NetBSD.org>2000-11-11 22:40:13 +0000
commitd5e76bbac25251c4036408fac11b840249bcfebf (patch)
tree158b29f98a0bf0412a15b319a00012625711a308 /libexec
parent5975446609576407292497b6142d2f64742a01eb (diff)
Don't hold every segment that is being cleaned in memory in its entirety;
instead, if the segment doesn't have many live blocks, copy them to a more appropriately sized chunk of memory and release the original. This should prevent the cleaner from distending itself when cleaning many segments with only one or two live blocks each, as when using the "-b" option.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/lfs_cleanerd/cleanerd.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/libexec/lfs_cleanerd/cleanerd.c b/libexec/lfs_cleanerd/cleanerd.c
index da2d172112d..d78d09409c4 100644
--- a/libexec/lfs_cleanerd/cleanerd.c
+++ b/libexec/lfs_cleanerd/cleanerd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cleanerd.c,v 1.23 2000/11/03 17:52:55 perseant Exp $ */
+/* $NetBSD: cleanerd.c,v 1.24 2000/11/11 22:40:13 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.23 2000/11/03 17:52:55 perseant Exp $");
+__RCSID("$NetBSD: cleanerd.c,v 1.24 2000/11/11 22:40:13 perseant Exp $");
#endif
#endif /* not lint */
@@ -655,6 +655,8 @@ add_segment(fsp, slp, sbp)
struct tossstruct t;
struct dinode *dip;
caddr_t seg_buf;
+ caddr_t cmp_buf, cmp_dp;
+ size_t size;
daddr_t seg_addr;
int num_blocks, i, j, error;
int seg_isempty=0;
@@ -787,6 +789,32 @@ add_segment(fsp, slp, sbp)
}
}
+ /* Compress segment buffer, if necessary */
+ if (slp->sl_bytes < seg_size(lfsp) / 2) {
+ if (debug > 1)
+ syslog(LOG_DEBUG, "compressing: %d < %d",
+ (int)slp->sl_bytes, seg_size(lfsp) / 2);
+ cmp_buf = malloc(slp->sl_bytes); /* XXX could do in-place */
+ if (cmp_buf == NULL) {
+ if (debug)
+ syslog(LOG_DEBUG, "can't compress segment: %m");
+ } else {
+ cmp_dp = cmp_buf;
+ for (i = 0; i < num_blocks; i++) {
+ if(tba[i].bi_lbn == LFS_UNUSED_LBN)
+ size = sizeof(struct dinode);
+ else
+ size = tba[i].bi_size;
+ memcpy(cmp_dp, tba[i].bi_bp, size);
+ tba[i].bi_bp = cmp_dp;
+ cmp_dp += size;
+ }
+ free(seg_buf);
+ seg_buf = cmp_buf;
+ sbp->buf[sbp->nsegs - 1] = seg_buf;
+ }
+ }
+
/* Add these blocks to the accumulated list */
sbp->ba = realloc(sbp->ba, (sbp->nb + num_blocks) * sizeof(BLOCK_INFO));
memcpy(sbp->ba + sbp->nb, tba, num_blocks * sizeof(BLOCK_INFO));