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

📄 ufs_alloc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto norot;	}	bpref = blknum(fs, bpref);	bpref = dtogd(fs, bpref);	/*	 * if the requested block is available, use it	 */	if (isblock(fs, cgp->cg_free, fragstoblks(fs, bpref))) {		bno = bpref;		goto gotit;	}	/*	 * check for a block available on the same cylinder	 */	cylno = cbtocylno(fs, bpref);	if (cgp->cg_btot[cylno] == 0)		goto norot;	if (fs->fs_cpc == 0) {		/*		 * block layout info is not available, so just have		 * to take any block in this cylinder.		 */		bpref = howmany(fs->fs_spc * cylno, NSPF(fs));		goto norot;	}	/*	 * check the summary information to see if a block is 	 * available in the requested cylinder starting at the	 * requested rotational position and proceeding around.	 */	cylbp = cgp->cg_b[cylno];	pos = cbtorpos(fs, bpref);	for (i = pos; i < NRPOS; i++)		if (cylbp[i] > 0)			break;	if (i == NRPOS)		for (i = 0; i < pos; i++)			if (cylbp[i] > 0)				break;	if (cylbp[i] > 0) {		/*		 * found a rotational position, now find the actual		 * block. A panic if none is actually there.		 */		pos = cylno % fs->fs_cpc;		bno = (cylno - pos) * fs->fs_spc / NSPB(fs);		if (fs->fs_postbl[pos][i] == -1) {			printf("pos = %d, i = %d, fs = %s\n",			    pos, i, fs->fs_fsmnt);			panic("alloccgblk: cyl groups corrupted");		}		for (i = fs->fs_postbl[pos][i];; ) {			if (isblock(fs, cgp->cg_free, bno + i)) {				bno = blkstofrags(fs, (bno + i));				goto gotit;			}			delta = fs->fs_rotbl[i];			if (delta <= 0 || delta > MAXBPC - i)				break;			i += delta;		}		printf("pos = %d, i = %d, fs = %s\n", pos, i, fs->fs_fsmnt);		panic("alloccgblk: can't find blk in cyl");	}norot:	/*	 * no blocks in the requested cylinder, so take next	 * available one in this cylinder group.	 */	bno = mapsearch(fs, cgp, bpref, (int)fs->fs_frag);	if (bno < 0)		return (NULL);	cgp->cg_rotor = bno;gotit:	clrblock(fs, cgp->cg_free, (long)fragstoblks(fs, bno));	cgp->cg_cs.cs_nbfree--;	cylno = cbtocylno(fs, bno);	cgp->cg_b[cylno][cbtorpos(fs, bno)]--;	cgp->cg_btot[cylno]--;	fs_lock(mp);	fs->fs_cstotal.cs_nbfree--;	fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--;	mp->m_flags |= M_MOD;	fs_unlock(mp);	return (cgp->cg_cgx * fs->fs_fpg + bno);}	/* * Determine whether an gnode can be allocated. * * Check to see if an gnode is available, and if it is, * allocate it using the following policy: *   1) allocate the requested gnode. *   2) allocate the next available gnode after the requested *      gnode in the specified cylinder group. */gno_tialloccg(gp, cg, gpref, mode)	register struct gnode *gp;	int cg;	register daddr_t gpref;	int mode;{	register struct fs *fs;	register struct cg *cgp;	struct buf *bp;	int start, len, loc;	register int map, i;	fs = FS(gp);	if (fs->fs_cs(fs, cg).cs_nifree == 0)		return (NULL);	bp = bread(gp->g_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,	(struct gnode *) NULL);	cgp = bp->b_un.b_cg;	if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC ||	    cgp->cg_cs.cs_nifree == 0) {		brelse(bp);		return (NULL);	}	cgp->cg_time = timepick->tv_sec;	if (gpref) {		gpref %= fs->fs_ipg;		if (isclr(cgp->cg_iused, gpref))			goto gotit;	}	start = cgp->cg_irotor / NBBY;	len = howmany(fs->fs_ipg - cgp->cg_irotor, NBBY);	loc = skpc(0xff, len, &cgp->cg_iused[start]);	if (loc == 0) {		len = start + 1;		start = 0;		loc = skpc(0xff, len, &cgp->cg_iused[0]);		if (loc == 0) {			printf("cg = %s, irotor = %d, fs = %s\n",			    cg, cgp->cg_irotor, fs->fs_fsmnt);			panic("ialloccg: map corrupted");			/* NOTREACHED */		}	}	i = start + len - loc;	map = cgp->cg_iused[i];	gpref = i * NBBY;	for (i = 1; i < (1 << NBBY); i <<= 1, gpref++) {		if ((map & i) == 0) {			cgp->cg_irotor = gpref;			goto gotit;		}	}	printf("fs = %s\n", fs->fs_fsmnt);	panic("ialloccg: block not in map");	/* NOTREACHED */gotit:	setbit(cgp->cg_iused, gpref);	cgp->cg_cs.cs_nifree--;	fs_lock(gp->g_mp);	fs->fs_cstotal.cs_nifree--;	fs->fs_cs(fs, cg).cs_nifree--;	gp->g_mp->m_flags |= M_MOD;	if ((mode & GFMT) == GFDIR) {		cgp->cg_cs.cs_ndir++;		fs->fs_cstotal.cs_ndir++;		fs->fs_cs(fs, cg).cs_ndir++;	}	fs_unlock(gp->g_mp);	if (gp->g_mp->m_flags & M_SYNC)		bwrite(bp);	else		bdwrite(bp);	return (cg * fs->fs_ipg + gpref);}/* * Free a block or fragment. * * The specified block or fragment is placed back in the * free map. If a fragment is deallocated, a possible  * block reassembly is checked. */free(gp, bno, size)	register struct gnode *gp;	register daddr_t bno;	off_t size;{	register struct fs *fs;	register struct cg *cgp;	register struct buf *bp;	int cg, blk, frags, bbase;	register int i;	fs = FS(gp);	if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0) {		printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n",		    gp->g_dev, fs->fs_bsize, size, fs->fs_fsmnt);		panic("free: bad size");	}	cg = dtog(fs, bno);	if (badblock(fs, bno)) {		printf("bad block %d, gno %d\n", bno, gp->g_number);		return;	}	bp = bread(gp->g_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,		   (struct gnode *) NULL);	cgp = bp->b_un.b_cg;	if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) {		brelse(bp);		return;	}	cgp->cg_time = timepick->tv_sec;	bno = dtogd(fs, bno);	if (size == fs->fs_bsize) {		if (isblock(fs, cgp->cg_free, fragstoblks(fs, bno))) {			printf("dev = 0x%x, block = %d, fs = %s\n",			    gp->g_dev, bno, fs->fs_fsmnt);			panic("free: freeing free block");		}		setblock(fs, cgp->cg_free, fragstoblks(fs, bno));		cgp->cg_cs.cs_nbfree++;		i = cbtocylno(fs, bno);		cgp->cg_b[i][cbtorpos(fs, bno)]++;		cgp->cg_btot[i]++;		fs_lock(gp->g_mp);		fs->fs_cstotal.cs_nbfree++;		fs->fs_cs(fs, cg).cs_nbfree++;		gp->g_mp->m_flags |= M_MOD;		fs_unlock(gp->g_mp);	} else {		bbase = bno - fragnum(fs, bno);		/*		 * decrement the counts associated with the old frags		 */		blk = blkmap(fs, cgp->cg_free, bbase);		fragacct(fs, blk, cgp->cg_frsum, -1);		/*		 * deallocate the fragment		 */		frags = numfrags(fs, size);		for (i = 0; i < frags; i++) {			if (isset(cgp->cg_free, bno + i)) {				printf("dev = 0x%x, block = %d, fs = %s\n",				    gp->g_dev, bno + i, fs->fs_fsmnt);				panic("free: freeing free frag");			}			setbit(cgp->cg_free, bno + i);		}		cgp->cg_cs.cs_nffree += i;		/*		 * add back in counts associated with the new frags		 */		blk = blkmap(fs, cgp->cg_free, bbase);		fragacct(fs, blk, cgp->cg_frsum, 1);		/*		 * Update superblock information. If a complete block		 * has been reassembled, account for it		 */		fs_lock(gp->g_mp);		fs->fs_cstotal.cs_nffree += i;		fs->fs_cs(fs, cg).cs_nffree += i;		if (isblock(fs, cgp->cg_free, fragstoblks(fs, bbase))) {			cgp->cg_cs.cs_nffree -= fs->fs_frag;			fs->fs_cstotal.cs_nffree -= fs->fs_frag;			fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag;			cgp->cg_cs.cs_nbfree++;			fs->fs_cstotal.cs_nbfree++;			fs->fs_cs(fs, cg).cs_nbfree++;			i = cbtocylno(fs, bbase);			cgp->cg_b[i][cbtorpos(fs, bbase)]++;			cgp->cg_btot[i]++;		}		gp->g_mp->m_flags |= M_MOD;		fs_unlock(gp->g_mp);	}	if (gp->g_mp->m_flags & M_SYNC)		bwrite(bp);	else		bdwrite(bp);}/* * Free a gnode. * * The specified gnode is placed back in the free map. */ufs_gfree(gp, gno, mode)	register struct gnode *gp;	register gno_t gno;	int mode;{	register struct fs *fs;	register struct cg *cgp;	register struct buf *bp;	register int cg;	fs = FS(gp);	if ((unsigned)gno >= fs->fs_ipg*fs->fs_ncg) {		printf("dev = 0x%x, gno = %d, fs = %s\n",		    gp->g_dev, gno, fs->fs_fsmnt);		panic("ufs_gfree: range");	}	cg = itog(fs, gno);	bp = bread(gp->g_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,		   (struct gnode *) NULL);	cgp = bp->b_un.b_cg;	if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) {		brelse(bp);		return;	}	cgp->cg_time = timepick->tv_sec;	gno %= fs->fs_ipg;	if (isclr(cgp->cg_iused, gno)) {		printf("dev = 0x%x, gno = %d, fs = %s block %d\n",		    gp->g_dev, gno, fs->fs_fsmnt, fsbtodb(fs, cgtod(fs, cg)));		panic("ufs_gfree: freeing free gnode");	}	clrbit(cgp->cg_iused, gno);	if (gno < cgp->cg_irotor)		cgp->cg_irotor = gno;	cgp->cg_cs.cs_nifree++;	fs_lock(gp->g_mp);	fs->fs_cstotal.cs_nifree++;	fs->fs_cs(fs, cg).cs_nifree++;	if ((mode & GFMT) == GFDIR) {		cgp->cg_cs.cs_ndir--;		fs->fs_cstotal.cs_ndir--;		fs->fs_cs(fs, cg).cs_ndir--;	}	gp->g_mp->m_flags |= M_MOD;	fs_unlock(gp->g_mp);	if (gp->g_mp->m_flags & M_SYNC)		bwrite(bp);	else		bdwrite(bp);}/* * Find a block of the specified size in the specified cylinder group. * * It is a panic if a request is made to find a block if none are * available. */daddr_tmapsearch(fs, cgp, bpref, allocsiz)	register struct fs *fs;	register struct cg *cgp;	daddr_t bpref;	int allocsiz;{	register daddr_t bno;	register int i;	register int field, subfield;	int start, len, loc;	int blk, pos;	/*	 * find the fragment by searching through the free block	 * map for an appropriate bit pattern	 */	if (bpref)		start = dtogd(fs, bpref) / NBBY;	else		start = cgp->cg_frotor / NBBY;	len = howmany(fs->fs_fpg, NBBY) - start;	loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[start],		(caddr_t)fragtbl[fs->fs_frag],		(int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));	if (loc == 0) {		len = start + 1;		start = 0;		loc = scanc((unsigned)len, (caddr_t)&cgp->cg_free[0],			(caddr_t)fragtbl[fs->fs_frag],			(int)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY))));		if (loc == 0) {			printf("start = %d, len = %d, fs = %s\n",			    start, len, fs->fs_fsmnt);			panic("alloccg: map corrupted");			/* NOTREACHED */		}	}	bno = (start + len - loc) * NBBY;	cgp->cg_frotor = bno;	/*	 * found the byte in the map	 * sift through the bits to find the selected frag	 */	for (i = bno + NBBY; bno < i; bno += fs->fs_frag) {		blk = blkmap(fs, cgp->cg_free, bno);		blk <<= 1;		field = around[allocsiz];		subfield = inside[allocsiz];		for (pos = 0; pos <= fs->fs_frag - allocsiz; pos++) {			if ((blk & field) == subfield)				return (bno + pos);			field <<= 1;			subfield <<= 1;		}	}	printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt);	panic("alloccg: block not in map");	return (-1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -