📄 library.c
字号:
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. */voidadd_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; u_long page_size;#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; psegaddr += db_per_block; bp += page_size; ++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. */voidadd_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; 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. */ intpseg_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 ((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 */intmmap_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) { err(0, "mmap_segment: bad open"); return (-1); } if (use_mmap) { *segbuf = mmap ((caddr_t)0, seg_size(lfsp), PROT_READ, 0, fid, seg_byte); if (*(long *)segbuf < 0) { err(0, "mmap_segment: mmap failed"); return (NULL); } } 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) { err(0, "mmap_segment: malloc failed"); return(NULL); } /* read the segment data into the buffer */ if (lseek (fid, seg_byte, SEEK_SET) != seg_byte) { err (0, "mmap_segment: bad lseek"); free(*segbuf); return (-1); } if (read (fid, *segbuf, ssize) != ssize) { err (0, "mmap_segment: bad read"); free(*segbuf); return (-1); } } close (fid); return (0);}voidmunmap_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: */voidprint_SEGSUM (lfsp, p) struct lfs *lfsp; SEGSUM *p;{ if (p) (void) dump_summary(lfsp, p, DUMP_ALL, NULL); else printf("0x0"); fflush(stdout);}intbi_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);} intbi_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);}voidtoss(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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -