summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorperseant <perseant@NetBSD.org>2000-06-21 01:58:52 +0000
committerperseant <perseant@NetBSD.org>2000-06-21 01:58:52 +0000
commitbbc8485d45d6d6b2d14af7c9813df7acca1514d5 (patch)
treef9dd86f6ff71dcc73987d47d3f4d59f914f7d800 /libexec
parentf42e218016b9e25f8a8a78142965c99382a46f55 (diff)
Make sure to segunmap segments on error in lfs_bmapv or lfs_markv. Prevents
a memory leak of by default 1 Mb per error. May fix PR #9149.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/lfs_cleanerd/cleanerd.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/libexec/lfs_cleanerd/cleanerd.c b/libexec/lfs_cleanerd/cleanerd.c
index dcd746e3059..4a62f291ddb 100644
--- a/libexec/lfs_cleanerd/cleanerd.c
+++ b/libexec/lfs_cleanerd/cleanerd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cleanerd.c,v 1.18 2000/01/18 08:02:30 perseant Exp $ */
+/* $NetBSD: cleanerd.c,v 1.19 2000/06/21 01:58:52 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.18 2000/01/18 08:02:30 perseant Exp $");
+__RCSID("$NetBSD: cleanerd.c,v 1.19 2000/06/21 01:58:52 perseant Exp $");
#endif
#endif /* not lint */
@@ -591,13 +591,14 @@ clean_segment(fsp, slp)
double util;
caddr_t seg_buf;
daddr_t seg_addr;
- int num_blocks, maxblocks, clean_blocks, i, j;
+ int num_blocks, maxblocks, clean_blocks, i, j, error;
int seg_isempty=0;
unsigned long *lp;
lfsp = &fsp->fi_lfs;
sp = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, id);
seg_addr = sntoda(lfsp,id);
+ error = 0;
syslog(LOG_DEBUG, "cleaning segment %d: contains %lu bytes", id,
(unsigned long)sp->su_nbytes);
@@ -615,10 +616,11 @@ clean_segment(fsp, slp)
return (-1);
}
/* get a list of blocks that are contained by the segment */
- if (lfs_segmapv(fsp, id, seg_buf, &block_array, &num_blocks) < 0) {
- syslog(LOG_WARNING,"clean_segment: lfs_segmapv failed for segment %d",id);
- ++cleaner_stats.segs_error;
- return (-1);
+ if ((error = lfs_segmapv(fsp, id, seg_buf, &block_array,
+ &num_blocks)) < 0) {
+ syslog(LOG_WARNING,
+ "clean_segment: lfs_segmapv failed for segment %d", id);
+ goto out;
}
cleaner_stats.blocks_read += fsp->fi_lfs.lfs_ssize;
@@ -626,11 +628,10 @@ clean_segment(fsp, slp)
syslog(LOG_DEBUG, "lfs_segmapv returned %d blocks", num_blocks);
/* get the current disk address of blocks contained by the segment */
- if (lfs_bmapv(&fsp->fi_statfsp->f_fsid, block_array, num_blocks) < 0) {
+ if ((error = lfs_bmapv(&fsp->fi_statfsp->f_fsid, block_array,
+ num_blocks)) < 0) {
perror("clean_segment: lfs_bmapv failed");
- ++cleaner_stats.segs_error;
- free(block_array); /* XXX KS */
- return -1;
+ goto out;
}
/* Now toss any blocks not in the current segment */
@@ -725,21 +726,23 @@ clean_segment(fsp, slp)
for (bp = block_array; num_blocks > 0; bp += clean_blocks) {
clean_blocks = maxblocks < num_blocks ? maxblocks : num_blocks;
- if (lfs_markv(&fsp->fi_statfsp->f_fsid,
- bp, clean_blocks) < 0) {
+ if ((error = lfs_markv(&fsp->fi_statfsp->f_fsid,
+ bp, clean_blocks)) < 0) {
syslog(LOG_WARNING,"clean_segment: lfs_markv failed: %m");
- ++cleaner_stats.segs_error;
- free(block_array); /* XXX KS */
- return (-1);
+ goto out;
}
num_blocks -= clean_blocks;
}
- free(block_array);
+ out:
+ if (block_array)
+ free(block_array);
+ if (error)
+ ++cleaner_stats.segs_error;
munmap_segment(fsp, seg_buf, do_mmap);
if (stat_report && cleaner_stats.segs_cleaned % stat_report == 0)
sig_report(SIGUSR1);
- return (0);
+ return (error);
}