示例#1
0
文件: cache.c 项目: vrthra/9front-tmp
void
cnodata(Mntcache *m)
{
	Extent *e;

	/*
	 * Invalidate all extent data
	 * Image lru will waste the pages
	 */
	while(e = m->list){
		m->list = e->next;
		extentfree(e);
	}
}
示例#2
0
文件: cache.c 项目: 99years/plan9
void
cnodata(Mntcache *m)
{
	Extent *e, *n;

	/*
	 * Invalidate all extent data
	 * Image lru will waste the pages
	 */
	for(e = m->list; e; e = n) {
		n = e->next;
		extentfree(e);
	}
	m->list = 0;
}
示例#3
0
文件: cache.c 项目: 99years/plan9
void
cwrite(Chan* c, uchar *buf, int len, vlong off)
{
	int o, eo;
	Mntcache *m;
	ulong eblock, ee;
	Extent *p, *f, *e, *tail;
	ulong offset;

	if(off > maxcache || len == 0)
		return;

	m = c->mcp;
	if(m == 0)
		return;

	qlock(m);
	if(cdev(m, c) == 0) {
		qunlock(m);
		return;
	}

	offset = off;
	m->qid.vers++;
	c->qid.vers++;

	p = 0;
	for(f = m->list; f; f = f->next) {
		if(f->start >= offset)
			break;
		p = f;
	}

	if(p != 0) {
		ee = p->start+p->len;
		eo = offset - p->start;
		/* pack in predecessor if there is space */
		if(offset <= ee && eo < BY2PG) {
			o = len;
			if(o > BY2PG - eo)
				o = BY2PG - eo;
			if(cpgmove(p, buf, eo, o)) {
				if(eo+o > p->len)
					p->len = eo+o;
				buf += o;
				len -= o;
				offset += o;
			}
		}
	}

	/* free the overlap -- it's a rare case */
	eblock = offset+len;
	while(f && f->start < eblock) {
		e = f->next;
		extentfree(f);
		f = e;
	}

	/* link the block (if any) into the middle */
	e = cchain(buf, offset, len, &tail);
	if(e != 0) {
		tail->next = f;
		f = e;
	}

	if(p == 0)
		m->list = f;
	else
		p->next = f;
	qunlock(m);
}
示例#4
0
文件: cache.c 项目: 99years/plan9
Extent*
cchain(uchar *buf, ulong offset, int len, Extent **tail)
{
	int l;
	Page *p;
	KMap *k;
	Extent *e, *start, **t;

	start = 0;
	*tail = 0;
	t = &start;
	while(len) {
		e = extentalloc();
		if(e == 0)
			break;

		p = auxpage();
		if(p == 0) {
			extentfree(e);
			break;
		}
		l = len;
		if(l > BY2PG)
			l = BY2PG;

		e->cache = p;
		e->start = offset;
		e->len = l;

		qlock(&cache);
		e->bid = cache.pgno;
		cache.pgno += BY2PG;
		/* wrap the counter; low bits are unused by pghash but checked by lookpage */
		if((cache.pgno & ~(BY2PG-1)) == 0){
			if(cache.pgno == BY2PG-1){
				print("cache wrapped\n");
				cache.pgno = 0;
			}else
				cache.pgno++;
		}
		qunlock(&cache);

		p->daddr = e->bid;
		k = kmap(p);
		if(waserror()) {		/* buf may be virtual */
			kunmap(k);
			nexterror();
		}
		memmove((void*)VA(k), buf, l);
		poperror();
		kunmap(k);

		cachepage(p, &fscache);
		putpage(p);

		buf += l;
		offset += l;
		len -= l;

		*t = e;
		*tail = e;
		t = &e->next;
	}

	return start;
}
示例#5
0
文件: cache.c 项目: 99years/plan9
int
cread(Chan *c, uchar *buf, int len, vlong off)
{
	KMap *k;
	Page *p;
	Mntcache *m;
	Extent *e, **t;
	int o, l, total;
	ulong offset;

	if(off+len > maxcache)
		return 0;

	m = c->mcp;
	if(m == 0)
		return 0;

	qlock(m);
	if(cdev(m, c) == 0) {
		qunlock(m);
		return 0;
	}

	offset = off;
	t = &m->list;
	for(e = *t; e; e = e->next) {
		if(offset >= e->start && offset < e->start+e->len)
			break;
		t = &e->next;
	}

	if(e == 0) {
		qunlock(m);
		return 0;
	}

	total = 0;
	while(len) {
		p = cpage(e);
		if(p == 0) {
			*t = e->next;
			extentfree(e);
			qunlock(m);
			return total;
		}

		o = offset - e->start;
		l = len;
		if(l > e->len-o)
			l = e->len-o;

		k = kmap(p);
		if(waserror()) {
			kunmap(k);
			putpage(p);
			qunlock(m);
			nexterror();
		}

		memmove(buf, (uchar*)VA(k) + o, l);

		poperror();
		kunmap(k);

		putpage(p);

		buf += l;
		len -= l;
		offset += l;
		total += l;
		t = &e->next;
		e = e->next;
		if(e == 0 || e->start != offset)
			break;
	}

	qunlock(m);
	return total;
}
示例#6
0
文件: cache.c 项目: 99years/plan9
void
copen(Chan *c)
{
	int h;
	Extent *e, *next;
	Mntcache *m, *f, **l;

	/* directories aren't cacheable and append-only files confuse us */
	if(c->qid.type&(QTDIR|QTAPPEND))
		return;

	h = c->qid.path%NHASH;
	qlock(&cache);
	for(m = cache.hash[h]; m; m = m->hash) {
		if(m->qid.path == c->qid.path)
		if(m->qid.type == c->qid.type)
		if(m->dev == c->dev && m->type == c->type) {
			c->mcp = m;
			ctail(m);
			qunlock(&cache);

			/* File was updated, invalidate cache */
			if(m->qid.vers != c->qid.vers) {
				m->qid.vers = c->qid.vers;
				qlock(m);
				cnodata(m);
				qunlock(m);
			}
			return;
		}
	}

	/* LRU the cache headers */
	m = cache.head;
	l = &cache.hash[m->qid.path%NHASH];
	for(f = *l; f; f = f->hash) {
		if(f == m) {
			*l = m->hash;
			break;
		}
		l = &f->hash;
	}

	m->qid = c->qid;
	m->dev = c->dev;
	m->type = c->type;

	l = &cache.hash[h];
	m->hash = *l;
	*l = m;
	ctail(m);

	qlock(m);
	c->mcp = m;
	e = m->list;
	m->list = 0;
	qunlock(&cache);

	while(e) {
		next = e->next;
		extentfree(e);
		e = next;
	}
	qunlock(m);
}