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