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

📄 dentry.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"all.h"Dentry*getdir(Iobuf *p, int slot){	Dentry *d;	if(!p)		return 0;	d = (Dentry*)p->iobuf + slot%DIRPERBUF;	return d;}voidaccessdir(Iobuf *p, Dentry *d, int f, int uid){	Timet t;	if(p && p->dev->type != Devro) {		p->flags |= Bmod;		t = time();		if(f & (FREAD|FWRITE))			d->atime = t;		if(f & FWRITE) {			d->mtime = t;			d->muid = uid;			d->qid.version++;		}	}}voidpreread(Device *d, Off addr){	Rabuf *rb;	if(addr == 0)		return;	if(raheadq->count+10 >= raheadq->size)	/* ugly knowing layout */		return;	lock(&rabuflock);	rb = rabuffree;	if(rb == 0) {		unlock(&rabuflock);		return;	}	rabuffree = rb->link;	unlock(&rabuflock);	rb->dev = d;	rb->addr = addr;	send(raheadq, rb);	cons.brahead[0].count++;	cons.brahead[1].count++;	cons.brahead[2].count++;}Offrel2abs(Iobuf *p, Dentry *d, Off a, int tag, int putb, int uid){	int i;	Off addr, qpath, indaddrs = 1, div;	Device *dev;	if(a < 0) {		print("rel2abs: neg offset\n");		if(putb)			putbuf(p);		return 0;	}	dev = p->dev;	qpath = d->qid.path;	/* is `a' a direct block? */	if(a < NDBLOCK) {		addr = d->dblock[a];		if(!addr && tag) {			addr = bufalloc(dev, tag, qpath, uid);			d->dblock[a] = addr;			p->flags |= Bmod|Bimm;		}		if(putb)			putbuf(p);		return addr;	}	a -= NDBLOCK;	/*	 * loop through indirect block depths.	 */	for (i = 0; i < NIBLOCK; i++) {		indaddrs *= INDPERBUF;		/* is a's disk addr in this indir block or one of its kids? */		if (a < indaddrs) {			addr = d->iblocks[i];			if(!addr && tag) {				addr = bufalloc(dev, Tind1+i, qpath, uid);				d->iblocks[i] = addr;				p->flags |= Bmod|Bimm;			}			if(putb)				putbuf(p);			div = indaddrs;			for (; i >= 0; i--) {				div /= INDPERBUF;				if (div <= 0)					panic("rel2abs: non-positive divisor");				addr = indfetch(dev, qpath, addr,					(a/div)%INDPERBUF, Tind1+i,					(i == 0? tag: Tind1+i-1), uid);			}			return addr;		}		a -= indaddrs;	}	if(putb)		putbuf(p);	/* quintuple-indirect blocks not implemented. */	print("rel2abs: no %d-deep indirect\n", NIBLOCK+1);	return 0;}/* * read-ahead strategy * on second block, read RAGAP blocks, * thereafter, read RAGAP ahead of current pos */Offdbufread(Iobuf *p, Dentry *d, Off a, Off ra, int uid){	Off addr;	if(a == 0)		return 1;	if(a == 1 && ra == 1) {		while(ra < a+RAGAP) {			ra++;			addr = rel2abs(p, d, ra, 0, 0, uid);			if(!addr)				return 0;			preread(p->dev, addr);		}		return ra+1;	}	if(ra == a+RAGAP) {		addr = rel2abs(p, d, ra, 0, 0, uid);		if(!addr)			return 0;		preread(p->dev, addr);		return ra+1;	}	return ra;}Iobuf*dnodebuf(Iobuf *p, Dentry *d, Off a, int tag, int uid){	Off addr;	addr = rel2abs(p, d, a, tag, 0, uid);	if(addr)		return getbuf(p->dev, addr, Bread);	return 0;}/* * same as dnodebuf but it calls putbuf(p) * to reduce interference. */Iobuf*dnodebuf1(Iobuf *p, Dentry *d, Off a, int tag, int uid){	Off addr;	Device *dev;	dev = p->dev;	addr = rel2abs(p, d, a, tag, 1, uid);	if(addr)		return getbuf(dev, addr, Bread);	return 0;}Offindfetch(Device* d, Off qpath, Off addr, Off a, int itag, int tag, int uid){	Iobuf *bp;	if(!addr)		return 0;	bp = getbuf(d, addr, Bread);	if(!bp || checktag(bp, itag, qpath)) {		if(!bp) {			print("ind fetch bp = 0\n");			return 0;		}		print("ind fetch tag\n");		putbuf(bp);		return 0;	}	addr = ((Off *)bp->iobuf)[a];	if(!addr && tag) {		addr = bufalloc(d, tag, qpath, uid);		if(addr) {			((Off *)bp->iobuf)[a] = addr;			bp->flags |= Bmod;			if(tag == Tdir)				bp->flags |= Bimm;			settag(bp, itag, qpath);		}	}	putbuf(bp);	return addr;}/* return INDPERBUF^exp */Offibbpow(int exp){	static Off pows[] = {		1,		INDPERBUF,		(Off)INDPERBUF*INDPERBUF,		(Off)INDPERBUF*(Off)INDPERBUF*INDPERBUF,		(Off)INDPERBUF*(Off)INDPERBUF*(Off)INDPERBUF*INDPERBUF,	};	if (exp < 0)		return 0;	else if (exp >= nelem(pows)) {	/* not in table? do it long-hand */		Off indpow = 1;		while (exp-- > 0)			indpow *= INDPERBUF;		return indpow;	} else		return pows[exp];}/* return sum of INDPERBUF^n for 1 ≤ n ≤ exp */Offibbpowsum(int exp){	Off indsum = 0;	for (; exp > 0; exp--)		indsum += ibbpow(exp);	return indsum;}/* zero bytes past new file length; return an error code */inttrunczero(Truncstate *ts){	int blkoff = ts->newsize % BUFSIZE;	Iobuf *pd;	pd = dnodebuf(ts->p, ts->d, ts->lastblk, Tfile, ts->uid);	if (pd == nil || checktag(pd, Tfile, QPNONE)) {		if (pd != nil)			putbuf(pd);		ts->err = Ephase;		return Ephase;	}	memset(pd->iobuf+blkoff, 0, BUFSIZE - blkoff);	putbuf(pd);	return 0;}/* * truncate d (in p) to length `newsize'. * if larger, just increase size. * if smaller, deallocate blocks after last one * still in file at new size.  last byte to keep * is newsize-1, due to zero origin. * we free in forward order because it's simpler to get right. * if the final block at the new size is partially-filled, * zero the remainder. */intdtrunclen(Iobuf *p, Dentry *d, Off newsize, int uid){	int i, pastlast;	Truncstate trunc;	if (newsize <= 0) {		dtrunc(p, d, uid);		return 0;	}	memset(&trunc, 0, sizeof trunc);	trunc.d = d;	trunc.p = p;	trunc.uid = uid;	trunc.newsize = newsize;	trunc.lastblk = newsize/BUFSIZE;	if (newsize % BUFSIZE == 0)		trunc.lastblk--;	else		trunczero(&trunc);	for (i = 0; i < NDBLOCK; i++)		if (trunc.pastlast) {			trunc.relblk = i;			buffree(p->dev, d->dblock[i], 0, &trunc);			d->dblock[i] = 0;		} else if (i == trunc.lastblk)			trunc.pastlast = 1;	trunc.relblk = NDBLOCK;	for (i = 0; i < NIBLOCK; i++) {		pastlast = trunc.pastlast;		buffree(p->dev, d->iblocks[i], i+1, &trunc);		if (pastlast)			d->iblocks[i] = 0;	}	d->size = newsize;	p->flags |= Bmod|Bimm;	accessdir(p, d, FWRITE, uid);	return trunc.err;}/* * truncate d (in p) to zero length. * freeing blocks in reverse order is traditional, from Unix, * in an attempt to keep the free list contiguous. */voiddtrunc(Iobuf *p, Dentry *d, int uid){	int i;	for (i = NIBLOCK-1; i >= 0; i--) {		buffree(p->dev, d->iblocks[i], i+1, nil);		d->iblocks[i] = 0;	}	for(i=NDBLOCK-1; i>=0; i--) {		buffree(p->dev, d->dblock[i], 0, nil);		d->dblock[i] = 0;	}	d->size = 0;	p->flags |= Bmod|Bimm;	accessdir(p, d, FWRITE, uid);}

⌨️ 快捷键说明

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