diff --git a/libexec/lfs_cleanerd/Makefile b/libexec/lfs_cleanerd/Makefile deleted file mode 100644 index aeee566e6c6b..000000000000 --- a/libexec/lfs_cleanerd/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 -# $Id: Makefile,v 1.7 1997/02/22 14:21:43 peter Exp $ - -PROG= lfs_cleanerd -CFLAGS+=-I${.CURDIR}/../../sys/ufs/lfs -I${.CURDIR} ${DEBUG} -MAN8= lfs_cleanerd.8 -SRCS= cleanerd.c lfs_cksum.c library.c misc.c print.c - -.PATH: ${.CURDIR}/../../sys/ufs/lfs - -.include diff --git a/libexec/lfs_cleanerd/clean.h b/libexec/lfs_cleanerd/clean.h deleted file mode 100644 index 22bf50354b18..000000000000 --- a/libexec/lfs_cleanerd/clean.h +++ /dev/null @@ -1,169 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)clean.h 8.2 (Berkeley) 5/4/95 - * $Id: clean.h,v 1.6 1997/02/22 14:21:44 peter Exp $ - */ - -/* - * The LFS user-level library will be used when writing cleaners and - * checkers for LFS file systems. It will have facilities for finding - * and parsing LFS segments. - */ - -#define DUMP_SUM_HEADER 0x0001 -#define DUMP_INODE_ADDRS 0x0002 -#define DUMP_FINFOS 0x0004 -#define DUMP_ALL 0xFFFF - -#define IFILE_NAME "ifile" - -/* - * Cleaner parameters - * BUSY_LIM: lower bound of the number of segments currently available - * as a percentage of the total number of free segments possibly - * available. - * IDLE_LIM: Same as BUSY_LIM but used when the system is idle. - * MIN_SEGS: Minimum number of segments you should always have. - * I have no idea what this should be, but it should probably - * be a function of lfsp. - * NUM_TO_CLEAN: Number of segments to clean at once. Again, this - * should probably be based on the file system size and how - * full or empty the segments being cleaned are. - */ - -#define BUSY_LIM 0.50 -#define IDLE_LIM 0.90 - -#define MIN_SEGS(lfsp) (5) -#define NUM_TO_CLEAN(fsp) (1) - -#define MAXLOADS 3 -#define ONE_MIN 0 -#define FIVE_MIN 1 -#define FIFTEEN_MIN 2 - -typedef struct fs_info { - struct statfs *fi_statfsp; /* fsstat info from getfsstat */ - struct lfs fi_lfs; /* superblock */ - CLEANERINFO *fi_cip; /* Cleaner info from ifile */ - SEGUSE *fi_segusep; /* segment usage table (from ifile) */ - IFILE *fi_ifilep; /* ifile table (from ifile) */ - u_long fi_daddr_shift; /* shift to get byte offset of daddr */ - u_long fi_ifile_count; /* # entries in the ifile table */ - off_t fi_ifile_length; /* length of the ifile */ -} FS_INFO; - -/* - * XXX: size (in bytes) of a segment - * should lfs_bsize be fsbtodb(fs,1), blksize(fs), or lfs_dsize? - */ -#define seg_size(fs) ((fs)->lfs_ssize << (fs)->lfs_bshift) - -/* daddr -> byte offset */ -#define datobyte(fs, da) ((da) << (fs)->fi_daddr_shift) -#define bytetoda(fs, byte) ((byte) >> (fs)->fi_daddr_shift) - -#define CLEANSIZE(fsp) (fsp->fi_lfs.lfs_cleansz << fsp->fi_lfs.lfs_bshift) -#define SEGTABSIZE(fsp) (fsp->fi_lfs.lfs_segtabsz << fsp->fi_lfs.lfs_bshift) - -#define IFILE_ENTRY(fs, if, i) \ - ((IFILE *)((caddr_t)(if) + ((i) / (fs)->lfs_ifpb << (fs)->lfs_bshift)) \ - + (i) % (fs)->lfs_ifpb) - -#define SEGUSE_ENTRY(fs, su, i) \ - ((SEGUSE *)((caddr_t)(su) + (fs)->lfs_bsize * ((i) / (fs)->lfs_sepb)) +\ - (i) % (fs)->lfs_sepb) - -__BEGIN_DECLS -int dump_summary __P((struct lfs *, SEGSUM *, u_long, daddr_t **)); -void err __P((const int, const char *, ...)); -int fs_getmntinfo __P((struct statfs **, char *, char *)); -int get __P((int, off_t, void *, size_t)); -FS_INFO *get_fs_info __P((struct statfs *, int)); -int lfs_segmapv __P((FS_INFO *, int, caddr_t, BLOCK_INFO **, int *)); -int mmap_segment __P((FS_INFO *, int, caddr_t *, int)); -void munmap_segment __P((FS_INFO *, caddr_t, int)); -void reread_fs_info __P((FS_INFO *, int)); -void toss __P((void *, int *, size_t, - int (*)(const void *, const void *, const void *), void *)); - -/* - * USEFUL DEBUGGING FUNCTIONS: - */ -#ifdef VERBOSE -#define PRINT_FINFO(fp, ip) { \ - (void)printf(" %s %s%d version %d nblocks %d\n", \ - (ip)->if_version > (fp)->fi_version ? "TOSSING" : "KEEPING", \ - "FINFO for inode: ", (fp)->fi_ino, \ - (fp)->fi_version, (fp)->fi_nblocks); \ - fflush(stdout); \ -} - -#define PRINT_INODE(b, bip) { \ - (void) printf("\t%s inode: %d daddr: 0x%lx create: %s\n", \ - b ? "KEEPING" : "TOSSING", (bip)->bi_inode, (bip)->bi_daddr, \ - ctime((time_t *)&(bip)->bi_segcreate)); \ - fflush(stdout); \ -} - -#define PRINT_BINFO(bip) { \ - (void)printf("\tinode: %d lbn: %d daddr: 0x%lx create: %s\n", \ - (bip)->bi_inode, (bip)->bi_lbn, (bip)->bi_daddr, \ - ctime((time_t *)&(bip)->bi_segcreate)); \ - fflush(stdout); \ -} - -#define PRINT_SEGUSE(sup, n) { \ - (void)printf("Segment %d nbytes=%lu\tflags=%c%c%c ninos=%d nsums=%d lastmod: %s\n", \ - n, (sup)->su_nbytes, \ - (sup)->su_flags & SEGUSE_DIRTY ? 'D' : 'C', \ - (sup)->su_flags & SEGUSE_ACTIVE ? 'A' : ' ', \ - (sup)->su_flags & SEGUSE_SUPERBLOCK ? 'S' : ' ', \ - (sup)->su_ninos, (sup)->su_nsums, \ - ctime((time_t *)&(sup)->su_lastmod)); \ - fflush(stdout); \ -} - -void dump_super __P((struct lfs *)); -void dump_cleaner_info __P((void *)); -void print_SEGSUM __P(( struct lfs *, SEGSUM *)); -void print_CLEANERINFO __P((CLEANERINFO *)); -#else -#define PRINT_FINFO(fp, ip) -#define PRINT_INODE(b, bip) -#define PRINT_BINFO(bip) -#define PRINT_SEGUSE(sup, n) -#define dump_cleaner_info(cip) -#define dump_super(lfsp) -#endif -__END_DECLS diff --git a/libexec/lfs_cleanerd/cleanerd.c b/libexec/lfs_cleanerd/cleanerd.c deleted file mode 100644 index c429f34c1b59..000000000000 --- a/libexec/lfs_cleanerd/cleanerd.c +++ /dev/null @@ -1,584 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cleanerd.c 8.5 (Berkeley) 6/10/95"; -#endif -static const char rcsid[] = - "$Id: cleanerd.c,v 1.8 1997/11/24 07:26:59 charnier Exp $"; -#endif /* not lint */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "clean.h" -int do_small = 0; -int do_mmap = 0; -int stat_report = 0; -struct cleaner_stats { - double util_tot; - double util_sos; - int blocks_read; - int blocks_written; - int segs_cleaned; - int segs_empty; - int segs_error; -} cleaner_stats; - -struct seglist { - int sl_id; /* segment number */ - int sl_cost; /* cleaning cost */ - char sl_bytes; /* bytes in segment */ -}; - -struct tossstruct { - struct lfs *lfs; - int seg; -}; - -#define CLEAN_BYTES 0x1 - -/* function prototypes for system calls; not sure where they should go */ -int lfs_segwait __P((fsid_t *, struct timeval *)); -int lfs_segclean __P((fsid_t *, u_long)); -int lfs_bmapv __P((fsid_t *, BLOCK_INFO *, int)); -int lfs_markv __P((fsid_t *, BLOCK_INFO *, int)); - -/* function prototypes */ -int bi_tossold __P((const void *, const void *, const void *)); -int choose_segments __P((FS_INFO *, struct seglist *, - int (*)(FS_INFO *, SEGUSE *))); -void clean_fs __P((FS_INFO *, int (*)(FS_INFO *, SEGUSE *), int, long)); -int clean_loop __P((FS_INFO *, int, long)); -int clean_segment __P((FS_INFO *, int)); -int cost_benefit __P((FS_INFO *, SEGUSE *)); -int cost_compare __P((const void *, const void *)); -void sig_report __P((int)); -static void usage __P((void)); - -/* - * Cleaning Cost Functions: - * - * These return the cost of cleaning a segment. The higher the cost value - * the better it is to clean the segment, so empty segments have the highest - * cost. (It is probably better to think of this as a priority value - * instead). - * - * This is the cost-benefit policy simulated and described in Rosenblum's - * 1991 SOSP paper. - */ - -int -cost_benefit(fsp, su) - FS_INFO *fsp; /* file system information */ - SEGUSE *su; -{ - struct lfs *lfsp; - struct timeval t; - int age; - int live; - - gettimeofday(&t, NULL); - - live = su->su_nbytes; - age = t.tv_sec < su->su_lastmod ? 0 : t.tv_sec - su->su_lastmod; - - lfsp = &fsp->fi_lfs; - if (live == 0) - return (t.tv_sec * lblkno(lfsp, seg_size(lfsp))); - else { - /* - * from lfsSegUsage.c (Mendel's code). - * priority calculation is done using INTEGER arithmetic. - * sizes are in BLOCKS (that is why we use lblkno below). - * age is in seconds. - * - * priority = ((seg_size - live) * age) / (seg_size + live) - */ -#ifdef VERBOSE - if (live < 0 || live > seg_size(lfsp)) { - warnx("bad segusage count: %d", live); - live = 0; - } -#endif - return (lblkno(lfsp, seg_size(lfsp) - live) * age) - / lblkno(lfsp, seg_size(lfsp) + live); - } -} - -int -main(argc, argv) - int argc; - char *argv[]; -{ - FS_INFO *fsp; - struct statfs *lstatfsp; /* file system stats */ - struct timeval timeout; /* sleep timeout */ - fsid_t fsid; - long clean_opts; /* cleaning options */ - int nodaemon, segs_per_clean; - int opt, cmd_err; - char *fs_name; /* name of filesystem to clean */ - - cmd_err = nodaemon = 0; - clean_opts = 0; - segs_per_clean = 1; - while ((opt = getopt(argc, argv, "bdmn:r:s")) != -1) { - switch (opt) { - case 'b': /* - * Use live bytes to determine - * how many segs to clean. - */ - clean_opts |= CLEAN_BYTES; - break; - case 'd': /* Debug mode. */ - nodaemon = 1; - break; - case 'm': /* Use mmap instead of read/write */ - do_mmap = 1; - break; - case 'n': /* How many segs to clean at once */ - segs_per_clean = atoi(optarg); - break; - case 'r': /* Report every stat_report segments */ - stat_report = atoi(optarg); - break; - case 's': /* small writes */ - do_small = 1; - break; - default: - ++cmd_err; - } - } - argc -= optind; - argv += optind; - if (cmd_err || (argc != 1)) - usage(); - - fs_name = argv[0]; - - signal(SIGINT, sig_report); - signal(SIGUSR1, sig_report); - signal(SIGUSR2, sig_report); - if (fs_getmntinfo(&lstatfsp, fs_name, "lfs") == 0) { - /* didn't find the filesystem */ - errx(1, "filesystem %s isn't an LFS", fs_name); - } - - if (!nodaemon) /* should we become a daemon, chdir to / & close fd's */ - if (daemon(0, 0) == -1) - errx(1, "couldn't become a daemon"); - - timeout.tv_sec = 5*60; /* five minutes */ - timeout.tv_usec = 0; - fsid.val[0] = 0; - fsid.val[1] = 0; - - for (fsp = get_fs_info(lstatfsp, do_mmap); ; - reread_fs_info(fsp, do_mmap)) { - /* - * clean the filesystem, and, if it needed cleaning - * (i.e. it returned nonzero) try it again - * to make sure that some nasty process hasn't just - * filled the disk system up. - */ - if (clean_loop(fsp, segs_per_clean, clean_opts)) - continue; - -#ifdef VERBOSE - (void)printf("Cleaner going to sleep.\n"); -#endif - if (lfs_segwait(&fsid, &timeout) < 0) - warnx("lfs_segwait: returned error"); -#ifdef VERBOSE - (void)printf("Cleaner waking up.\n"); -#endif - } -} - -static void -usage() -{ - fprintf(stderr, "usage: lfs_cleanerd [-smd] fs_name\n"); - exit (1); -} - -/* return the number of segments cleaned */ -int -clean_loop(fsp, nsegs, options) - FS_INFO *fsp; /* file system information */ - int nsegs; - long options; -{ - double loadavg[MAXLOADS]; - time_t now; - u_long max_free_segs; - u_long db_per_seg; - - /* - * Compute the maximum possible number of free segments, given the - * number of free blocks. - */ - db_per_seg = fsbtodb(&fsp->fi_lfs, fsp->fi_lfs.lfs_ssize); - max_free_segs = fsp->fi_lfs.lfs_bfree / db_per_seg; - - /* - * We will clean if there are not enough free blocks or total clean - * space is less than BUSY_LIM % of possible clean space. - */ - now = time((time_t *)NULL); -#ifdef VERBOSE - printf("db_er_seg = %d max_free_segs = %d, bfree = %d avail = %d ", - db_per_seg, max_free_segs, fsp->fi_lfs.lfs_bfree, - fsp->fi_lfs.lfs_avail); - printf("clean = %d\n", fsp->fi_cip->clean); -#endif - if ((fsp->fi_lfs.lfs_bfree - fsp->fi_lfs.lfs_avail > db_per_seg && - fsp->fi_lfs.lfs_avail < db_per_seg) || - (fsp->fi_cip->clean < max_free_segs && - (fsp->fi_cip->clean <= MIN_SEGS(&fsp->fi_lfs) || - fsp->fi_cip->clean < max_free_segs * BUSY_LIM))) { - printf("Cleaner Running at %s (%d of %ld segments available)\n", - ctime(&now), fsp->fi_cip->clean, max_free_segs); - clean_fs(fsp, cost_benefit, nsegs, options); - return (1); - } else { - /* - * We will also clean if the system is reasonably idle and - * the total clean space is less then IDLE_LIM % of possible - * clean space. - */ - if (getloadavg(loadavg, MAXLOADS) == -1) { - warn("getloadavg failed"); - return (-1); - } - if (loadavg[ONE_MIN] == 0.2 && loadavg[FIVE_MIN] && - fsp->fi_cip->clean < max_free_segs * IDLE_LIM) { - clean_fs(fsp, cost_benefit, nsegs, options); - printf("Cleaner running (system idle) at %s", - ctime(&now)); - return (1); - } - } -#ifdef VERBOSE - printf("Cleaner not running at %s", ctime(&now)); -#endif - return (0); -} - - -void -clean_fs(fsp, cost_func, nsegs, options) - FS_INFO *fsp; /* file system information */ - int (*cost_func) __P((FS_INFO *, SEGUSE *)); - int nsegs; - long options; -{ - struct seglist *segs, *sp; - int to_clean, cleaned_bytes; - int i; - - if ((segs = - malloc(fsp->fi_lfs.lfs_nseg * sizeof(struct seglist))) == NULL) { - warnx("malloc failed"); - return; - } - i = choose_segments(fsp, segs, cost_func); -#ifdef VERBOSE - printf("clean_fs: found %d segments to clean in file system %s\n", - i, fsp->fi_statfsp->f_mntonname); - fflush(stdout); -#endif - if (i) { - /* Check which cleaning algorithm to use. */ - if (options & CLEAN_BYTES) { - cleaned_bytes = 0; - to_clean = nsegs << - (fsp->fi_lfs.lfs_segshift + fsp->fi_lfs.lfs_bshift); - for (sp = segs; i && cleaned_bytes < to_clean; - i--, ++sp) { - if (clean_segment(fsp, sp->sl_id) < 0) - warn("clean_segment failed"); - else if (lfs_segclean(&fsp->fi_statfsp->f_fsid, - sp->sl_id) < 0) - warn("lfs_segclean failed"); - printf("Cleaned segment %d (%d bytes)\n", - sp->sl_id, sp->sl_bytes); - cleaned_bytes += sp->sl_bytes; - } - } else - for (i = MIN(i, nsegs), sp = segs; i-- ; ++sp) { - if (clean_segment(fsp, sp->sl_id) < 0) - warn("clean_segment failed"); - else if (lfs_segclean(&fsp->fi_statfsp->f_fsid, - sp->sl_id) < 0) - warn("lfs_segclean failed"); - printf("Completed cleaning segment %d\n", sp->sl_id); - } - } - free(segs); -} - -/* - * Segment with the highest priority get sorted to the beginning of the - * list. This sort assumes that empty segments always have a higher - * cost/benefit than any utilized segment. - */ -int -cost_compare(a, b) - const void *a; - const void *b; -{ - return (((struct seglist *)b)->sl_cost - - ((struct seglist *)a)->sl_cost); -} - - -/* - * Returns the number of segments to be cleaned with the elements of seglist - * filled in. - */ -int -choose_segments(fsp, seglist, cost_func) - FS_INFO *fsp; - struct seglist *seglist; - int (*cost_func) __P((FS_INFO *, SEGUSE *)); -{ - struct lfs *lfsp; - struct seglist *sp; - SEGUSE *sup; - int i, nsegs; - - lfsp = &fsp->fi_lfs; - -#ifdef VERBOSE - (void)printf("Entering choose_segments\n"); -#endif - dump_super(lfsp); - dump_cleaner_info(fsp->fi_cip); - - for (sp = seglist, i = 0; i < lfsp->lfs_nseg; ++i) { - sup = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, i); - PRINT_SEGUSE(sup, i); - if (!(sup->su_flags & SEGUSE_DIRTY) || - sup->su_flags & SEGUSE_ACTIVE) - continue; -#ifdef VERBOSE - (void)printf("\tchoosing segment %d\n", i); -#endif - sp->sl_cost = (*cost_func)(fsp, sup); - sp->sl_id = i; - sp->sl_bytes = sup->su_nbytes; - ++sp; - } - nsegs = sp - seglist; - qsort(seglist, nsegs, sizeof(struct seglist), cost_compare); -#ifdef VERBOSE - (void)printf("Returning %d segments\n", nsegs); -#endif - return (nsegs); -} - - -int -clean_segment(fsp, id) - FS_INFO *fsp; /* file system information */ - int id; /* segment number */ -{ - BLOCK_INFO *block_array, *bp; - SEGUSE *sp; - struct lfs *lfsp; - struct tossstruct t; - caddr_t seg_buf; - double util; - int num_blocks, maxblocks, clean_blocks; - - lfsp = &fsp->fi_lfs; - sp = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, id); - -#ifdef VERBOSE - (void)printf("cleaning segment %d: contains %lu bytes\n", id, - sp->su_nbytes); - fflush(stdout); -#endif - /* XXX could add debugging to verify that segment is really empty */ - if (sp->su_nbytes == sp->su_nsums * LFS_SUMMARY_SIZE) { - ++cleaner_stats.segs_empty; - return (0); - } - - /* map the segment into a buffer */ - if (mmap_segment(fsp, id, &seg_buf, do_mmap) < 0) { - warn("mmap_segment failed"); - ++cleaner_stats.segs_error; - 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) { - warn("clean_segment: lfs_segmapv failed"); - ++cleaner_stats.segs_error; - return (-1); - } - cleaner_stats.blocks_read += fsp->fi_lfs.lfs_ssize; - -#ifdef VERBOSE - (void)printf("lfs_segmapv returned %d blocks\n", num_blocks); - fflush(stdout); -#endif - - /* get the current disk address of blocks contained by the segment */ - if (lfs_bmapv(&fsp->fi_statfsp->f_fsid, block_array, num_blocks) < 0) { - warn("clean_segment: lfs_bmapv failed"); - ++cleaner_stats.segs_error; - return -1; - } - - /* Now toss any blocks not in the current segment */ - t.lfs = lfsp; - t.seg = id; - toss(block_array, &num_blocks, sizeof(BLOCK_INFO), bi_tossold, &t); - - /* Check if last element should be tossed */ - if (num_blocks && bi_tossold(&t, block_array + num_blocks - 1, NULL)) - --num_blocks; - -#ifdef VERBOSE - { - BLOCK_INFO *_bip; - u_long *lp; - int i; - - (void)printf("after bmapv still have %d blocks\n", num_blocks); - fflush(stdout); - if (num_blocks) - printf("BLOCK INFOS\n"); - for (_bip = block_array, i=0; i < num_blocks; ++_bip, ++i) { - PRINT_BINFO(_bip); - lp = (u_long *)_bip->bi_bp; - } - } - -#endif - ++cleaner_stats.segs_cleaned; - cleaner_stats.blocks_written += num_blocks; - util = ((double)num_blocks / fsp->fi_lfs.lfs_ssize); - cleaner_stats.util_tot += util; - cleaner_stats.util_sos += util * util; - - if (do_small) - maxblocks = MAXPHYS / fsp->fi_lfs.lfs_bsize - 1; - else - maxblocks = num_blocks; - - 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) { - warn("clean_segment: lfs_markv failed"); - ++cleaner_stats.segs_error; - return (-1); - } - num_blocks -= clean_blocks; - } - - free(block_array); - munmap_segment(fsp, seg_buf, do_mmap); - if (stat_report && cleaner_stats.segs_cleaned % stat_report == 0) - sig_report(SIGUSR1); - return (0); -} - - -int -bi_tossold(client, a, b) - const void *client; - const void *a; - const void *b; -{ - const struct tossstruct *t; - - t = (struct tossstruct *)client; - - return (((BLOCK_INFO *)a)->bi_daddr == LFS_UNUSED_DADDR || - datosn(t->lfs, ((BLOCK_INFO *)a)->bi_daddr) != t->seg); -} - -void -sig_report(sig) - int sig; -{ - double avg; - - printf("lfs_cleanerd:\t%s%d\n\t\t%s%d\n\t\t%s%d\n\t\t%s%d\n\t\t%s%d\n", - "blocks_read ", cleaner_stats.blocks_read, - "blocks_written ", cleaner_stats.blocks_written, - "segs_cleaned ", cleaner_stats.segs_cleaned, - "segs_empty ", cleaner_stats.segs_empty, - "seg_error ", cleaner_stats.segs_error); - printf("\t\t%s%5.2f\n\t\t%s%5.2f\n", - "util_tot ", cleaner_stats.util_tot, - "util_sos ", cleaner_stats.util_sos); - printf("\t\tavg util: %4.2f std dev: %9.6f\n", - avg = cleaner_stats.util_tot / cleaner_stats.segs_cleaned, - cleaner_stats.util_sos / cleaner_stats.segs_cleaned - avg * avg); - - - if (sig == SIGUSR2) { - cleaner_stats.blocks_read = 0; - cleaner_stats.blocks_written = 0; - cleaner_stats.segs_cleaned = 0; - cleaner_stats.segs_empty = 0; - cleaner_stats.segs_error = 0; - cleaner_stats.util_tot = 0.0; - cleaner_stats.util_sos = 0.0; - } - if (sig == SIGINT) - exit(0); -} diff --git a/libexec/lfs_cleanerd/lfs_cleanerd.8 b/libexec/lfs_cleanerd/lfs_cleanerd.8 deleted file mode 100644 index 7ce8c33641f0..000000000000 --- a/libexec/lfs_cleanerd/lfs_cleanerd.8 +++ /dev/null @@ -1,79 +0,0 @@ -.\" Copyright (c) 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)lfs_cleanerd.8 8.2 (Berkeley) 12/11/93 -.\" $Id: lfs_cleanerd.8,v 1.6 1997/06/23 04:02:09 steve Exp $ -.\" -.Dd December 11, 1993 -.Dt LFS_CLEANERD 8 -.Os BSD 4.4 -.Sh NAME -.Nm lfs_cleanerd -.Nd garbage collect a log-structured file system -.Sh SYNOPSIS -.Nm lfs_cleanerd -.Op Fl ds -.Pa node -.Sh DESCRIPTION -The -.Nm -command starts a daemon process which garbage-collects -the log-structured file system residing at the point named by -.Ar node -in the global file system namespace. -This command is normally executed by -.Xr mount_lfs 8 -when the log-structured file system is mounted. -The daemon will exit within a few minutes -of when the file system it was cleaning is unmounted. -.Pp -Garbage collection on a log-structured file system is done by scanning -the file system's segments for active, i.e. referenced, data and copying -it to new segments. -When all of the active data in a given segment has been copied to a new -segment that segment can be marked as empty, thus reclaiming the space -taken by the inactive data which was in it. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl d -Run in debug mode. -Do not become a daemon process, and print debugging information. -.It Fl s -When cleaning the file system, read data in small chunks. -.El -.Sh SEE ALSO -.Xr mount_lfs 8 -.Sh HISTORY -The -.Nm -utility first appeared in -.Bx 4.4 . diff --git a/libexec/lfs_cleanerd/library.c b/libexec/lfs_cleanerd/library.c deleted file mode 100644 index 13132e57602d..000000000000 --- a/libexec/lfs_cleanerd/library.c +++ /dev/null @@ -1,699 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)library.c 8.3 (Berkeley) 5/24/95"; -#endif -static const char rcsid[] = - "$Id: library.c,v 1.9 1997/11/24 07:27:02 charnier Exp $"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "clean.h" - -void add_blocks __P((FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t, - daddr_t, daddr_t)); -void add_inodes __P((FS_INFO *, BLOCK_INFO *, int *, SEGSUM *, caddr_t, - daddr_t)); -int bi_compare __P((const void *, const void *)); -int bi_toss __P((const void *, const void *, const void *)); -u_long cksum __P((void *, size_t)); -void get_ifile __P((FS_INFO *, int)); -int get_superblock __P((FS_INFO *, struct lfs *)); -int pseg_valid __P((FS_INFO *, SEGSUM *)); - -/* - * This function will get information on a a filesystem which matches - * the name and type given. If a "name" is in a filesystem of the given - * type, then buf is filled with that filesystem's info, and the - * a non-zero value is returned. - */ -int -fs_getmntinfo(buf, name, type) - struct statfs **buf; - char *name; - char *type; -{ - /* allocate space for the filesystem info */ - *buf = (struct statfs *)malloc(sizeof(struct statfs)); - if (*buf == NULL) - return 0; - - /* grab the filesystem info */ - if (statfs(name, *buf) < 0) { - free(*buf); - return 0; - } - - /* check to see if it's the one we want */ - if (strcmp((*buf)->f_fstypename, type) || - strncmp(name, (*buf)->f_mntonname, MNAMELEN)) { - /* "this is not the filesystem you're looking for" */ - free(*buf); - return 0; - } - - return 1; -} - -/* - * Get all the information available on an LFS file system. - * Returns an pointer to an FS_INFO structure, NULL on error. - */ -FS_INFO * -get_fs_info (lstatfsp, use_mmap) - struct statfs *lstatfsp; /* IN: pointer to statfs struct */ - int use_mmap; /* IN: mmap or read */ -{ - FS_INFO *fsp; - - fsp = (FS_INFO *)malloc(sizeof(FS_INFO)); - if (fsp == NULL) - return NULL; - bzero(fsp, sizeof(FS_INFO)); - - fsp->fi_statfsp = lstatfsp; - if (get_superblock (fsp, &fsp->fi_lfs)) - errx(1, "get_fs_info: get_superblock failed"); - fsp->fi_daddr_shift = - fsp->fi_lfs.lfs_bshift - fsp->fi_lfs.lfs_fsbtodb; - get_ifile (fsp, use_mmap); - return (fsp); -} - -/* - * If we are reading the ifile then we need to refresh it. Even if - * we are mmapping it, it might have grown. Finally, we need to - * refresh the file system information (statfs) info. - */ -void -reread_fs_info(fsp, use_mmap) - FS_INFO *fsp; /* IN: prointer fs_infos to reread */ - int use_mmap; -{ - if (statfs(fsp->fi_statfsp->f_mntonname, fsp->fi_statfsp)) - errx(1, "reread_fs_info: statfs failed"); - get_ifile (fsp, use_mmap); -} - -/* - * Gets the superblock from disk (possibly in face of errors) - */ -int -get_superblock (fsp, sbp) - FS_INFO *fsp; /* local file system info structure */ - struct lfs *sbp; -{ - char mntfromname[MNAMELEN+1]; - int fid; - - strcpy(mntfromname, "/dev/r"); - strcat(mntfromname, fsp->fi_statfsp->f_mntfromname+5); - - if ((fid = open(mntfromname, O_RDONLY, (mode_t)0)) < 0) { - warn("get_superblock: bad open"); - return (-1); - } - - get(fid, LFS_LABELPAD, sbp, sizeof(struct lfs)); - close (fid); - - return (0); -} - -/* - * This function will map the ifile into memory. It causes a - * fatal error on failure. - */ -void -get_ifile (fsp, use_mmap) - FS_INFO *fsp; - int use_mmap; - -{ - struct stat file_stat; - caddr_t ifp; - char *ifile_name; - int count, fid; - - ifp = NULL; - ifile_name = malloc(strlen(fsp->fi_statfsp->f_mntonname) + - strlen(IFILE_NAME)+2); - strcat(strcat(strcpy(ifile_name, fsp->fi_statfsp->f_mntonname), "/"), - IFILE_NAME); - - if ((fid = open(ifile_name, O_RDWR, (mode_t)0)) < 0) - err(1, "get_ifile: bad open"); - - if (fstat (fid, &file_stat)) - err(1, "get_ifile: fstat failed"); - - if (use_mmap && file_stat.st_size == fsp->fi_ifile_length) { - (void) close(fid); - return; - } - - /* get the ifile */ - if (use_mmap) { - if (fsp->fi_cip) - munmap((caddr_t)fsp->fi_cip, fsp->fi_ifile_length); - ifp = mmap ((caddr_t)0, file_stat.st_size, - PROT_READ|PROT_WRITE, MAP_SHARED, fid, (off_t)0); - if (ifp == MAP_FAILED) - err(1, "get_ifile: mmap failed"); - } else { - if (fsp->fi_cip) - free(fsp->fi_cip); - if (!(ifp = malloc (file_stat.st_size))) - errx(1, "get_ifile: malloc failed"); -redo_read: - count = read (fid, ifp, (size_t) file_stat.st_size); - - if (count < 0) - err(1, "get_ifile: bad ifile read"); - else if (count < file_stat.st_size) { - warnx("get_ifile"); - if (lseek(fid, 0, SEEK_SET) < 0) - err(1, "get_ifile: bad ifile lseek"); - goto redo_read; - } - } - fsp->fi_ifile_length = file_stat.st_size; - close (fid); - - fsp->fi_cip = (CLEANERINFO *)ifp; - fsp->fi_segusep = (SEGUSE *)(ifp + CLEANSIZE(fsp)); - fsp->fi_ifilep = (IFILE *)((caddr_t)fsp->fi_segusep + SEGTABSIZE(fsp)); - - /* - * The number of ifile entries is equal to the number of blocks - * blocks in the ifile minus the ones allocated to cleaner info - * and segment usage table multiplied by the number of ifile - * entries per page. - */ - fsp->fi_ifile_count = (fsp->fi_ifile_length >> fsp->fi_lfs.lfs_bshift - - fsp->fi_lfs.lfs_cleansz - fsp->fi_lfs.lfs_segtabsz) * - fsp->fi_lfs.lfs_ifpb; - - free (ifile_name); -} - -/* - * This function will scan a segment and return a list of - * pairs which indicate which blocks were - * contained as live data within the segment when the segment - * summary was read (it may have "died" since then). Any given - * pair will be listed at most once. - */ -int -lfs_segmapv(fsp, seg, seg_buf, blocks, bcount) - FS_INFO *fsp; /* pointer to local file system information */ - int seg; /* the segment number */ - caddr_t seg_buf; /* the buffer containing the segment's data */ - BLOCK_INFO **blocks; /* OUT: array of block_info for live blocks */ - int *bcount; /* OUT: number of active blocks in segment */ -{ - BLOCK_INFO *bip; - SEGSUM *sp; - SEGUSE *sup; - struct lfs *lfsp; - caddr_t s, segend; - daddr_t pseg_addr, seg_addr; - int nelem, nblocks, nsegs; -#ifdef DIAGNOSTIC - FINFO *fip; - int i, sumsize; -#endif /* DIAGNOSTIC */ - time_t timestamp; - - lfsp = &fsp->fi_lfs; - nelem = 2 * lfsp->lfs_ssize; - if (!(bip = malloc(nelem * sizeof(BLOCK_INFO)))) - goto err0; - - sup = SEGUSE_ENTRY(lfsp, fsp->fi_segusep, seg); - s = seg_buf + (sup->su_flags & SEGUSE_SUPERBLOCK ? LFS_SBPAD : 0); - seg_addr = sntoda(lfsp, seg); - pseg_addr = seg_addr + - (sup->su_flags & SEGUSE_SUPERBLOCK ? btodb(LFS_SBPAD) : 0); -#ifdef VERBOSE - printf("\tsegment buffer at: 0x%x\tseg_addr 0x%x\n", s, seg_addr); -#endif /* VERBOSE */ - - *bcount = 0; - for (nsegs = 0, timestamp = 0; nsegs < sup->su_nsums; nsegs++) { - sp = (SEGSUM *)s; - - nblocks = pseg_valid(fsp, sp); - if (nblocks <= 0) { - printf("Warning: invalid segment summary at 0x%x\n", - pseg_addr); - break; - } - -#ifdef VERBOSE - printf("\tpartial at: 0x%x\n", pseg_addr); - print_SEGSUM(lfsp, sp); - fflush(stdout); -#endif /* VERBOSE */ - - /* Check if we have hit old data */ - if (timestamp > ((SEGSUM*)s)->ss_create) - break; - timestamp = ((SEGSUM*)s)->ss_create; - -#ifdef DIAGNOSTIC - /* Verify size of summary block */ - sumsize = sizeof(SEGSUM) + - (sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp); - for (i = 0, fip = (FINFO *)(sp + 1); i < sp->ss_nfinfo; ++i) { - sumsize += sizeof(FINFO) + - (fip->fi_nblocks - 1) * sizeof(daddr_t); - fip = (FINFO *)(&fip->fi_blocks[fip->fi_nblocks]); - } - if (sumsize > LFS_SUMMARY_SIZE) - errx(1, "segment %d summary block too big: %d", - seg, sumsize); -#endif - - if (*bcount + nblocks + sp->ss_ninos > nelem) { - nelem = *bcount + nblocks + sp->ss_ninos; - bip = realloc (bip, nelem * sizeof(BLOCK_INFO)); - if (!bip) - goto err0; - } - add_blocks(fsp, bip, bcount, sp, seg_buf, seg_addr, pseg_addr); - add_inodes(fsp, bip, bcount, sp, seg_buf, seg_addr); - pseg_addr += fsbtodb(lfsp, nblocks) + - bytetoda(fsp, LFS_SUMMARY_SIZE); - s += (nblocks << lfsp->lfs_bshift) + LFS_SUMMARY_SIZE; - } - qsort(bip, *bcount, sizeof(BLOCK_INFO), bi_compare); - toss(bip, bcount, sizeof(BLOCK_INFO), bi_toss, NULL); -#ifdef VERBOSE - { - BLOCK_INFO *_bip; - int i; - - printf("BLOCK INFOS\n"); - for (_bip = bip, i=0; i < *bcount; ++_bip, ++i) - PRINT_BINFO(_bip); - } -#endif - *blocks = bip; - return (0); - -err0: *bcount = 0; - return (-1); - -} - -/* - * This will parse a partial segment and fill in BLOCK_INFO structures - * for each block described in the segment summary. It will not include - * blocks or inodes from files with new version numbers. - */ -void -add_blocks (fsp, bip, countp, sp, seg_buf, segaddr, psegaddr) - FS_INFO *fsp; /* pointer to super block */ - BLOCK_INFO *bip; /* Block info array */ - int *countp; /* IN/OUT: number of blocks in array */ - SEGSUM *sp; /* segment summmary pointer */ - caddr_t seg_buf; /* buffer containing segment */ - daddr_t segaddr; /* address of this segment */ - daddr_t psegaddr; /* address of this partial segment */ -{ - IFILE *ifp; - FINFO *fip; - caddr_t bp; - daddr_t *dp, *iaddrp; - int db_per_block, i, j; - int db_frag; - u_long page_size; -long *lp; - -#ifdef VERBOSE - printf("FILE INFOS\n"); -#endif - db_per_block = fsbtodb(&fsp->fi_lfs, 1); - page_size = fsp->fi_lfs.lfs_bsize; - bp = seg_buf + datobyte(fsp, psegaddr - segaddr) + LFS_SUMMARY_SIZE; - bip += *countp; - psegaddr += bytetoda(fsp, LFS_SUMMARY_SIZE); - iaddrp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE); - --iaddrp; - for (fip = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; - ++i, fip = (FINFO *)(&fip->fi_blocks[fip->fi_nblocks])) { - - ifp = IFILE_ENTRY(&fsp->fi_lfs, fsp->fi_ifilep, fip->fi_ino); - PRINT_FINFO(fip, ifp); - if (ifp->if_version > fip->fi_version) - continue; - dp = &(fip->fi_blocks[0]); - for (j = 0; j < fip->fi_nblocks; j++, dp++) { - while (psegaddr == *iaddrp) { - psegaddr += db_per_block; - bp += page_size; - --iaddrp; - } - bip->bi_inode = fip->fi_ino; - bip->bi_lbn = *dp; - bip->bi_daddr = psegaddr; - bip->bi_segcreate = (time_t)(sp->ss_create); - bip->bi_bp = bp; - bip->bi_version = ifp->if_version; - if (fip->fi_lastlength == page_size) { - bip->bi_size = page_size; - psegaddr += db_per_block; - bp += page_size; - } else { - db_frag = fragstodb(&(fsp->fi_lfs), - numfrags(&(fsp->fi_lfs), - fip->fi_lastlength)); -#ifdef VERBOSE - printf("lastlength, frags: %d, %d, %d\n", - fip->fi_lastlength, temp, - bytetoda(fsp, temp)); - fflush(stdout); -#endif - bip->bi_size = fip->fi_lastlength; - bp += fip->fi_lastlength; - psegaddr += db_frag; - } - ++bip; - ++(*countp); - } - } -} - -/* - * For a particular segment summary, reads the inode blocks and adds - * INODE_INFO structures to the array. Returns the number of inodes - * actually added. - */ -void -add_inodes (fsp, bip, countp, sp, seg_buf, seg_addr) - FS_INFO *fsp; /* pointer to super block */ - BLOCK_INFO *bip; /* block info array */ - int *countp; /* pointer to current number of inodes */ - SEGSUM *sp; /* segsum pointer */ - caddr_t seg_buf; /* the buffer containing the segment's data */ - daddr_t seg_addr; /* disk address of seg_buf */ -{ - struct dinode *di = NULL; - struct lfs *lfsp; - IFILE *ifp; - BLOCK_INFO *bp; - daddr_t *daddrp; - ino_t inum; - int i; - - if (sp->ss_ninos <= 0) - return; - - bp = bip + *countp; - lfsp = &fsp->fi_lfs; -#ifdef VERBOSE - (void) printf("INODES:\n"); -#endif - daddrp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE); - for (i = 0; i < sp->ss_ninos; ++i) { - if (i % INOPB(lfsp) == 0) { - --daddrp; - di = (struct dinode *)(seg_buf + - ((*daddrp - seg_addr) << fsp->fi_daddr_shift)); - } else - ++di; - - inum = di->di_inumber; - bp->bi_lbn = LFS_UNUSED_LBN; - bp->bi_inode = inum; - bp->bi_daddr = *daddrp; - bp->bi_bp = di; - bp->bi_segcreate = sp->ss_create; - - if (inum == LFS_IFILE_INUM) { - bp->bi_version = 1; /* Ifile version should be 1 */ - bp++; - ++(*countp); - PRINT_INODE(1, bp); - } else { - ifp = IFILE_ENTRY(lfsp, fsp->fi_ifilep, inum); - PRINT_INODE(ifp->if_daddr == *daddrp, bp); - bp->bi_version = ifp->if_version; - if (ifp->if_daddr == *daddrp) { - bp++; - ++(*countp); - } - } - } -} - -/* - * Checks the summary checksum and the data checksum to determine if the - * segment is valid or not. Returns the size of the partial segment if it - * is valid, * and 0 otherwise. Use dump_summary to figure out size of the - * the partial as well as whether or not the checksum is valid. - */ -int -pseg_valid (fsp, ssp) - FS_INFO *fsp; /* pointer to file system info */ - SEGSUM *ssp; /* pointer to segment summary block */ -{ - caddr_t p; - int i, nblocks; - u_long *datap; - - if (ssp->ss_magic != SS_MAGIC) - return(0); - - if ((nblocks = dump_summary(&fsp->fi_lfs, ssp, 0, NULL)) <= 0 || - nblocks > fsp->fi_lfs.lfs_ssize - 1) - return(0); - - /* check data/inode block(s) checksum too */ - datap = (u_long *)malloc(nblocks * sizeof(u_long)); - p = (caddr_t)ssp + LFS_SUMMARY_SIZE; - for (i = 0; i < nblocks; ++i) { - datap[i] = *((u_long *)p); - p += fsp->fi_lfs.lfs_bsize; - } - if (cksum ((void *)datap, nblocks * sizeof(u_long)) != ssp->ss_datasum) - return (0); - - return (nblocks); -} - - -/* #define MMAP_SEGMENT */ -/* - * read a segment into a memory buffer - */ -int -mmap_segment (fsp, segment, segbuf, use_mmap) - FS_INFO *fsp; /* file system information */ - int segment; /* segment number */ - caddr_t *segbuf; /* pointer to buffer area */ - int use_mmap; /* mmap instead of read */ -{ - struct lfs *lfsp; - int fid; /* fildes for file system device */ - daddr_t seg_daddr; /* base disk address of segment */ - off_t seg_byte; - size_t ssize; - char mntfromname[MNAMELEN+2]; - - lfsp = &fsp->fi_lfs; - - /* get the disk address of the beginning of the segment */ - seg_daddr = sntoda(lfsp, segment); - seg_byte = datobyte(fsp, seg_daddr); - ssize = seg_size(lfsp); - - strcpy(mntfromname, "/dev/r"); - strcat(mntfromname, fsp->fi_statfsp->f_mntfromname+5); - - if ((fid = open(mntfromname, O_RDONLY, (mode_t)0)) < 0) { - warn("mmap_segment: bad open"); - return (-1); - } - - if (use_mmap) { - *segbuf = mmap ((caddr_t)0, seg_size(lfsp), PROT_READ, - MAP_SHARED, fid, seg_byte); - if (*segbuf == MAP_FAILED) { - warn("mmap_segment: mmap failed"); - return (0); - } - } else { -#ifdef VERBOSE - printf("mmap_segment\tseg_daddr: %lu\tseg_size: %lu\tseg_offset: %qu\n", - seg_daddr, ssize, seg_byte); -#endif - /* malloc the space for the buffer */ - *segbuf = malloc(ssize); - if (!*segbuf) { - warnx("mmap_segment: malloc failed"); - return(0); - } - - /* read the segment data into the buffer */ - if (lseek (fid, seg_byte, SEEK_SET) != seg_byte) { - warn("mmap_segment: bad lseek"); - free(*segbuf); - return (-1); - } - - if (read (fid, *segbuf, ssize) != ssize) { - warn("mmap_segment: bad read"); - free(*segbuf); - return (-1); - } - } - close (fid); - - return (0); -} - -void -munmap_segment (fsp, seg_buf, use_mmap) - FS_INFO *fsp; /* file system information */ - caddr_t seg_buf; /* pointer to buffer area */ - int use_mmap; /* mmap instead of read/write */ -{ - if (use_mmap) - munmap (seg_buf, seg_size(&fsp->fi_lfs)); - else - free (seg_buf); -} - - -/* - * USEFUL DEBUGGING TOOLS: - */ -void -print_SEGSUM (lfsp, p) - struct lfs *lfsp; - SEGSUM *p; -{ - if (p) - (void) dump_summary(lfsp, p, DUMP_ALL, NULL); - else printf("0x0"); - fflush(stdout); -} - -int -bi_compare(a, b) - const void *a; - const void *b; -{ - const BLOCK_INFO *ba, *bb; - int diff; - - ba = a; - bb = b; - - if ((diff = (int)(ba->bi_inode - bb->bi_inode))) - return (diff); - if ((diff = (int)(ba->bi_lbn - bb->bi_lbn))) { - if (ba->bi_lbn == LFS_UNUSED_LBN) - return(-1); - else if (bb->bi_lbn == LFS_UNUSED_LBN) - return(1); - else if (ba->bi_lbn < 0 && bb->bi_lbn >= 0) - return(1); - else if (bb->bi_lbn < 0 && ba->bi_lbn >= 0) - return(-1); - else - return (diff); - } - if ((diff = (int)(ba->bi_segcreate - bb->bi_segcreate))) - return (diff); - diff = (int)(ba->bi_daddr - bb->bi_daddr); - return (diff); -} - -int -bi_toss(dummy, a, b) - const void *dummy; - const void *a; - const void *b; -{ - const BLOCK_INFO *ba, *bb; - - ba = a; - bb = b; - - return(ba->bi_inode == bb->bi_inode && ba->bi_lbn == bb->bi_lbn); -} - -void -toss(p, nump, size, dotoss, client) - void *p; - int *nump; - size_t size; - int (*dotoss) __P((const void *, const void *, const void *)); - void *client; -{ - int i; - void *p1; - - if (*nump == 0) - return; - - for (i = *nump; --i > 0;) { - p1 = p + size; - if (dotoss(client, p, p1)) { - memmove(p, p1, i * size); - --(*nump); - } else - p += size; - } -} diff --git a/libexec/lfs_cleanerd/misc.c b/libexec/lfs_cleanerd/misc.c deleted file mode 100644 index e0b707145d8d..000000000000 --- a/libexec/lfs_cleanerd/misc.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$Id$"; -#endif /* not lint */ - -#include - -#include -#include -#include -#include -#include - -void -get(fd, off, p, len) - int fd; - off_t off; - void *p; - size_t len; -{ - int rbytes; - - if (lseek(fd, off, SEEK_SET) < 0) - err(1, NULL); - if ((rbytes = read(fd, p, len)) < 0) - err(1, NULL); - if (rbytes != len) - errx(1, "short read (%d, not %d)", rbytes, len); -} diff --git a/libexec/lfs_cleanerd/print.c b/libexec/lfs_cleanerd/print.c deleted file mode 100644 index 0c0de620bb3b..000000000000 --- a/libexec/lfs_cleanerd/print.c +++ /dev/null @@ -1,224 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)print.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$Id$"; -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include "clean.h" - -u_long cksum __P((void *, size_t)); - -/* - * Print out a summary block; return number of blocks in segment; 0 - * for empty segment or corrupt segment. - * Returns a pointer to the array of inode addresses. - */ -int -dump_summary(lfsp, sp, flags, iaddrp) - struct lfs *lfsp; - SEGSUM *sp; - u_long flags; - daddr_t **iaddrp; -{ - int i, j, numblocks; - daddr_t *dp; - - FINFO *fp; - int ck; - - if (sp->ss_sumsum != (ck = cksum(&sp->ss_datasum, - LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum)))) - return(-1); - - if (flags & DUMP_SUM_HEADER) { - (void)printf(" %s0x%X\t%s%d\t%s%d\n %s0x%X\t%s0x%X", - "next ", sp->ss_next, - "nfinfo ", sp->ss_nfinfo, - "ninos ", sp->ss_ninos, - "sumsum ", sp->ss_sumsum, - "datasum ", sp->ss_datasum ); - (void)printf("\tcreate %s", ctime((time_t *)&sp->ss_create)); - } - - numblocks = (sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp); - - /* Dump out inode disk addresses */ - if (flags & DUMP_INODE_ADDRS) - printf(" Inode addresses:"); - - dp = (daddr_t *)((caddr_t)sp + LFS_SUMMARY_SIZE); - for (--dp, i = 0; i < sp->ss_ninos; --dp) - if (flags & DUMP_INODE_ADDRS) { - (void)printf("\t0x%lx", *dp); - if (++i % 7 == 0) - (void)printf("\n"); - } else - ++i; - if (iaddrp) - *iaddrp = ++dp; - if (flags & DUMP_INODE_ADDRS) - printf("\n"); - - for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; ++i) { - numblocks += fp->fi_nblocks; - if (flags & DUMP_FINFOS) { - (void)printf(" %s%d version %d nblocks %d\n", - "FINFO for inode: ", fp->fi_ino, - fp->fi_version, fp->fi_nblocks); - dp = &(fp->fi_blocks[0]); - for (j = 0; j < fp->fi_nblocks; j++, dp++) { - (void)printf("\t%d", *dp); - if ((j % 8) == 7) - (void)printf("\n"); - } - if ((j % 8) != 0) - (void)printf("\n"); - fp = (FINFO *)dp; - } else { - fp = (FINFO *)(&fp->fi_blocks[fp->fi_nblocks]); - } - } - return (numblocks); -} - -#ifdef VERBOSE -void -dump_cleaner_info(ipage) - void *ipage; -{ - CLEANERINFO *cip; - - cip = (CLEANERINFO *)ipage; - (void)printf("segments clean\t%d\tsegments dirty\t%d\n\n", - cip->clean, cip->dirty); -} - -void -dump_super(lfsp) - struct lfs *lfsp; -{ - int i; - - (void)printf("%s0x%X\t%s0x%X\t%s%d\t%s%d\n", - "magic ", lfsp->lfs_magic, - "version ", lfsp->lfs_version, - "size ", lfsp->lfs_size, - "ssize ", lfsp->lfs_ssize); - (void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n", - "dsize ", lfsp->lfs_dsize, - "bsize ", lfsp->lfs_bsize, - "fsize ", lfsp->lfs_fsize, - "frag ", lfsp->lfs_frag); - - (void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n", - "minfree ", lfsp->lfs_minfree, - "inopb ", lfsp->lfs_inopb, - "ifpb ", lfsp->lfs_ifpb, - "nindir ", lfsp->lfs_nindir); - - (void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n", - "nseg ", lfsp->lfs_nseg, - "nspf ", lfsp->lfs_nspf, - "cleansz ", lfsp->lfs_cleansz, - "segtabsz ", lfsp->lfs_segtabsz); - - (void)printf("%s0x%X\t%s%d\t%s0x%X\t%s%d\n", - "segmask ", lfsp->lfs_segmask, - "segshift ", lfsp->lfs_segshift, - "bmask ", lfsp->lfs_bmask, - "bshift ", lfsp->lfs_bshift); - - (void)printf("%s0x%X\t\t%s%d\t%s0x%X\t%s%d\n", - "ffmask ", lfsp->lfs_ffmask, - "ffshift ", lfsp->lfs_ffshift, - "fbmask ", lfsp->lfs_fbmask, - "fbshift ", lfsp->lfs_fbshift); - - (void)printf("%s%d\t\t%s0x%X\t%s0x%qx\n", - "fsbtodb ", lfsp->lfs_fsbtodb, - "cksum ", lfsp->lfs_cksum, - "maxfilesize ", lfsp->lfs_maxfilesize); - - (void)printf("Superblock disk addresses:\t"); - for (i = 0; i < LFS_MAXNUMSB; i++) { - (void)printf(" 0x%X", lfsp->lfs_sboffs[i]); - if ( i == (LFS_MAXNUMSB >> 1)) - (void)printf("\n\t\t\t\t"); - } - (void)printf("\n"); - - (void)printf("Checkpoint Info\n"); - (void)printf("%s%d\t%s0x%X\t%s%d\n", - "free ", lfsp->lfs_free, - "idaddr ", lfsp->lfs_idaddr, - "ifile ", lfsp->lfs_ifile); - (void)printf("%s%d\t%s%d\t%s%d\n", - "bfree ", lfsp->lfs_bfree, - "avail ", lfsp->lfs_avail, - "uinodes ", lfsp->lfs_uinodes); - (void)printf("%s%d\t%s0x%X\t%s0x%X\n%s0x%X\t%s0x%X\t", - "nfiles ", lfsp->lfs_nfiles, - "lastseg ", lfsp->lfs_lastseg, - "nextseg ", lfsp->lfs_nextseg, - "curseg ", lfsp->lfs_curseg, - "offset ", lfsp->lfs_offset); - (void)printf("tstamp %s", ctime((time_t *)&lfsp->lfs_tstamp)); - (void)printf("\nIn-Memory Information\n"); - (void)printf("%s%d\t%s0x%X\t%s%d\t%s%d\t%s%d\n", - "seglock ", lfsp->lfs_seglock, - "iocount ", lfsp->lfs_iocount, - "writer ", lfsp->lfs_writer, - "dirops ", lfsp->lfs_dirops, - "doifile ", lfsp->lfs_doifile ); - (void)printf("%s%d\t%s%d\t%s0x%X\t%s%d\n", - "nactive ", lfsp->lfs_nactive, - "fmod ", lfsp->lfs_fmod, - "clean ", lfsp->lfs_clean, - "ronly ", lfsp->lfs_ronly); -} -#endif /* VERBOSE */