1*55491Sbostic /* 2*55491Sbostic * The LFS user-level library will be used when writing cleaners and 3*55491Sbostic * checkers for LFS file systems. It will have facilities 4*55491Sbostic * for finding and parsing LFS segments. 5*55491Sbostic */ 6*55491Sbostic 7*55491Sbostic #define IFILE_NAME "ifile" 8*55491Sbostic 9*55491Sbostic #ifndef TRUE 10*55491Sbostic #define TRUE (1) 11*55491Sbostic #define FALSE (0) 12*55491Sbostic #endif 13*55491Sbostic 14*55491Sbostic typedef struct fs_info { 15*55491Sbostic struct statfs *fi_statfsp; /* fsstat info from getfsstat */ 16*55491Sbostic struct lfs *fi_lfsp; /* superblock */ 17*55491Sbostic /* 18*55491Sbostic * shared cleaner info data 19*55491Sbostic * (from top of ifile) 20*55491Sbostic */ 21*55491Sbostic CLEANERINFO *fi_cip; 22*55491Sbostic SEGUSE *fi_segusep; /* segment usage table (from ifile) */ 23*55491Sbostic IFILE *fi_ifilep; /* ifile table (from ifile) */ 24*55491Sbostic u_long fi_daddr_shift; /* shift to get byte offset of daddr */ 25*55491Sbostic u_long fi_ifile_count; /* # entries in the ifile table */ 26*55491Sbostic u_long fi_ifile_length; /* length of the ifile */ 27*55491Sbostic } FS_INFO; 28*55491Sbostic 29*55491Sbostic 30*55491Sbostic #define fsid (fsp->fi_statfsp->f_fsid) 31*55491Sbostic #define statfsp (fsp->fi_statfsp) 32*55491Sbostic #define lfsp (fsp->fi_lfsp) 33*55491Sbostic #define cip (fsp->fi_cip) 34*55491Sbostic #define segusep (fsp->fi_segusep) 35*55491Sbostic #define ifilep (fsp->fi_ifilep) 36*55491Sbostic #define ifile_count (fsp->fi_ifile_count) 37*55491Sbostic #define ifile_length (fsp->fi_ifile_length) 38*55491Sbostic 39*55491Sbostic /* 40*55491Sbostic * XXX: size (in bytes) of a segment 41*55491Sbostic * should lfs_bsize be fsbtodb(fs,1), blksize(fs), or lfs_dsize? 42*55491Sbostic */ 43*55491Sbostic #define seg_size(fs) ((fs)->lfs_ssize<<(fs)->lfs_bshift) 44*55491Sbostic 45*55491Sbostic /* daddr -> byte offset */ 46*55491Sbostic #define datobyte(fs, da) ((da)<<(fs)->fi_daddr_shift) 47*55491Sbostic #define bytetoda(fs, byte) ((byte)>>(fs)->fi_daddr_shift) 48*55491Sbostic 49*55491Sbostic #define CLEANSIZE(fs) (CLEANSIZE_SU(fs) << fs->lfs_bshift) 50*55491Sbostic #define SEGTABSIZE(fs) (SEGTABSIZE_SU(fs) << fs->lfs_bshift) 51*55491Sbostic 52*55491Sbostic #define IFILE_ENTRY(fs, if, i) ((IFILE*)((caddr_t)(if) + \ 53*55491Sbostic (fs)->lfs_bsize*((i)/(fs)->lfs_ifpb) + \ 54*55491Sbostic sizeof(IFILE)*((i)%(fs)->lfs_ifpb))) 55*55491Sbostic #define SEGUSE_ENTRY(fs, su, i) ((SEGUSE*)((caddr_t)(su) + \ 56*55491Sbostic (fs)->lfs_bsize*((i)/(fs)->lfs_sepb) + \ 57*55491Sbostic sizeof(IFILE)*((i)%(fs)->lfs_sepb))) 58*55491Sbostic 59*55491Sbostic /* 60*55491Sbostic * fs_getmntinfo: 61*55491Sbostic * 62*55491Sbostic * This function will get information on all mounted file systems 63*55491Sbostic * with the given type. It will return the number of mounted file 64*55491Sbostic * systems with the right type. It will return in *buf a pointer to 65*55491Sbostic * the array of statfs structures. 66*55491Sbostic */ 67*55491Sbostic extern int 68*55491Sbostic fs_getmntinfo __P((struct statfs **buf, int type)); 69*55491Sbostic 70*55491Sbostic /* 71*55491Sbostic * get_fs_info: 72*55491Sbostic * 73*55491Sbostic * get all the information available on a file system 74*55491Sbostic */ 75*55491Sbostic extern int 76*55491Sbostic get_fs_info __P((struct statfs *lstatfsp, FS_INFO **fspp, int count)); 77*55491Sbostic 78*55491Sbostic extern void 79*55491Sbostic free_fs_info __P((FS_INFO *fsp, int count)); 80*55491Sbostic 81*55491Sbostic /* 82*55491Sbostic * get_superblock: 83*55491Sbostic * gets the superblock from disk (possibly in face of errors) 84*55491Sbostic */ 85*55491Sbostic extern int 86*55491Sbostic get_superblock __P((FS_INFO *fsp, struct lfs *sbp)); 87*55491Sbostic 88*55491Sbostic 89*55491Sbostic /* 90*55491Sbostic * get_ifile: 91*55491Sbostic * This function will map the ifile into memory. It returns 92*55491Sbostic * NULL on failure. 93*55491Sbostic */ 94*55491Sbostic extern int 95*55491Sbostic get_ifile __P((FS_INFO *fsp)); 96*55491Sbostic 97*55491Sbostic /* 98*55491Sbostic * segmapv: 99*55491Sbostic * 100*55491Sbostic * This function will scan a segment and return a list of 101*55491Sbostic * <inode, blocknum> pairs which indicate which blocks were 102*55491Sbostic * contained as live data within the segment at some point 103*55491Sbostic * (it may have "died" since then). Any given pair will be 104*55491Sbostic * listed at most once. 105*55491Sbostic */ 106*55491Sbostic extern int 107*55491Sbostic lfs_segmapv __P((FS_INFO *fsp, int seg, caddr_t seg_buf, 108*55491Sbostic BLOCK_INFO **blocks, int *bcount, 109*55491Sbostic INODE_INFO **inodes, int *icount)); 110*55491Sbostic 111*55491Sbostic /* 112*55491Sbostic * this will parse a partial segment and create a vector of block_info's 113*55491Sbostic * for live data blocks for live inodes. It will not include blocks or 114*55491Sbostic * inodes from files with new version numbers. 115*55491Sbostic */ 116*55491Sbostic extern void 117*55491Sbostic pseg_blocks __P((FS_INFO *fsp, int seg, SEGSUM *s, caddr_t seg_buf, 118*55491Sbostic BLOCK_INFO **blocks, int *count)); 119*55491Sbostic 120*55491Sbostic /* 121*55491Sbostic * this will parse a partial segment and create a vector of inode_info's 122*55491Sbostic * for live inodes. It will not include blocks or inodes from files 123*55491Sbostic * with new version numbers. 124*55491Sbostic */ 125*55491Sbostic extern void 126*55491Sbostic pseg_inodes __P((FS_INFO *fsp, int seg, SEGSUM *s, caddr_t seg_buf, 127*55491Sbostic INODE_INFO **inodes, int *count)); 128*55491Sbostic 129*55491Sbostic /* 130*55491Sbostic * return the size of the partial segment in bytes. 131*55491Sbostic */ 132*55491Sbostic extern u_long 133*55491Sbostic pseg_size __P((FS_INFO *fsp, SEGSUM *s)); 134*55491Sbostic 135*55491Sbostic 136*55491Sbostic /* 137*55491Sbostic * join block list b with list a (eliminating duplicates), leaving result 138*55491Sbostic * in list a. 139*55491Sbostic */ 140*55491Sbostic extern void 141*55491Sbostic pseg_bjoin __P((FS_INFO *fsp, BLOCK_INFO **ablocks, int *acount, 142*55491Sbostic BLOCK_INFO *bblocks, int bcount)); 143*55491Sbostic 144*55491Sbostic 145*55491Sbostic /* 146*55491Sbostic * join inode list b with list a (eliminating duplicates), leaving result 147*55491Sbostic * in list a. 148*55491Sbostic */ 149*55491Sbostic extern void 150*55491Sbostic pseg_ijoin __P((FS_INFO *fsp, INODE_INFO **ainodes, int *acount, 151*55491Sbostic INODE_INFO *binodes, int bcount)); 152*55491Sbostic 153*55491Sbostic 154*55491Sbostic /* is the segsum block valid? return TRUE if it is, FALSE otherwise */ 155*55491Sbostic extern int 156*55491Sbostic segsum_valid __P((FS_INFO *fsp, SEGSUM *ssp)); 157*55491Sbostic 158*55491Sbostic 159*55491Sbostic /* 160*55491Sbostic * pseg_valid: 161*55491Sbostic * 162*55491Sbostic * returns 1 if the partial segment is valid, and 0 if it is invalid. 163*55491Sbostic * it uses the checksums to verify validity. 164*55491Sbostic */ 165*55491Sbostic extern int 166*55491Sbostic pseg_valid __P((FS_INFO *fsp, SEGSUM *ssp)); 167*55491Sbostic 168*55491Sbostic 169*55491Sbostic /* 170*55491Sbostic * pseg_finfos: 171*55491Sbostic * 172*55491Sbostic * get array of FINFO pointers for partial segment 173*55491Sbostic * return the array in finfos, and the size of the array in count 174*55491Sbostic */ 175*55491Sbostic extern void 176*55491Sbostic pseg_finfos __P((FS_INFO *fsp, SEGSUM *ssp, FINFO ***finfos, int *count)); 177*55491Sbostic 178*55491Sbostic /* 179*55491Sbostic * blocksize: 180*55491Sbostic * 181*55491Sbostic * returns the size (in bytes) of a (logical) block. 182*55491Sbostic * this is used because lfs uses different block sizes, depending 183*55491Sbostic * on the logical # of the block. Lfs uses various sizes so 184*55491Sbostic * it doesn't need fragments. 185*55491Sbostic */ 186*55491Sbostic extern u_long 187*55491Sbostic blocksize __P((FS_INFO *fsp, int index)); 188*55491Sbostic 189*55491Sbostic /* 190*55491Sbostic * finfo_size: 191*55491Sbostic * 192*55491Sbostic * returns the size in bytes of an FINFO structure 193*55491Sbostic */ 194*55491Sbostic extern u_long 195*55491Sbostic finfo_size __P((FINFO *finfop)); 196*55491Sbostic 197*55491Sbostic /* 198*55491Sbostic * Simple, general purpose, fast checksum. Data must be short-aligned. 199*55491Sbostic * Returns a u_long in case we ever want to do something more rigorous. 200*55491Sbostic * 201*55491Sbostic * XXX 202*55491Sbostic * Use the TCP/IP checksum instead. 203*55491Sbostic */ 204*55491Sbostic extern u_long 205*55491Sbostic cksum __P((register void *str, register size_t len)); 206*55491Sbostic 207*55491Sbostic /* 208*55491Sbostic * read a segment into a memory buffer 209*55491Sbostic */ 210*55491Sbostic extern int 211*55491Sbostic mmap_segment __P((FS_INFO *fsp, int segment, caddr_t *seg_buf)); 212*55491Sbostic 213*55491Sbostic extern void 214*55491Sbostic munmap_segment __P((FS_INFO *fsp, caddr_t seg_buf)); 215*55491Sbostic 216*55491Sbostic 217*55491Sbostic /* 218*55491Sbostic * USEFUL DEBUGGING TOOLS: 219*55491Sbostic */ 220*55491Sbostic 221*55491Sbostic extern void 222*55491Sbostic print_IFILE __P((IFILE *p)); 223*55491Sbostic 224*55491Sbostic extern void 225*55491Sbostic print_SEGUSE __P((SEGUSE *p)); 226*55491Sbostic 227*55491Sbostic extern void 228*55491Sbostic print_CLEANERINFO __P((CLEANERINFO *p)); 229*55491Sbostic 230*55491Sbostic extern void 231*55491Sbostic print_SEGSUM __P((SEGSUM *p)); 232*55491Sbostic 233*55491Sbostic extern void 234*55491Sbostic print_time_t __P((time_t t)); 235*55491Sbostic 236*55491Sbostic extern void 237*55491Sbostic print_BLOCK_INFO __P((BLOCK_INFO *p)); 238*55491Sbostic 239*55491Sbostic extern void 240*55491Sbostic print_INODE_INFO __P((INODE_INFO *p)); 241*55491Sbostic 242*55491Sbostic extern void 243*55491Sbostic print_FINFO __P((FINFO *p)); 244*55491Sbostic 245*55491Sbostic extern void 246*55491Sbostic print_lfs __P((struct lfs *p)); 247*55491Sbostic 248