1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)clean.h 8.1 (Berkeley) 06/04/93 8 */ 9 10 /* 11 * The LFS user-level library will be used when writing cleaners and 12 * checkers for LFS file systems. It will have facilities for finding 13 * and parsing LFS segments. 14 */ 15 16 #define DUMP_SUM_HEADER 0x0001 17 #define DUMP_INODE_ADDRS 0x0002 18 #define DUMP_FINFOS 0x0004 19 #define DUMP_ALL 0xFFFF 20 21 #define IFILE_NAME "ifile" 22 23 /* 24 * Cleaner parameters 25 * BUSY_LIM: lower bound of the number of segments currently available 26 * as a percentage of the total number of free segments possibly 27 * available. 28 * IDLE_LIM: Same as BUSY_LIM but used when the system is idle. 29 * MIN_SEGS: Minimum number of segments you should always have. 30 * I have no idea what this should be, but it should probably 31 * be a function of lfsp. 32 * NUM_TO_CLEAN: Number of segments to clean at once. Again, this 33 * should probably be based on the file system size and how 34 * full or empty the segments being cleaned are. 35 */ 36 37 #define BUSY_LIM 0.50 38 #define IDLE_LIM 0.90 39 40 #define MIN_SEGS(lfsp) (3) 41 #define NUM_TO_CLEAN(fsp) (1) 42 43 #define MAXLOADS 3 44 #define ONE_MIN 0 45 #define FIVE_MIN 1 46 #define FIFTEEN_MIN 2 47 48 typedef struct fs_info { 49 struct statfs *fi_statfsp; /* fsstat info from getfsstat */ 50 struct lfs fi_lfs; /* superblock */ 51 CLEANERINFO *fi_cip; /* Cleaner info from ifile */ 52 SEGUSE *fi_segusep; /* segment usage table (from ifile) */ 53 IFILE *fi_ifilep; /* ifile table (from ifile) */ 54 u_long fi_daddr_shift; /* shift to get byte offset of daddr */ 55 u_long fi_ifile_count; /* # entries in the ifile table */ 56 off_t fi_ifile_length; /* length of the ifile */ 57 } FS_INFO; 58 59 /* 60 * XXX: size (in bytes) of a segment 61 * should lfs_bsize be fsbtodb(fs,1), blksize(fs), or lfs_dsize? 62 */ 63 #define seg_size(fs) ((fs)->lfs_ssize << (fs)->lfs_bshift) 64 65 /* daddr -> byte offset */ 66 #define datobyte(fs, da) ((da) << (fs)->fi_daddr_shift) 67 #define bytetoda(fs, byte) ((byte) >> (fs)->fi_daddr_shift) 68 69 #define CLEANSIZE(fsp) (fsp->fi_lfs.lfs_cleansz << fsp->fi_lfs.lfs_bshift) 70 #define SEGTABSIZE(fsp) (fsp->fi_lfs.lfs_segtabsz << fsp->fi_lfs.lfs_bshift) 71 72 #define IFILE_ENTRY(fs, if, i) \ 73 ((IFILE *)((caddr_t)(if) + ((i) / (fs)->lfs_ifpb << (fs)->lfs_bshift)) \ 74 + (i) % (fs)->lfs_ifpb) 75 76 #define SEGUSE_ENTRY(fs, su, i) \ 77 ((SEGUSE *)((caddr_t)(su) + (fs)->lfs_bsize * ((i) / (fs)->lfs_sepb)) +\ 78 (i) % (fs)->lfs_sepb) 79 80 __BEGIN_DECLS 81 int dump_summary __P((struct lfs *, SEGSUM *, u_long, daddr_t **)); 82 void err __P((const int, const char *, ...)); 83 int fs_getmntinfo __P((struct statfs **, char *, int)); 84 int get __P((int, off_t, void *, size_t)); 85 FS_INFO *get_fs_info __P((struct statfs *, int)); 86 int lfs_segmapv __P((FS_INFO *, int, caddr_t, BLOCK_INFO **, int *)); 87 int mmap_segment __P((FS_INFO *, int, caddr_t *, int)); 88 void munmap_segment __P((FS_INFO *, caddr_t, int)); 89 void reread_fs_info __P((FS_INFO *, int)); 90 void toss __P((void *, int *, size_t, 91 int (*)(const void *, const void *, const void *), void *)); 92 93 /* 94 * USEFUL DEBUGGING FUNCTIONS: 95 */ 96 #ifdef VERBOSE 97 #define PRINT_FINFO(fp, ip) { \ 98 (void)printf(" %s %s%d version %d nblocks %d\n", \ 99 (ip)->if_version > (fp)->fi_version ? "TOSSING" : "KEEPING", \ 100 "FINFO for inode: ", (fp)->fi_ino, \ 101 (fp)->fi_version, (fp)->fi_nblocks); \ 102 fflush(stdout); \ 103 } 104 105 #define PRINT_INODE(b, bip) { \ 106 (void) printf("\t%s inode: %d daddr: 0x%lx create: %s\n", \ 107 b ? "KEEPING" : "TOSSING", (bip)->bi_inode, (bip)->bi_daddr, \ 108 ctime((time_t *)&(bip)->bi_segcreate)); \ 109 fflush(stdout); \ 110 } 111 112 #define PRINT_BINFO(bip) { \ 113 (void)printf("\tinode: %d lbn: %d daddr: 0x%lx create: %s\n", \ 114 (bip)->bi_inode, (bip)->bi_lbn, (bip)->bi_daddr, \ 115 ctime((time_t *)&(bip)->bi_segcreate)); \ 116 fflush(stdout); \ 117 } 118 119 #define PRINT_SEGUSE(sup, n) { \ 120 (void)printf("Segment %d nbytes=%lu\tflags=%c%c%c ninos=%d nsums=%d lastmod: %s\n", \ 121 n, (sup)->su_nbytes, \ 122 (sup)->su_flags & SEGUSE_DIRTY ? 'D' : 'C', \ 123 (sup)->su_flags & SEGUSE_ACTIVE ? 'A' : ' ', \ 124 (sup)->su_flags & SEGUSE_SUPERBLOCK ? 'S' : ' ', \ 125 (sup)->su_ninos, (sup)->su_nsums, \ 126 ctime((time_t *)&(sup)->su_lastmod)); \ 127 fflush(stdout); \ 128 } 129 130 void dump_super __P((struct lfs *)); 131 void dump_cleaner_info __P((void *)); 132 void print_SEGSUM __P(( struct lfs *, SEGSUM *)); 133 void print_CLEANERINFO __P((CLEANERINFO *)); 134 #else 135 #define PRINT_FINFO(fp, ip) 136 #define PRINT_INODE(b, bip) 137 #define PRINT_BINFO(bip) 138 #define PRINT_SEGUSE(sup, n) 139 #define dump_cleaner_info(cip) 140 #define dump_super(lfsp) 141 #endif 142 __END_DECLS 143