diff options
| author | perseant <perseant@NetBSD.org> | 2000-06-21 01:58:52 +0000 |
|---|---|---|
| committer | perseant <perseant@NetBSD.org> | 2000-06-21 01:58:52 +0000 |
| commit | bbc8485d45d6d6b2d14af7c9813df7acca1514d5 (patch) | |
| tree | f9dd86f6ff71dcc73987d47d3f4d59f914f7d800 /libexec | |
| parent | f42e218016b9e25f8a8a78142965c99382a46f55 (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.c | 39 |
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); } |
