1*55491Sbostic 2*55491Sbostic #include <sys/param.h> 3*55491Sbostic #include <sys/time.h> 4*55491Sbostic #include <sys/uio.h> 5*55491Sbostic #include <sys/vnode.h> 6*55491Sbostic #include <sys/stat.h> 7*55491Sbostic #include <sys/mount.h> 8*55491Sbostic 9*55491Sbostic #include <ufs/ufs/dinode.h> 10*55491Sbostic #include <ufs/lfs/lfs.h> 11*55491Sbostic #include <ufs/lfs/lfs_extern.h> 12*55491Sbostic 13*55491Sbostic #include <fcntl.h> 14*55491Sbostic #include <stdio.h> 15*55491Sbostic #include <unistd.h> 16*55491Sbostic #include "clean.h" 17*55491Sbostic 18*55491Sbostic /* 19*55491Sbostic * fs_getmntinfo: 20*55491Sbostic * 21*55491Sbostic * This function will get information on all mounted file systems 22*55491Sbostic * of a given type. 23*55491Sbostic */ 24*55491Sbostic int 25*55491Sbostic fs_getmntinfo(buf, type) 26*55491Sbostic struct statfs **buf; 27*55491Sbostic int type; 28*55491Sbostic { 29*55491Sbostic int i; 30*55491Sbostic int count; 31*55491Sbostic int tcount; 32*55491Sbostic struct statfs *tstatfsp; 33*55491Sbostic 34*55491Sbostic tcount = getmntinfo(&tstatfsp, 0); 35*55491Sbostic 36*55491Sbostic if (tcount < 0) { 37*55491Sbostic perror ("fs_getmntinfo: getmntinfo failed"); 38*55491Sbostic return -1; 39*55491Sbostic } 40*55491Sbostic 41*55491Sbostic for (count = 0, i = 0 ; i < tcount ; i ++) 42*55491Sbostic if (type == 0 || tstatfsp[i].f_type == type) 43*55491Sbostic ++ count; 44*55491Sbostic 45*55491Sbostic if (count > 0) { 46*55491Sbostic *buf = (struct statfs *) 47*55491Sbostic malloc(count*sizeof(struct statfs)); 48*55491Sbostic if (*buf == 0) { perror ("fs_getmntinfo: out of space"); exit (1); } 49*55491Sbostic for (i = 0, count = 0 ; i < tcount ; i ++) { 50*55491Sbostic if (type == 0 || tstatfsp[i].f_type == type) { 51*55491Sbostic (*buf)[count] = tstatfsp[i]; 52*55491Sbostic ++count; 53*55491Sbostic } 54*55491Sbostic } 55*55491Sbostic return count; 56*55491Sbostic } 57*55491Sbostic return 0; 58*55491Sbostic } 59*55491Sbostic 60*55491Sbostic /* 61*55491Sbostic * get_fs_info: 62*55491Sbostic * 63*55491Sbostic * get all the information available on a file system 64*55491Sbostic */ 65*55491Sbostic int 66*55491Sbostic get_fs_info (lstatfsp, fspp, count) 67*55491Sbostic struct statfs *lstatfsp; /* IN: array of statfs structs */ 68*55491Sbostic FS_INFO **fspp; /* OUT: resulting array of FS_INFOs */ 69*55491Sbostic int count; /* IN: number of file systems */ 70*55491Sbostic { 71*55491Sbostic int i; 72*55491Sbostic caddr_t ifp; 73*55491Sbostic FS_INFO *fsp; 74*55491Sbostic 75*55491Sbostic *fspp = (FS_INFO *)malloc(count * sizeof(FS_INFO)); 76*55491Sbostic 77*55491Sbostic for (i = 0 ; i < count ; i++) { 78*55491Sbostic fsp = *fspp + i; 79*55491Sbostic statfsp = lstatfsp + i; 80*55491Sbostic lfsp = (struct lfs *)malloc (LFS_SBPAD); 81*55491Sbostic if (get_superblock (fsp, lfsp) < 0) { 82*55491Sbostic perror("get_fs_info: get_superblock failed"); 83*55491Sbostic return -1; 84*55491Sbostic } 85*55491Sbostic fsp->fi_daddr_shift = lfsp->lfs_bshift - lfsp->lfs_fsbtodb; 86*55491Sbostic if (get_ifile (fsp) < 0) { 87*55491Sbostic perror("get_fs_info: get_ifile failed"); 88*55491Sbostic return -1; 89*55491Sbostic } 90*55491Sbostic } 91*55491Sbostic return 0; 92*55491Sbostic } 93*55491Sbostic 94*55491Sbostic /* this is needed temporarily, because of the bug in mmap'ed files */ 95*55491Sbostic void 96*55491Sbostic free_fs_info (fsp, count) 97*55491Sbostic FS_INFO *fsp; /* IN: array of fs_infos we will dispose of */ 98*55491Sbostic int count; /* IN: number of file systems */ 99*55491Sbostic { 100*55491Sbostic int i; 101*55491Sbostic caddr_t fsp_base = (caddr_t)fsp; 102*55491Sbostic 103*55491Sbostic for (i = 0 ; i < count ; i++, fsp++) { 104*55491Sbostic /* free superblock */ 105*55491Sbostic free (lfsp); 106*55491Sbostic /* sdp points to the beginning of the ifile area */ 107*55491Sbostic #ifndef MMAP_WORKS 108*55491Sbostic free (cip); 109*55491Sbostic #else 110*55491Sbostic if (munmap (cip, ifile_length) < 0) { 111*55491Sbostic perror("free_fs_info: munmap failed\n"); 112*55491Sbostic } 113*55491Sbostic #endif /* MMAP_WORKS */ 114*55491Sbostic } 115*55491Sbostic 116*55491Sbostic free (fsp_base); 117*55491Sbostic } 118*55491Sbostic 119*55491Sbostic /* 120*55491Sbostic * get_superblock: 121*55491Sbostic * gets the superblock from disk (possibly in face of errors) 122*55491Sbostic */ 123*55491Sbostic int 124*55491Sbostic get_superblock (fsp, sbp) 125*55491Sbostic FS_INFO *fsp; /* IN: array of fs_infos we will dispose of */ 126*55491Sbostic struct lfs *sbp; 127*55491Sbostic { 128*55491Sbostic int fid; 129*55491Sbostic char mntfromname[MNAMELEN+1]; 130*55491Sbostic 131*55491Sbostic strcpy(mntfromname, "/dev/r"); 132*55491Sbostic strcat(mntfromname, statfsp->f_mntfromname+5); 133*55491Sbostic 134*55491Sbostic if ((fid = open(mntfromname, O_RDONLY, (mode_t)0)) < 0) { 135*55491Sbostic perror("get_superblock: bad open"); 136*55491Sbostic return -1; 137*55491Sbostic } 138*55491Sbostic 139*55491Sbostic if(lseek (fid, LFS_LABELPAD, SEEK_SET) != LFS_LABELPAD) { 140*55491Sbostic perror("get_superblock: bad seek"); 141*55491Sbostic return -1; 142*55491Sbostic } 143*55491Sbostic if(read (fid, (char *)sbp, LFS_SBPAD) != LFS_SBPAD) { 144*55491Sbostic perror("get_superblock: bad read"); 145*55491Sbostic return -1; 146*55491Sbostic } 147*55491Sbostic close (fid); 148*55491Sbostic 149*55491Sbostic return 0; 150*55491Sbostic } 151*55491Sbostic 152*55491Sbostic /* 153*55491Sbostic * get_ifile: 154*55491Sbostic * This function will map the ifile into memory. It returns 155*55491Sbostic * NULL on failure. 156*55491Sbostic */ 157*55491Sbostic int 158*55491Sbostic get_ifile (fsp) 159*55491Sbostic FS_INFO *fsp; 160*55491Sbostic { 161*55491Sbostic int fid; 162*55491Sbostic int count; 163*55491Sbostic caddr_t ifp = NULL; 164*55491Sbostic char *ifile_name; 165*55491Sbostic struct stat file_stat; 166*55491Sbostic 167*55491Sbostic ifile_name = (char *) 168*55491Sbostic malloc(strlen(statfsp->f_mntonname)+strlen(IFILE_NAME)+2); 169*55491Sbostic strcpy(ifile_name, statfsp->f_mntonname); 170*55491Sbostic strcat(ifile_name, "/"); 171*55491Sbostic strcat(ifile_name, IFILE_NAME); 172*55491Sbostic 173*55491Sbostic if ((fid = open(ifile_name, O_RDWR, (mode_t)0)) < 0) { 174*55491Sbostic perror("get_ifile: bad open"); 175*55491Sbostic return -1; 176*55491Sbostic } 177*55491Sbostic 178*55491Sbostic if(fstat (fid, &file_stat)) { 179*55491Sbostic perror("get_ifile: fstat failed"); 180*55491Sbostic return -1; 181*55491Sbostic } 182*55491Sbostic ifile_length = file_stat.st_size; 183*55491Sbostic 184*55491Sbostic /* get the ifile */ 185*55491Sbostic #ifndef MMAP_WORKS 186*55491Sbostic ifp = (caddr_t)malloc (ifile_length); 187*55491Sbostic if (ifp == 0) { 188*55491Sbostic perror ("get_ifile: malloc failed, out of memory?"); 189*55491Sbostic return -1; 190*55491Sbostic } 191*55491Sbostic count = read (fid, ifp, ifile_length); 192*55491Sbostic 193*55491Sbostic if (count != ifile_length) { 194*55491Sbostic perror("get_ifile: bad ifile read"); 195*55491Sbostic return -1; 196*55491Sbostic } 197*55491Sbostic #else /* MMAP_WORKS */ 198*55491Sbostic ifp = mmap ((caddr_t)0, ifile_length, PROT_READ|PROT_WRITE, 199*55491Sbostic MAP_FILE|MAP_SHARED, fid, (off_t)0); 200*55491Sbostic if (ifp < 0) { 201*55491Sbostic perror("get_ifile: mmap failed"); 202*55491Sbostic return NULL; 203*55491Sbostic } 204*55491Sbostic #endif /* MMAP_WORKS */ 205*55491Sbostic 206*55491Sbostic close (fid); 207*55491Sbostic 208*55491Sbostic cip = (CLEANERINFO*)ifp; 209*55491Sbostic segusep = (SEGUSE*)(ifp + CLEANSIZE(lfsp)); 210*55491Sbostic ifilep = (IFILE*)(ifp + CLEANSIZE(lfsp) + SEGTABSIZE(lfsp)); 211*55491Sbostic /* # of bytes in ifile table */ 212*55491Sbostic ifile_count = ifile_length - (CLEANSIZE(lfsp) + SEGTABSIZE(lfsp)); 213*55491Sbostic /* # of ifile entries in ifile table */ 214*55491Sbostic ifile_count = (ifile_count / lfsp->lfs_bsize) * lfsp->lfs_ifpb; 215*55491Sbostic free (ifile_name); 216*55491Sbostic return 0; 217*55491Sbostic } 218*55491Sbostic 219*55491Sbostic 220*55491Sbostic /* 221*55491Sbostic * segmapv: 222*55491Sbostic * 223*55491Sbostic * This function will scan a segment and return a list of 224*55491Sbostic * <inode, blocknum> pairs which indicate which blocks were 225*55491Sbostic * contained as live data within the segment at some point 226*55491Sbostic * (it may have "died" since then). Any given pair will be 227*55491Sbostic * listed at most once. 228*55491Sbostic */ 229*55491Sbostic int 230*55491Sbostic lfs_segmapv(fsp, seg, seg_buf, blocks, bcount, inodes, icount) 231*55491Sbostic FS_INFO *fsp; /* pointer to super block */ 232*55491Sbostic int seg; /* the segment id */ 233*55491Sbostic caddr_t seg_buf; /* the buffer containing the segment's data */ 234*55491Sbostic /* OUT: array of block_info for live blocks */ 235*55491Sbostic BLOCK_INFO **blocks; 236*55491Sbostic int *bcount; /* OUT: number of active blocks in segment */ 237*55491Sbostic /* OUT: array of inode_info for live inodes */ 238*55491Sbostic INODE_INFO **inodes; 239*55491Sbostic int *icount; /* OUT: number of active inodes in segment */ 240*55491Sbostic { 241*55491Sbostic caddr_t s; 242*55491Sbostic caddr_t endofseg; 243*55491Sbostic int nextsum; 244*55491Sbostic u_long sb_off; 245*55491Sbostic time_t timestamp; 246*55491Sbostic 247*55491Sbostic *bcount = 0; 248*55491Sbostic *blocks = (BLOCK_INFO *)malloc (sizeof(BLOCK_INFO)); 249*55491Sbostic 250*55491Sbostic *icount = 0; 251*55491Sbostic *inodes = (INODE_INFO *)malloc(sizeof(INODE_INFO)); 252*55491Sbostic 253*55491Sbostic sb_off = (SEGUSE_ENTRY(lfsp, segusep, seg)->su_flags & SEGUSE_SUPERBLOCK) ? 254*55491Sbostic LFS_SBPAD : 0; 255*55491Sbostic 256*55491Sbostic for (s = seg_buf + sb_off, endofseg = seg_buf + seg_size(lfsp), 257*55491Sbostic timestamp = 0 ; 258*55491Sbostic s < endofseg ; 259*55491Sbostic s += pseg_size (fsp, (SEGSUM*)s)) { 260*55491Sbostic BLOCK_INFO *pblocks; 261*55491Sbostic int pbcount; 262*55491Sbostic INODE_INFO *pinodes; 263*55491Sbostic int picount; 264*55491Sbostic 265*55491Sbostic #ifdef VERBOSE 266*55491Sbostic printf("lfs_segmapv: seg_buf = 0x%x, pseg_buf = 0x%x, offset = %lu (0x%x), pseg = \n\t", 267*55491Sbostic (u_int)seg_buf, (u_int)s, 268*55491Sbostic (u_int)s - (u_int)seg_buf - (u_int)sb_off, 269*55491Sbostic (u_int)s - (u_int)seg_buf - (u_int)sb_off); 270*55491Sbostic /* this can cause core dumps when printing an invalid segsum 271*55491Sbostic * print_SEGSUM ((SEGSUM*)s); 272*55491Sbostic * printf("\n"); 273*55491Sbostic * printf("pseg_size = %lu\n", pseg_size(fsp, (SEGSUM*)s)); 274*55491Sbostic */ 275*55491Sbostic fflush(stdout); 276*55491Sbostic #endif /* VERBOSE */ 277*55491Sbostic 278*55491Sbostic /* we have hit the end of the valid data */ 279*55491Sbostic if (! pseg_valid (fsp, (SEGSUM*)s)) break; 280*55491Sbostic 281*55491Sbostic /* we have gone back in time and hit old data */ 282*55491Sbostic if (timestamp > ((SEGSUM*)s)->ss_create) break; 283*55491Sbostic 284*55491Sbostic timestamp = ((SEGSUM*)s)->ss_create; 285*55491Sbostic 286*55491Sbostic /* get the block and inode list */ 287*55491Sbostic pseg_blocks (fsp, seg, (SEGSUM*)s, seg_buf, 288*55491Sbostic &pblocks, &pbcount); 289*55491Sbostic pseg_bjoin (fsp, blocks, bcount, pblocks, pbcount); 290*55491Sbostic 291*55491Sbostic pseg_inodes (fsp, seg, (SEGSUM*)s, seg_buf, 292*55491Sbostic &pinodes, &picount); 293*55491Sbostic pseg_ijoin (fsp, inodes, icount, pinodes, picount); 294*55491Sbostic 295*55491Sbostic /* free the temporary tables */ 296*55491Sbostic free (pblocks); 297*55491Sbostic free (pinodes); 298*55491Sbostic } 299*55491Sbostic 300*55491Sbostic } 301*55491Sbostic 302*55491Sbostic /* 303*55491Sbostic * this will parse a partial segment and create a vector of block_info's 304*55491Sbostic * for live data and a vector of inode_info's for live inodes. It will 305*55491Sbostic * not include blocks or inodes from files with new version numbers. 306*55491Sbostic */ 307*55491Sbostic void 308*55491Sbostic pseg_blocks (fsp, seg, s, seg_buf, blocks, count) 309*55491Sbostic FS_INFO *fsp; /* pointer to super block */ 310*55491Sbostic int seg; /* the segment id */ 311*55491Sbostic SEGSUM *s; /* (unvalidated) segsum pointer */ 312*55491Sbostic caddr_t seg_buf; /* the buffer containing the segment's data */ 313*55491Sbostic /* OUT: array of block_info for live blocks */ 314*55491Sbostic BLOCK_INFO **blocks; 315*55491Sbostic int *count; /* OUT: number of active blocks in segment */ 316*55491Sbostic { 317*55491Sbostic FINFO **finfos; 318*55491Sbostic int finfoc; 319*55491Sbostic int blockc; 320*55491Sbostic int i; 321*55491Sbostic int j; 322*55491Sbostic int ninob; /* number of inode blocks passed */ 323*55491Sbostic daddr_t seg_daddr; 324*55491Sbostic daddr_t *cur_iaddrp; /* pointer to current inode block */ 325*55491Sbostic u_long offset; /* the offset (in bytes) within the segment */ 326*55491Sbostic 327*55491Sbostic *count = 0; 328*55491Sbostic *blocks = NULL; 329*55491Sbostic 330*55491Sbostic pseg_finfos (fsp, s, &finfos, &finfoc); 331*55491Sbostic 332*55491Sbostic #ifdef VERBOSE 333*55491Sbostic for(i=0;i<finfoc;i++){print_FINFO(finfos[i]);printf("\n");fflush(stdout);} 334*55491Sbostic printf("pseg_blocks: finfoc = %d\n", finfoc);fflush(stdout); 335*55491Sbostic #endif 336*55491Sbostic 337*55491Sbostic /* count how many blocks are held by live FINFO's */ 338*55491Sbostic for (i = 0, blockc = 0 ; i < finfoc ; ++i) 339*55491Sbostic if (finfos[i]->fi_version == 340*55491Sbostic IFILE_ENTRY(lfsp, ifilep, finfos[i]->fi_ino)->if_version) 341*55491Sbostic blockc += finfos[i]->fi_nblocks; 342*55491Sbostic 343*55491Sbostic if (finfoc == 0 || blockc == 0) return; 344*55491Sbostic 345*55491Sbostic ninob = 0; 346*55491Sbostic offset = LFS_SUMMARY_SIZE + ((u_int)s - (u_int)seg_buf) + 347*55491Sbostic s->ss_next * datobyte(fsp, 1<<lfsp->lfs_bshift); 348*55491Sbostic cur_iaddrp = (daddr_t*)(s->ss_ninos == 0 ? 0 : 349*55491Sbostic (char *)s + LFS_SUMMARY_SIZE - sizeof(daddr_t)); 350*55491Sbostic seg_daddr = sntoda(lfsp, seg); 351*55491Sbostic *blocks = (BLOCK_INFO *)malloc (blockc*sizeof(BLOCK_INFO)); 352*55491Sbostic 353*55491Sbostic for (i = 0 ; i < finfoc ; i ++) { 354*55491Sbostic FINFO *f = finfos[i]; 355*55491Sbostic 356*55491Sbostic if (f->fi_version != IFILE_ENTRY(lfsp, ifilep, f->fi_ino)->if_version) 357*55491Sbostic continue; 358*55491Sbostic 359*55491Sbostic #ifdef VERBOSE 360*55491Sbostic printf("finfo %d = ", i); 361*55491Sbostic print_FINFO(f); 362*55491Sbostic printf("\n"); 363*55491Sbostic fflush(stdout); 364*55491Sbostic printf("IFILE entry for file %d = ", f->fi_ino); 365*55491Sbostic print_IFILE (IFILE_ENTRY(lfsp, ifilep, f->fi_ino)); 366*55491Sbostic printf("\n"); 367*55491Sbostic fflush(stdout); 368*55491Sbostic #endif 369*55491Sbostic for (j = 0 ; j < finfos[i]->fi_nblocks ; j ++) { 370*55491Sbostic BLOCK_INFO *b = &(*blocks)[*count]; 371*55491Sbostic 372*55491Sbostic /* 373*55491Sbostic * XXX: 374*55491Sbostic * this changes if we have variable size blocks 375*55491Sbostic */ 376*55491Sbostic for (;cur_iaddrp && 377*55491Sbostic seg_daddr + bytetoda(fsp, offset) == *cur_iaddrp; 378*55491Sbostic offset += datobyte(fsp, 1<<lfsp->lfs_bshift)) { 379*55491Sbostic if (ninob <= (s->ss_ninos + INOPB(lfsp) - 1) 380*55491Sbostic / INOPB(lfsp)) { 381*55491Sbostic ++ninob; 382*55491Sbostic --cur_iaddrp; 383*55491Sbostic } else 384*55491Sbostic cur_iaddrp = NULL; 385*55491Sbostic } 386*55491Sbostic b->bi_inode = f->fi_ino; 387*55491Sbostic b->bi_lbn = f->fi_blocks[j]; 388*55491Sbostic b->bi_daddr = seg_daddr + bytetoda(fsp, offset); 389*55491Sbostic b->bi_segcreate = s->ss_create; 390*55491Sbostic b->bi_bp = seg_buf + offset; 391*55491Sbostic 392*55491Sbostic (*count) ++; 393*55491Sbostic offset += blocksize(fsp, b->bi_lbn); 394*55491Sbostic #ifdef VERBOSE 395*55491Sbostic printf("\tb[%d] = ", j); 396*55491Sbostic print_BLOCK_INFO(b); 397*55491Sbostic printf("\n"); 398*55491Sbostic fflush(stdout); 399*55491Sbostic #endif 400*55491Sbostic } 401*55491Sbostic } 402*55491Sbostic free (finfos); 403*55491Sbostic } 404*55491Sbostic 405*55491Sbostic void 406*55491Sbostic pseg_inodes (fsp, seg, s, seg_buf, inodes, count) 407*55491Sbostic FS_INFO *fsp; /* pointer to super block */ 408*55491Sbostic int seg; /* the segment id */ 409*55491Sbostic SEGSUM *s; /* (unvalidated) segsum pointer */ 410*55491Sbostic caddr_t seg_buf; /* the buffer containing the segment's data */ 411*55491Sbostic /* OUT: array of inode_info for live inodes */ 412*55491Sbostic INODE_INFO **inodes; 413*55491Sbostic int *count; /* OUT: number of active inodes in segment */ 414*55491Sbostic { 415*55491Sbostic int i; 416*55491Sbostic ino_t inum; 417*55491Sbostic daddr_t *daddrp, i_daddr, seg_daddr; 418*55491Sbostic struct dinode *di; 419*55491Sbostic 420*55491Sbostic *count = 0; 421*55491Sbostic *inodes = NULL; 422*55491Sbostic 423*55491Sbostic if (s->ss_ninos <= 0) return; 424*55491Sbostic 425*55491Sbostic *inodes = (INODE_INFO *)malloc (s->ss_ninos * sizeof(INODE_INFO)); 426*55491Sbostic 427*55491Sbostic seg_daddr = sntoda(lfsp, seg); 428*55491Sbostic 429*55491Sbostic #ifdef VERBOSE 430*55491Sbostic printf("pseg_inodes:\n"); 431*55491Sbostic print_SEGSUM(s); 432*55491Sbostic printf("\n"); 433*55491Sbostic fflush(stdout); 434*55491Sbostic #endif 435*55491Sbostic 436*55491Sbostic daddrp = (daddr_t *)((caddr_t)s + LFS_SUMMARY_SIZE); 437*55491Sbostic 438*55491Sbostic for (i = 0 ; i < s->ss_ninos ; ++i) { 439*55491Sbostic 440*55491Sbostic if (i % INOPB(lfsp) == 0) { 441*55491Sbostic i_daddr = *--daddrp; 442*55491Sbostic if (datosn(lfsp, i_daddr) != seg || 443*55491Sbostic datobyte(fsp, i_daddr - seg_daddr) > seg_size(lfsp)) { 444*55491Sbostic printf("pseg_inodes: bad i_daddr\n"); 445*55491Sbostic print_SEGSUM(s); 446*55491Sbostic printf("\n"); 447*55491Sbostic fflush(stdout); 448*55491Sbostic printf("i_daddr = %d, seg_daddr = %d, offset = %d, pseg_size = %d\n", 449*55491Sbostic i_daddr, seg_daddr, i_daddr - seg_daddr, 450*55491Sbostic pseg_size(fsp, (SEGSUM*)s)); 451*55491Sbostic fflush(stdout); 452*55491Sbostic } 453*55491Sbostic di = (struct dinode *) 454*55491Sbostic (seg_buf + datobyte(fsp, i_daddr - seg_daddr)); 455*55491Sbostic } else 456*55491Sbostic ++di; 457*55491Sbostic 458*55491Sbostic inum = di->di_inum; 459*55491Sbostic 460*55491Sbostic if (IFILE_ENTRY(lfsp, ifilep, inum)->if_daddr == i_daddr) { 461*55491Sbostic (*inodes)[*count].ii_inode = inum; 462*55491Sbostic (*inodes)[*count].ii_daddr = i_daddr; 463*55491Sbostic (*inodes)[*count].ii_segcreate = s->ss_create; 464*55491Sbostic (*inodes)[*count].ii_dinode = di; 465*55491Sbostic 466*55491Sbostic (*count) ++; 467*55491Sbostic } 468*55491Sbostic } 469*55491Sbostic } 470*55491Sbostic 471*55491Sbostic /* return the size of the partial segment in bytes. */ 472*55491Sbostic u_long 473*55491Sbostic pseg_size (fsp, s) 474*55491Sbostic FS_INFO *fsp; /* pointer to super block */ 475*55491Sbostic SEGSUM *s; /* segsum pointer */ 476*55491Sbostic { 477*55491Sbostic int i; 478*55491Sbostic int j; 479*55491Sbostic FINFO **finfos; 480*55491Sbostic int finfoc; 481*55491Sbostic u_long size = LFS_SUMMARY_SIZE; 482*55491Sbostic 483*55491Sbostic pseg_finfos (fsp, s, &finfos, &finfoc); 484*55491Sbostic for (i = 0 ; i < finfoc ; i ++) 485*55491Sbostic for (j = 0 ; j < finfos[i]->fi_nblocks ; j ++) 486*55491Sbostic size += blocksize(fsp, finfos[i]->fi_blocks[j]); 487*55491Sbostic 488*55491Sbostic /* inodes are packed INOPB inodes per block */ 489*55491Sbostic /* there can be unused space in an inode block */ 490*55491Sbostic size += datobyte(fsp, fsbtodb(lfsp,1)*((s->ss_ninos+INOPB(lfsp)-1)/INOPB(lfsp))); 491*55491Sbostic 492*55491Sbostic return size; 493*55491Sbostic } 494*55491Sbostic 495*55491Sbostic /* 496*55491Sbostic * join block list b with list a (eliminating duplicates), leaving result 497*55491Sbostic * in list a. 498*55491Sbostic */ 499*55491Sbostic void 500*55491Sbostic pseg_bjoin (fsp, ablocks, acount, bblocks, bcount) 501*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 502*55491Sbostic /* INOUT: array of live blocks block_info */ 503*55491Sbostic BLOCK_INFO **ablocks; 504*55491Sbostic int *acount; /* INOUT: number of active blocks */ 505*55491Sbostic /* IN: array of live blocks block_info */ 506*55491Sbostic BLOCK_INFO *bblocks; 507*55491Sbostic int bcount; /* IN: number of active blocks */ 508*55491Sbostic { 509*55491Sbostic int i; 510*55491Sbostic int j; 511*55491Sbostic BLOCK_INFO *abp; 512*55491Sbostic BLOCK_INFO *bbp; 513*55491Sbostic 514*55491Sbostic #ifdef VERBOSE 515*55491Sbostic printf("pseg_bjoin: *acount = %d, bcount = %d\n", *acount, bcount); 516*55491Sbostic /**/ 517*55491Sbostic printf("ablocks = \n"); 518*55491Sbostic for(i=0;i<*acount;i++){print_BLOCK_INFO((*ablocks)+i); printf("\n");} 519*55491Sbostic /**/ 520*55491Sbostic printf("bblocks = \n"); 521*55491Sbostic for(i=0;i<bcount;i++){print_BLOCK_INFO(bblocks+i); printf("\n");} 522*55491Sbostic /**/ 523*55491Sbostic fflush(stdout); 524*55491Sbostic /**/ 525*55491Sbostic #endif 526*55491Sbostic 527*55491Sbostic for (i = 0, bbp = bblocks ; i < bcount ; ++i, ++bbp) { 528*55491Sbostic for (j = 0, abp = *ablocks ; j < *acount ; ++j, ++abp) { 529*55491Sbostic if (abp->bi_inode == bbp->bi_inode 530*55491Sbostic && abp->bi_lbn == bbp->bi_lbn) { 531*55491Sbostic /* the data is for the same file and logical block */ 532*55491Sbostic if (abp->bi_segcreate < bbp->bi_segcreate) 533*55491Sbostic *abp = *bbp; 534*55491Sbostic break; 535*55491Sbostic } 536*55491Sbostic } 537*55491Sbostic if (j == *acount) { 538*55491Sbostic /* this is a block we haven't seen before */ 539*55491Sbostic *ablocks = (BLOCK_INFO*) 540*55491Sbostic realloc (*ablocks, sizeof(BLOCK_INFO)*(*acount + 1)); 541*55491Sbostic (*ablocks)[*acount] = *bbp; 542*55491Sbostic (*acount) ++; 543*55491Sbostic } 544*55491Sbostic } 545*55491Sbostic } 546*55491Sbostic 547*55491Sbostic /* 548*55491Sbostic * join block list b with list a (eliminating duplicates), leaving result 549*55491Sbostic * in list a. 550*55491Sbostic */ 551*55491Sbostic void 552*55491Sbostic pseg_ijoin (fsp, ainodes, acount, binodes, bcount) 553*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 554*55491Sbostic /* INOUT: array of live inodes inode_info */ 555*55491Sbostic INODE_INFO **ainodes; 556*55491Sbostic int *acount; /* INOUT: number of active inodes */ 557*55491Sbostic /* IN: array of live inodes inode_info */ 558*55491Sbostic INODE_INFO *binodes; 559*55491Sbostic int bcount; /* IN: number of active inodes */ 560*55491Sbostic { 561*55491Sbostic int i; 562*55491Sbostic int j; 563*55491Sbostic daddr_t daddr; 564*55491Sbostic INODE_INFO *aip; 565*55491Sbostic INODE_INFO *bip; 566*55491Sbostic 567*55491Sbostic /* we assume that we have no duplicate live inodes on "a" and "b" */ 568*55491Sbostic 569*55491Sbostic /* eliminate dead inodes from "a" */ 570*55491Sbostic for (i = 0, aip = *ainodes ; i < *acount ; ++aip ) { 571*55491Sbostic daddr = IFILE_ENTRY(lfsp, ifilep, aip->ii_inode)->if_daddr; 572*55491Sbostic if (daddr != aip->ii_daddr) 573*55491Sbostic *aip = (*ainodes)[--(*acount)]; 574*55491Sbostic else i++; 575*55491Sbostic } 576*55491Sbostic 577*55491Sbostic /* eliminate dead inodes from "b" */ 578*55491Sbostic for (i = 0, bip = binodes ; i < bcount ; ++bip) { 579*55491Sbostic daddr = IFILE_ENTRY(lfsp, ifilep, bip->ii_inode)->if_daddr; 580*55491Sbostic if (daddr != bip->ii_daddr) { 581*55491Sbostic /* don't really need to do this, only we don't want 582*55491Sbostic to lose any inodes, just in case */ 583*55491Sbostic INODE_INFO tmp; 584*55491Sbostic tmp = *bip; 585*55491Sbostic *bip = binodes[bcount]; 586*55491Sbostic binodes[bcount] = tmp; 587*55491Sbostic bcount --; 588*55491Sbostic } 589*55491Sbostic else i++; 590*55491Sbostic } 591*55491Sbostic /* append "b" to "a" */ 592*55491Sbostic if (bcount > 0) { 593*55491Sbostic *ainodes = (INODE_INFO *)realloc ((void *)*ainodes, 594*55491Sbostic (*acount + bcount + 1)*sizeof(INODE_INFO)); 595*55491Sbostic for (i = 0 ; i < bcount ; i ++) 596*55491Sbostic (*ainodes)[(*acount)++] = binodes[i]; 597*55491Sbostic } 598*55491Sbostic } 599*55491Sbostic 600*55491Sbostic /* is the segsum block valid? return TRUE if it is, FALSE otherwise */ 601*55491Sbostic int 602*55491Sbostic segsum_valid (fsp, ssp) 603*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 604*55491Sbostic SEGSUM *ssp; /* pointer to segment summary block */ 605*55491Sbostic { 606*55491Sbostic u_long sumsum; 607*55491Sbostic 608*55491Sbostic /* check segsum block checksum */ 609*55491Sbostic sumsum = cksum(&ssp->ss_datasum, 610*55491Sbostic LFS_SUMMARY_SIZE - sizeof(ssp->ss_sumsum)); 611*55491Sbostic 612*55491Sbostic if (sumsum != ssp->ss_sumsum) return FALSE; 613*55491Sbostic 614*55491Sbostic return TRUE; 615*55491Sbostic } 616*55491Sbostic 617*55491Sbostic /* 618*55491Sbostic * pseg_valid: 619*55491Sbostic * 620*55491Sbostic * returns 1 if the partial segment is valid, and 0 if it is invalid. 621*55491Sbostic * it uses the checksums to verify validity. 622*55491Sbostic */ 623*55491Sbostic int 624*55491Sbostic pseg_valid (fsp, ssp) 625*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 626*55491Sbostic SEGSUM *ssp; /* pointer to segment summary block */ 627*55491Sbostic { 628*55491Sbostic u_long datasum; 629*55491Sbostic u_long size; 630*55491Sbostic int nblocks; 631*55491Sbostic int i; 632*55491Sbostic u_long *datap; 633*55491Sbostic caddr_t p; 634*55491Sbostic 635*55491Sbostic /* check segsum block checksum */ 636*55491Sbostic if (segsum_valid (fsp, ssp) == FALSE) return FALSE; 637*55491Sbostic 638*55491Sbostic return TRUE; 639*55491Sbostic 640*55491Sbostic /* check data/inode block(s) checksum too... */ 641*55491Sbostic size = pseg_size (fsp, ssp); 642*55491Sbostic nblocks = size/fsbtodb(lfsp, 1); 643*55491Sbostic datap = (u_long*)malloc(sizeof(u_long)*nblocks); 644*55491Sbostic p = (caddr_t)ssp + LFS_SUMMARY_SIZE; 645*55491Sbostic for (i = 0 ; i < nblocks ; i ++) { 646*55491Sbostic datap[i] = *((u_long *)p); 647*55491Sbostic p += lfsp->lfs_bsize; 648*55491Sbostic } 649*55491Sbostic datasum = cksum ((void *)datap, nblocks*sizeof(u_long)); 650*55491Sbostic if (datasum != ssp->ss_datasum) return FALSE; 651*55491Sbostic 652*55491Sbostic return TRUE; 653*55491Sbostic } 654*55491Sbostic 655*55491Sbostic /* get array of FINFO pointers for partial segment */ 656*55491Sbostic void 657*55491Sbostic pseg_finfos (fsp, ssp, finfos, count) 658*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 659*55491Sbostic SEGSUM *ssp; /* pointer to segment summary block */ 660*55491Sbostic FINFO ***finfos; /* OUT: return an array of FINFO pointers */ 661*55491Sbostic int *count; /* OUT: return size of array */ 662*55491Sbostic { 663*55491Sbostic caddr_t p = (caddr_t)ssp + sizeof(SEGSUM); 664*55491Sbostic int i; 665*55491Sbostic FINFO *fip; 666*55491Sbostic 667*55491Sbostic *count = 0; 668*55491Sbostic *finfos = NULL; 669*55491Sbostic 670*55491Sbostic if (ssp->ss_nfinfo > 0) 671*55491Sbostic *finfos = (FINFO**)malloc (ssp->ss_nfinfo*sizeof(FINFO*)); 672*55491Sbostic 673*55491Sbostic for (i = 0 ; i < ssp->ss_nfinfo ; i ++) { 674*55491Sbostic fip = (FINFO *)p; 675*55491Sbostic (*finfos)[*count] = fip; 676*55491Sbostic (*count) ++; 677*55491Sbostic p += finfo_size (fip); 678*55491Sbostic } 679*55491Sbostic } 680*55491Sbostic 681*55491Sbostic /* 682*55491Sbostic * blocksize: 683*55491Sbostic * 684*55491Sbostic * returns the size (in bytes) of a (logical) block. 685*55491Sbostic * this is used because lfs uses different block sizes, depending 686*55491Sbostic * on the logical # of the block. Lfs uses various sizes so 687*55491Sbostic * it doesn't need fragments. 688*55491Sbostic */ 689*55491Sbostic u_long 690*55491Sbostic blocksize (fsp, index) 691*55491Sbostic FS_INFO *fsp; /* pointer to file system info */ 692*55491Sbostic int index; /* logical block # w/in file */ 693*55491Sbostic { 694*55491Sbostic return lfsp->lfs_bsize; /* XXX: blocksize might depend on 695*55491Sbostic the logical block number */ 696*55491Sbostic } 697*55491Sbostic 698*55491Sbostic /* 699*55491Sbostic * finfo_size 700*55491Sbostic * 701*55491Sbostic * returns the size in bytes of an FINFO structure 702*55491Sbostic */ 703*55491Sbostic u_long 704*55491Sbostic finfo_size (finfop) 705*55491Sbostic FINFO *finfop; 706*55491Sbostic { 707*55491Sbostic return sizeof(FINFO) + sizeof(long)*(finfop->fi_nblocks-1); 708*55491Sbostic } 709*55491Sbostic 710*55491Sbostic 711*55491Sbostic /* #define MMAP_SEGMENT */ 712*55491Sbostic /* 713*55491Sbostic * read a segment into a memory buffer 714*55491Sbostic */ 715*55491Sbostic int 716*55491Sbostic mmap_segment (fsp, segment, seg_buf) 717*55491Sbostic FS_INFO *fsp; /* file system information */ 718*55491Sbostic int segment; /* the index of the segment to be cleaned */ 719*55491Sbostic caddr_t *seg_buf; /* pointer to buffer area */ 720*55491Sbostic { 721*55491Sbostic off_t seg_daddr; /* base disk address of segment */ 722*55491Sbostic int fid; /* fildes for file system device */ 723*55491Sbostic char mntfromname[MNAMELEN+2]; 724*55491Sbostic 725*55491Sbostic /* get the disk address of the beginning of the segment */ 726*55491Sbostic seg_daddr = sntoda(lfsp, segment); 727*55491Sbostic 728*55491Sbostic strcpy(mntfromname, "/dev/r"); 729*55491Sbostic strcat(mntfromname, statfsp->f_mntfromname+5); 730*55491Sbostic 731*55491Sbostic if ((fid = open(mntfromname, O_RDONLY, (mode_t)0)) < 0) { 732*55491Sbostic perror("mmap_segment: bad open"); 733*55491Sbostic return -1; 734*55491Sbostic } 735*55491Sbostic 736*55491Sbostic #ifdef MMAP_SEGMENT 737*55491Sbostic *seg_buf = mmap ((caddr_t)0, seg_size(lfsp), PROT_READ, 738*55491Sbostic MAP_FILE, fid, (off_t)datobyte(fsp, seg_daddr)); 739*55491Sbostic if ((long)*seg_buf < 0) { 740*55491Sbostic perror("mmap_segment: mmap failed"); 741*55491Sbostic return NULL; 742*55491Sbostic } 743*55491Sbostic #else /* MMAP_SEGMENT */ 744*55491Sbostic printf("mmap_segment: seg_daddr = %lu, seg_size = %lu, seg_offset = %lu\n", 745*55491Sbostic seg_daddr, seg_size(lfsp), datobyte(fsp, seg_daddr)); 746*55491Sbostic /* malloc the space for the buffer */ 747*55491Sbostic *seg_buf = (caddr_t)malloc(seg_size(lfsp)); 748*55491Sbostic 749*55491Sbostic /* read the segment data into the buffer */ 750*55491Sbostic if (datobyte(fsp, seg_daddr) != lseek (fid, datobyte(fsp, seg_daddr), SEEK_SET)) { 751*55491Sbostic perror ("mmap_segment: bad lseek"); 752*55491Sbostic return -1; 753*55491Sbostic } 754*55491Sbostic 755*55491Sbostic if (seg_size(lfsp) != read (fid, *seg_buf, seg_size(lfsp))) { 756*55491Sbostic perror ("mmap_segment: bad read"); 757*55491Sbostic return -1; 758*55491Sbostic } 759*55491Sbostic #endif /* MMAP_SEGMENT */ 760*55491Sbostic close (fid); 761*55491Sbostic 762*55491Sbostic return 0; 763*55491Sbostic } 764*55491Sbostic 765*55491Sbostic void 766*55491Sbostic munmap_segment (fsp, seg_buf) 767*55491Sbostic FS_INFO *fsp; /* file system information */ 768*55491Sbostic caddr_t seg_buf; /* pointer to buffer area */ 769*55491Sbostic { 770*55491Sbostic #ifdef MMAP_SEGMENT 771*55491Sbostic munmap (seg_buf, seg_size(lfsp)); 772*55491Sbostic #else /* MMAP_SEGMENT */ 773*55491Sbostic free (seg_buf); 774*55491Sbostic #endif /* MMAP_SEGMENT */ 775*55491Sbostic } 776*55491Sbostic 777*55491Sbostic 778*55491Sbostic /* 779*55491Sbostic * USEFUL DEBUGGING TOOLS: 780*55491Sbostic */ 781*55491Sbostic 782*55491Sbostic void 783*55491Sbostic print_IFILE (p) 784*55491Sbostic IFILE *p; 785*55491Sbostic { 786*55491Sbostic if (p) { 787*55491Sbostic if (p->if_daddr == 0) 788*55491Sbostic printf("{free, if_version=%lu, if_nextfree=%lu}", 789*55491Sbostic p->if_version, p->if_nextfree); 790*55491Sbostic else 791*55491Sbostic printf("{if_version=%lu, if_daddr=%lu}", 792*55491Sbostic p->if_version, p->if_daddr); 793*55491Sbostic } 794*55491Sbostic else printf("0x0"); 795*55491Sbostic fflush(stdout); 796*55491Sbostic } 797*55491Sbostic 798*55491Sbostic void 799*55491Sbostic print_SEGUSE (p) 800*55491Sbostic SEGUSE *p; 801*55491Sbostic { 802*55491Sbostic if (p) { 803*55491Sbostic printf("{su_nbytes=%lu, su_flags=%c%c%c, su_lastmod=", 804*55491Sbostic p->su_nbytes, 805*55491Sbostic ((p->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), 806*55491Sbostic ((p->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), 807*55491Sbostic ((p->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' ')); 808*55491Sbostic print_time_t(p->su_lastmod); 809*55491Sbostic printf("}"); 810*55491Sbostic } 811*55491Sbostic else 812*55491Sbostic printf("0x0"); 813*55491Sbostic fflush(stdout); 814*55491Sbostic } 815*55491Sbostic 816*55491Sbostic void 817*55491Sbostic print_CLEANERINFO (p) 818*55491Sbostic CLEANERINFO *p; 819*55491Sbostic { 820*55491Sbostic if (p) printf("{clean=%lu, dirty=%lu}", p->clean, p->dirty); 821*55491Sbostic else printf("0x0"); 822*55491Sbostic fflush(stdout); 823*55491Sbostic } 824*55491Sbostic 825*55491Sbostic void 826*55491Sbostic print_SEGSUM (p) 827*55491Sbostic SEGSUM *p; 828*55491Sbostic { 829*55491Sbostic if (p) { 830*55491Sbostic printf("{ss_sumsum=%lu, ss_datasum=%lu, ss_next=%lu, ", 831*55491Sbostic p->ss_sumsum, p->ss_datasum, p->ss_next); 832*55491Sbostic printf("ss_create=%lu, ss_nfinfo=%lu, ss_ninos=%lu", 833*55491Sbostic p->ss_create, p->ss_nfinfo, p->ss_ninos); 834*55491Sbostic printf("}"); 835*55491Sbostic } 836*55491Sbostic else printf("0x0"); 837*55491Sbostic fflush(stdout); 838*55491Sbostic } 839*55491Sbostic 840*55491Sbostic void 841*55491Sbostic print_time_t (t) 842*55491Sbostic time_t t; 843*55491Sbostic { 844*55491Sbostic char temp[128]; 845*55491Sbostic int len; 846*55491Sbostic 847*55491Sbostic strcpy (temp, ctime(&t)); 848*55491Sbostic len = strlen(temp); 849*55491Sbostic if (temp[len-1] == '\n') temp[len-1] = 0; 850*55491Sbostic printf("%s", temp); 851*55491Sbostic fflush(stdout); 852*55491Sbostic } 853*55491Sbostic 854*55491Sbostic void 855*55491Sbostic print_FINFO (p) 856*55491Sbostic FINFO *p; 857*55491Sbostic { 858*55491Sbostic int i; 859*55491Sbostic 860*55491Sbostic if (p) { 861*55491Sbostic printf("{fi_nblocks=%lu, fi_version=%lu, fi_ino=%lu, fi_blocks={", 862*55491Sbostic p->fi_nblocks, p->fi_version, p->fi_ino); 863*55491Sbostic for (i = 0 ; i < p->fi_nblocks ; i ++) { 864*55491Sbostic if (i > 0) printf(", "); 865*55491Sbostic printf("%ld", p->fi_blocks[i]); 866*55491Sbostic } 867*55491Sbostic printf("}}"); 868*55491Sbostic } else printf("0x0"); 869*55491Sbostic fflush(stdout); 870*55491Sbostic } 871*55491Sbostic 872*55491Sbostic void 873*55491Sbostic print_BLOCK_INFO (p) 874*55491Sbostic BLOCK_INFO *p; 875*55491Sbostic { 876*55491Sbostic if (p) { 877*55491Sbostic printf("{bi_inode=%lu, bi_lbn=%ld, bi_daddr=%lu, bi_segcreate=", 878*55491Sbostic p->bi_inode, p->bi_lbn, p->bi_daddr); 879*55491Sbostic print_time_t(p->bi_segcreate); 880*55491Sbostic printf(", bi_bp = 0x%x}", p->bi_bp); 881*55491Sbostic } 882*55491Sbostic else 883*55491Sbostic printf("0x0"); 884*55491Sbostic fflush(stdout); 885*55491Sbostic } 886*55491Sbostic 887*55491Sbostic void 888*55491Sbostic print_INODE_INFO (p) 889*55491Sbostic INODE_INFO *p; 890*55491Sbostic { 891*55491Sbostic if (p) { 892*55491Sbostic printf("{ii_inode=%lu, ii_daddr=%lu, ii_segcreate=", 893*55491Sbostic p->ii_inode, p->ii_daddr); 894*55491Sbostic print_time_t (p->ii_segcreate); 895*55491Sbostic printf(", ii_dinode=0x%x}", p->ii_dinode); 896*55491Sbostic } 897*55491Sbostic else 898*55491Sbostic printf("0x0"); 899*55491Sbostic fflush(stdout); 900*55491Sbostic } 901*55491Sbostic 902*55491Sbostic void 903*55491Sbostic print_lfs (p) 904*55491Sbostic struct lfs *p; 905*55491Sbostic { 906*55491Sbostic int i; 907*55491Sbostic 908*55491Sbostic if (p) { 909*55491Sbostic printf("{\n"); 910*55491Sbostic printf("\tlfs_magic=0x%x\n", p->lfs_magic); 911*55491Sbostic printf("\tlfs_version=%lu\n", p->lfs_version); 912*55491Sbostic printf("\tlfs_size=%lu\n", p->lfs_size); 913*55491Sbostic printf("\tlfs_ssize=%lu\n", p->lfs_ssize); 914*55491Sbostic printf("\tlfs_dsize=%lu\n", p->lfs_dsize); 915*55491Sbostic printf("\tlfs_bsize=%lu\n", p->lfs_bsize); 916*55491Sbostic printf("\tlfs_fsize=%lu\n", p->lfs_fsize); 917*55491Sbostic printf("\tlfs_frag=%lu\n", p->lfs_frag); 918*55491Sbostic /* checkpoint region */ 919*55491Sbostic printf("\tlfs_free=%lu\n", p->lfs_free); 920*55491Sbostic printf("\tlfs_bfree=%lu\n", p->lfs_bfree); 921*55491Sbostic printf("\tlfs_nfiles=%lu\n", p->lfs_nfiles); 922*55491Sbostic printf("\tlfs_idaddr=%lu\n", p->lfs_idaddr); 923*55491Sbostic printf("\tlfs_ifile=%lu\n", p->lfs_ifile); 924*55491Sbostic printf("\tlfs_lastseg=%lu\n", p->lfs_lastseg); 925*55491Sbostic printf("\tlfs_nextseg=%lu\n", p->lfs_nextseg); 926*55491Sbostic printf("\tlfs_curseg=%lu\n", p->lfs_curseg); 927*55491Sbostic printf("\tlfs_offset=%lu\n", p->lfs_offset); 928*55491Sbostic printf("\tlfs_tstamp=%lu\n", p->lfs_tstamp); 929*55491Sbostic /* configuration parameters */ 930*55491Sbostic printf("\tlfs_minfree=%lu\n", p->lfs_minfree); 931*55491Sbostic /* these fields can be computed from the others */ 932*55491Sbostic printf("\tlfs_dbpseg=%lu\n", p->lfs_dbpseg); 933*55491Sbostic printf("\tlfs_inopb=%lu\n", p->lfs_inopb); 934*55491Sbostic printf("\tlfs_ifpb=%lu\n", p->lfs_ifpb); 935*55491Sbostic printf("\tlfs_sepb=%lu\n", p->lfs_sepb); 936*55491Sbostic printf("\tlfs_nindir=%lu\n", p->lfs_nindir); 937*55491Sbostic printf("\tlfs_nseg=%lu\n", p->lfs_nseg); 938*55491Sbostic printf("\tlfs_nspf=%lu\n", p->lfs_nspf); 939*55491Sbostic printf("\tlfs_cleansz=%lu\n", p->lfs_cleansz); 940*55491Sbostic printf("\tlfs_segtabsz=%lu\n", p->lfs_segtabsz); 941*55491Sbostic 942*55491Sbostic printf("\tlfs_segmask=%lu\n", p->lfs_segmask); 943*55491Sbostic printf("\tlfs_segshift=%lu\n", p->lfs_segshift); 944*55491Sbostic printf("\tlfs_bmask=%lu\n", p->lfs_bmask); 945*55491Sbostic printf("\tlfs_bshift=%lu\n", p->lfs_bshift); 946*55491Sbostic printf("\tlfs_ffmask=%lu\n", p->lfs_ffmask); 947*55491Sbostic printf("\tlfs_ffshift=%lu\n", p->lfs_ffshift); 948*55491Sbostic printf("\tlfs_fbmask=%lu\n", p->lfs_fbmask); 949*55491Sbostic printf("\tlfs_fbshift=%lu\n", p->lfs_fbshift); 950*55491Sbostic printf("\tlfs_fsbtodb=%lu\n", p->lfs_fsbtodb); 951*55491Sbostic /* superblock offsets */ 952*55491Sbostic printf("\tlfs_sboffs={"); 953*55491Sbostic for (i = 0 ; i < LFS_MAXNUMSB ; i ++) { 954*55491Sbostic if (i > 0) printf(", "); 955*55491Sbostic printf("%lu", p->lfs_sboffs[i]); 956*55491Sbostic } 957*55491Sbostic printf("}\n"); 958*55491Sbostic 959*55491Sbostic printf("}"); 960*55491Sbostic } 961*55491Sbostic else 962*55491Sbostic printf("0x0"); 963*55491Sbostic fflush(stdout); 964*55491Sbostic } 965