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

📄 subr.c

📁 著名的AT&T UNIX v6 源码
💻 C
字号:
#include "../h/param.h"#include "../h/systm.h"#include "../h/conf.h"#include "../h/inode.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/buf.h"/* * Bmap defines the structure of file system storage * by returning the physical block number on a device given the * inode and the logical block number in a file. * When convenient, it also leaves the physical * block number of the next block of the file in rablock * for use in read-ahead. */daddr_tbmap(ip, bn, rwflg)register struct inode *ip;daddr_t bn;{	register i;	struct buf *bp, *nbp;	int j, sh;	daddr_t nb, *bap;	dev_t dev;	if(bn < 0) {		u.u_error = EFBIG;		return((daddr_t)0);	}	dev = ip->i_dev;	rablock = 0;	/*	 * blocks 0..NADDR-4 are direct blocks	 */	if(bn < NADDR-3) {		i = bn;		nb = ip->i_un.i_addr[i];		if(nb == 0) {			if(rwflg==B_READ || (bp = alloc(dev))==NULL)				return((daddr_t)-1);			nb = bp->b_blkno;			bdwrite(bp);			ip->i_un.i_addr[i] = nb;			ip->i_flag |= IUPD|ICHG;		}		if(i < NADDR-4)			rablock = ip->i_un.i_addr[i+1];		return(nb);	}	/*	 * addresses NADDR-3, NADDR-2, and NADDR-1	 * have single, double, triple indirect blocks.	 * the first step is to determine	 * how many levels of indirection.	 */	sh = 0;	nb = 1;	bn -= NADDR-3;	for(j=3; j>0; j--) {		sh += NSHIFT;		nb <<= NSHIFT;		if(bn < nb)			break;		bn -= nb;	}	if(j == 0) {		u.u_error = EFBIG;		return((daddr_t)0);	}	/*	 * fetch the address from the inode	 */	nb = ip->i_un.i_addr[NADDR-j];	if(nb == 0) {		if(rwflg==B_READ || (bp = alloc(dev))==NULL)			return((daddr_t)-1);		nb = bp->b_blkno;		bdwrite(bp);		ip->i_un.i_addr[NADDR-j] = nb;		ip->i_flag |= IUPD|ICHG;	}	/*	 * fetch through the indirect blocks	 */	for(; j<=3; j++) {		bp = bread(dev, nb);		if(bp->b_flags & B_ERROR) {			brelse(bp);			return((daddr_t)0);		}		bap = bp->b_un.b_daddr;		sh -= NSHIFT;		i = (bn>>sh) & NMASK;		nb = bap[i];		if(nb == 0) {			if(rwflg==B_READ || (nbp = alloc(dev))==NULL) {				brelse(bp);				return((daddr_t)-1);			}			nb = nbp->b_blkno;			bdwrite(nbp);			bap[i] = nb;			bdwrite(bp);		} else			brelse(bp);	}	/*	 * calculate read-ahead.	 */	if(i < NINDIR-1)		rablock = bap[i+1];	return(nb);}/* * Pass back  c  to the user at his location u_base; * update u_base, u_count, and u_offset.  Return -1 * on the last character of the user's read. * u_base is in the user address space unless u_segflg is set. */passc(c)register c;{	register id;	if((id = u.u_segflg) == 1)		*u.u_base = c;	else		if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) {			u.u_error = EFAULT;			return(-1);		}	u.u_count--;	u.u_offset++;	u.u_base++;	return(u.u_count == 0? -1: 0);}/* * Pick up and return the next character from the user's * write call at location u_base; * update u_base, u_count, and u_offset.  Return -1 * when u_count is exhausted.  u_base is in the user's * address space unless u_segflg is set. */cpass(){	register c, id;	if(u.u_count == 0)		return(-1);	if((id = u.u_segflg) == 1)		c = *u.u_base;	else		if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) {			u.u_error = EFAULT;			return(-1);		}	u.u_count--;	u.u_offset++;	u.u_base++;	return(c&0377);}/* * Routine which sets a user error; placed in * illegal entries in the bdevsw and cdevsw tables. */nodev(){	u.u_error = ENODEV;}/* * Null routine; placed in insignificant entries * in the bdevsw and cdevsw tables. */nulldev(){}

⌨️ 快捷键说明

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