⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 library.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -