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

📄 icache.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 CC
字号:
#include <lib/root.h>#include <lib/ostream.h>#include <init/ctor.h>#include <lib/errno.h>#include <mm/allockm.h>#include <dev/blk/dev.h>#include "buf.h"#include "inode.h"#include "fs.h"static int hsize, hmask;typedef Q(hash,inode_t) hashq_t;static hashq_t * hashtab;static Q(all,inode_t) allq;static Q(free,inode_t) freeq;static int ninode;static inode_t * inodetab;static ino_t virtualino;static hashq_t * hashfunc(fs_t * fs, ino_t ino){	int base = (int) fs;	return hashtab + ((base+ino)&hmask);}void dumpi(ostream_t * os){	os->write("total inode number:%d ", ninode);	os->write("free inode number:%d ", freeq.count());	inode_t * i;	os->write("\nbusy inode(dev:ino:refcnt\n");	foreach (i, allq) {		if (i->refcnt != 0)			os->write("(%x:%d:%d)  ", i->dev, i->ino, i->refcnt);	}	os->write("\n");}__ctor(PRIFS, SUBANY, inodecache){	construct(&allq);	construct(&freeq);	hsize = min(256, roundup2p2(8 * nphysmeg));	hmask = hsize - 1;	hashtab = (hashq_t *) allocbm(hsize * sizeof(hashq_t));	construct(hashtab, hsize);	ninode = hsize;	inodetab = (inode_t *) allocbm(ninode * sizeof(inode_t));	construct(inodetab, ninode);	for (inode_t * i = inodetab, * end = inodetab + ninode; i < end; i++) {		i->nextall = i->prevall = NULL;		i->nexthash = i->prevhash = NULL;		i->nextfree = i->prevfree = NULL;		i->state = IINVAL;		i->flags = 0;		i->refcnt = 0;		i->fs = NULL;		i->dev = mkdev(NULLMAJOR, 0);		i->ino = virtualino++;		i->bsize = MINIXBSIZE;		i->bsizebits = 10;		i->peer = NULL;		i->unstsock = NULL;		allq.enqtail(i);		freeq.enqtail(i);		hashfunc(i->fs, i->ino)->enqtail(i);	}}inode_t * findi(fs_t * fs, ino_t ino){	inode_t * inode;	foreach (inode, *hashfunc(fs, ino)) {		if (inode->fs == fs && inode->ino == ino)			return inode;	}	return NULL;}static inode_t * geti(fs_t * fs, ino_t ino){	inode_t * inode;	int candidates = 8;repeat: if (inode = findi(fs, ino)) {		inode->hold();		inode->wait();		if (inode->nextfree)			freeq.unlink(inode);		return inode;	}	foreach (inode, freeq) {		if (inode->refcnt)			continue;		if (candidates > 0)			candidates--;		if (inode->locked()) {			if (candidates)				continue;			inode->wait();			goto repeat;		}		if (inode->state == IDIRTY) {			inode->write();			goto repeat;		}		/* !refcnt && !locked && state != BDIRTY */		inode->hold();		freeq.unlink(inode);		inode->state = IINVAL;		assert(!inode->flags);		inode->unlinkhash();		inode->fs = fs;		inode->dev = fs->dev;		inode->ino = ino;		inode->bsize = getbsize(fs->dev);		hashfunc(fs, ino)->enqhead(inode);		assert(!inode->peer);		assert(!inode->rwlock.locked());		return inode;	}	return NULL;}/* iget */int readi(fs_t * fs, ino_t ino, inode_t ** result){	int e;	if (!(*result = geti(fs, ino)))		return ENFILE;	if ((*result)->state != IINVAL)		return 0;	if (e = (*result)->read()) {		(*result)->lose();		(*result) = NULL;		return e;	}	return 0;}/* iput */void inode_t::lose(){	assert(findi(fs, ino));	assert(refcnt > 0);	if (--refcnt)		return;	if (!nextfree)			freeq.enqtail(this); /* make this inode as MRU */	if (state == IINVAL)		return;	if (nlink)		return;	truncate();	if (refcnt || nlink) {		warn("nonexistent inode is referenced\n");		return;	}	fs->freei(ino);	state = IINVAL;}int inode_t::read(){	int e;	buf_t * b;	minixdi_t * di;	lock();	if (state != IINVAL) {		unlock();		return 0;	}	if (e = fs->seeki(ino, &b, &di)) {		unlock();		return e;	}	mode = di->mode;	nlink = di->nlink;	uid = di->uid;	gid = di->gid;	size = di->size;	atime = di->atime;	mtime = di->mtime;	ctime = di->ctime;	for (int i = 0; i < MINIXNDADDR; i++)		daddr[i] = di->daddr[i];	b->lose();	state = ICLEAN;	unlock();	return 0;}int inode_t::write(){	int e;	buf_t * b;	minixdi_t * di;	lock();	if (state != IDIRTY) {		unlock();		return 0;	}	if (e = fs->seeki(ino, &b, &di)) {		unlock();		return e;	}	di->mode = mode;	di->nlink = nlink;	di->uid = uid; 	di->gid = gid;	di->size = size;	di->atime = atime; 	di->mtime = mtime;	di->ctime = ctime;	for (int i = 0; i < MINIXNDADDR; i++)		di->daddr[i] = daddr[i];	b->lose2();	state = ICLEAN;	unlock();	return 0;}void synci(){	inode_t * inode;	foreach (inode, allq) {		inode->hold();		inode->write();		inode->lose();	}}void synci(fs_t * fs){	inode_t * inode;	foreach (inode, allq) {		if (inode->fs != fs)			continue;		inode->hold();		inode->write();		inode->lose();	}}int tryumount(fs_t * fs){	inode_t * inode;	foreach (inode, allq) {		if (inode->fs != fs)			continue;		if (inode == fs->root) {			if (inode->refcnt != 1)				return EBUSY;		} else {			if (inode->refcnt != 0)				return EBUSY;		}	}	return 0;}void invali(fs_t *fs){	inode_t *inode;	foreach (inode, allq) {		if (inode->state == IINVAL || inode->fs != fs)			continue;		inode->state = IINVAL;	}}

⌨️ 快捷键说明

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