plan 9 kernel history: overview | file list | diff list

1993/1014/port/cache.c (diff list | history)

1993/1011/sys/src/9/port/cache.c:6,311993/1013/sys/src/9/port/cache.c:6,274 (short | long)
1993/1011    
#include	"../port/error.h" 
#include	"devtab.h" 
 
typedef struct Fcache Fcache; 
typedef struct Fcalloc Fcalloc; 
struct Fcache 
1993/1013    
Image	fscache; 
 
typedef Extent Extent; 
struct Extent 
1993/1011    
{ 
	QLock; 
1993/1013    
	int	bid; 
	ulong	start; 
	int	len; 
	Extent	*next; 
}; 
 
typedef struct Mntcache Mntcache; 
struct Mntcache 
{ 
1993/1011    
	Qid; 
	Page*	alloc; 
	Fcache*	hash; 
	Fcache*	next; 
1993/1013    
	int	dev; 
	int	type; 
	Qlock; 
	Extent	 *list; 
	Mntcache *hash; 
	Mntcache *prev; 
	Mntcache *next; 
1993/1011    
}; 
 
struct Fcalloc 
1993/1013    
typedef struct Cache Cache; 
struct Cache 
1993/1011    
{ 
	ulong	start; 
	short	len; 
	Page*	data; 
1993/1013    
	Ref; 
	Mntcache	*head; 
	Mntcache	*tail; 
	Mntcache	*hash[NHASH]; 
1993/1011    
}; 
1993/1013    
Cache cache; 
1993/1011    
 
Fcache* 
clook(Qid *qid) 
1993/1013    
Mntcache* 
clook(Chan *c) 
1993/1011    
{ 
1993/1013    
	int h; 
1993/1011    
 
1993/1013    
	h = c->qid.path%NHASH; 
 
	lock(&cache); 
	for(m = cache.hash[h]; m; m = m->hash) { 
		if(m->path == c->path) { 
			qlock(m); 
			if(m->path == c->qid.path) 
			if(m->dev  == c->dev) 
			if(m->type == c->type) { 
				unlock(&cache); 
				return m; 
			} 
			qunlock(m); 
		} 
	} 
	unlock(&cache); 
	return 0; 
} 
 
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->list; 
		free(e); 
	} 
} 
 
void 
ctail(Mntcache *m) 
{ 
	lock(&cache); 
 
	/* Unlink and send to the tail */ 
	if(m->prev)  
		m->prev->next = m->next; 
	else 
		cache.head = m->next; 
	if(m->next) 
		m->next->prev = m->prev; 
	else 
		cache.tail = m->prev; 
 
	if(cache.tail) { 
		m->prev = cache.tail; 
		cache.tail->next = m; 
		m->next = 0; 
		cache.tail = m; 
	} 
	else { 
		cache.head = cache.tail = m; 
		m->prev = m->next = 0; 
	} 
 
	unlock(&cache); 
} 
 
void 
copen(Chan *c) 
{ 
	Mntcache *m, *f, **l; 
 
	m = clook(c); 
	if(m != 0) { 
		/* File was updated */ 
		if(m->vers != c->vers) 
			cnodata(m); 
 
		ctail(m); 
		qunlock(m); 
		return; 
	} 
 
	/* LRU the cache headers */ 
	m = cache.head; 
	qlock(m); 
	lock(cache); 
	l = &cache.hash[m->qid.path%NHASH]; 
	for(f = *l; f; f = f->next) { 
		if(f == m) { 
			*l = f->next; 
			break; 
		} 
		l = &f->next; 
	} 
	l = &cache.hash[c->qid.path%NHASH]; 
	m->hash = *l; 
	*l = m; 
	unlock(cache); 
	m->qid = c->qid; 
	m->dev = c->dev; 
	m->type = c->type; 
	cnodata(m); 
	ctail(m); 
	c->mcp = m; 
	qunlock(m); 
} 
 
static int 
cdev(Mntcache *m, Chan *c) 
{ 
	if(m->path != c->path) 
		return 0; 
	if(m->vers != c->vers) 
		return 0; 
	if(m->dev != c->dev) 
		return 0; 
	if(m->type != c->type) 
		return 0; 
	return 1; 
} 
 
int 
cread(Chan *c, uchar *buf, int len, long offset) 
{ 
	KMap *k; 
	Page *p; 
	Mntcache *m; 
	Extent *e, **l; 
	int o, l, total; 
 
	m = c->mcp; 
	if(m == 0) 
		return 0; 
	qlock(m); 
	if(cdev(m, c) == 0) { 
		qunlock(m); 
		return 0; 
	} 
 
	end = offset+len; 
	l = &m->list; 
	for(e = *l; e; e = e->next) { 
		if(e->start >= offset && e->start+e->len < end) 
			break; 
		l = &e->next; 
	} 
 
	if(e == 0) { 
		qunlock(m); 
		return 0; 
	} 
 
	total = 0; 
	while(len) { 
		p = lookpage(&fscache, e->bid); 
		if(p == 0) { 
			*l = e->next; 
			free(e); 
			qunlock(m); 
			return total; 
		} 
 
		k = kmap(p); 
		if(waserror()) { 
			kunmap(k); 
			putpage(p); 
			qunlock(m); 
			nexterror(); 
		} 
 
		o = offset - e->start; 
		l = len; 
		if(l > e->len-o) 
			l = e->len-o; 
 
		p = (uchar*)VA(k) + o; 
		memset(buf, p, l); 
		kunmap(k); 
		putpage(p); 
 
		buf += l; 
		len -= l; 
		offset += l; 
		total += l; 
		l = &e->next; 
		e = e->next; 
		if(e == 0 || e->start != offset) 
			break; 
	} 
	qunlock(m) 
	return total; 
} 
 
void 
cwrite(Chan *c, uchar *buf, int len, long offset) 
{ 
	Extent *e; 
	Mntcache *m; 
 
	if(offset > MAXCACHE) 
		return; 
 
	m = c->mcp; 
	if(m == 0) 
		return; 
	qlock(m); 
	if(cdev(m, c) == 0) { 
		qunlock(m); 
		return; 
	} 
 
	if(m->list == 0) { 
		e = malloc(sizeof(Extent)); 
		if(e == 0) 
			return; 
		e->start = offset; 
		l = len; 
		if(l > BY2PG) 
			l = BY2PG; 
		p = auxpage(); 
		if(p == 0) 
			return; 
		e->bid = incref(&cache); 
		p->daddr = e->bid; 
		cachepage(p, fscache); 
		k = kmap(p); 
		 
		kunmap(p); 
	} 
1993/1011    
} 
1993/1013/sys/src/9/port/cache.c:8,191993/1014/sys/src/9/port/cache.c:8,27 (short | long)
1993/1011    
 
1993/1013    
Image	fscache; 
 
typedef Extent Extent; 
1993/1014    
enum 
{ 
	NHASH		= 128, 
	MAXCACHE	= 1024*1024, 
	NFILE		= 4096, 
}; 
 
typedef struct Extent Extent; 
1993/1013    
struct Extent 
1993/1011    
{ 
1993/1013    
	int	bid; 
	ulong	start; 
	int	len; 
1993/1014    
	Page	*cache; 
1993/1013    
	Extent	*next; 
}; 
 
1993/1013/sys/src/9/port/cache.c:23,291993/1014/sys/src/9/port/cache.c:31,37
1993/1011    
	Qid; 
1993/1013    
	int	dev; 
	int	type; 
	Qlock; 
1993/1014    
	QLock; 
1993/1013    
	Extent	 *list; 
	Mntcache *hash; 
	Mntcache *prev; 
1993/1013/sys/src/9/port/cache.c:40,551993/1014/sys/src/9/port/cache.c:48,85
1993/1011    
}; 
1993/1013    
Cache cache; 
1993/1011    
 
1993/1014    
void 
cinit(void) 
{ 
	int i; 
	Mntcache *m; 
 
	cache.ref = 1; 
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
	 
	for(i = NFILE; i > 0; i++) { 
		m->next = m+1; 
		m->prev = m-1; 
		m++; 
	} 
 
	cache.tail = m; 
	cache.tail->next = 0; 
	cache.head->prev = 0; 
} 
 
1993/1013    
Mntcache* 
clook(Chan *c) 
1993/1011    
{ 
1993/1013    
	int h; 
1993/1014    
	Mntcache *m; 
1993/1011    
 
1993/1013    
	h = c->qid.path%NHASH; 
 
	lock(&cache); 
	for(m = cache.hash[h]; m; m = m->hash) { 
		if(m->path == c->path) { 
1993/1014    
		if(m->path == c->qid.path) { 
1993/1013    
			qlock(m); 
			if(m->path == c->qid.path) 
			if(m->dev  == c->dev) 
1993/1013/sys/src/9/port/cache.c:65,701993/1014/sys/src/9/port/cache.c:95,122
1993/1013    
} 
 
void 
1993/1014    
cprint(Mntcache *m) 
{ 
	Extent *e; 
 
	print("%lux.%lux %d %d\n", m->path, m->vers, m->type, m->dev); 
 
	while(e) 
		print("\t%4d %5d %4d %lux\n", 
			e->bid, e->start, e->len, e->cache); 
} 
 
Page* 
cpage(Extent *e) 
{ 
	/* Easy consistency check */ 
	if(e->cache->daddr != e->bid) 
		return 0; 
 
	return lookpage(&fscache, e->bid); 
} 
 
void 
1993/1013    
cnodata(Mntcache *m) 
{ 
	Extent *e, *n; 
1993/1013/sys/src/9/port/cache.c:74,801993/1014/sys/src/9/port/cache.c:126,132
1993/1013    
	 * Image lru will waste the pages 
	 */ 
	for(e = m->list; e; e = n) { 
		n = e->list; 
1993/1014    
		n = e->next; 
1993/1013    
		free(e); 
	} 
} 
1993/1013/sys/src/9/port/cache.c:116,1221993/1014/sys/src/9/port/cache.c:168,174
1993/1013    
	m = clook(c); 
	if(m != 0) { 
		/* File was updated */ 
		if(m->vers != c->vers) 
1993/1014    
		if(m->vers != c->qid.vers) 
1993/1013    
			cnodata(m); 
 
		ctail(m); 
1993/1013/sys/src/9/port/cache.c:127,1341993/1014/sys/src/9/port/cache.c:179,186
1993/1013    
	/* LRU the cache headers */ 
	m = cache.head; 
	qlock(m); 
	lock(cache); 
	l = &cache.hash[m->qid.path%NHASH]; 
1993/1014    
	lock(&cache); 
	l = &cache.hash[m->path%NHASH]; 
1993/1013    
	for(f = *l; f; f = f->next) { 
		if(f == m) { 
			*l = f->next; 
1993/1013/sys/src/9/port/cache.c:139,1461993/1014/sys/src/9/port/cache.c:191,198
1993/1013    
	l = &cache.hash[c->qid.path%NHASH]; 
	m->hash = *l; 
	*l = m; 
	unlock(cache); 
	m->qid = c->qid; 
1993/1014    
	unlock(&cache); 
	m->Qid = c->qid; 
1993/1013    
	m->dev = c->dev; 
	m->type = c->type; 
	cnodata(m); 
1993/1013/sys/src/9/port/cache.c:152,1601993/1014/sys/src/9/port/cache.c:204,212
1993/1013    
static int 
cdev(Mntcache *m, Chan *c) 
{ 
	if(m->path != c->path) 
1993/1014    
	if(m->path != c->qid.path) 
1993/1013    
		return 0; 
	if(m->vers != c->vers) 
1993/1014    
	if(m->vers != c->qid.vers) 
1993/1013    
		return 0; 
	if(m->dev != c->dev) 
		return 0; 
1993/1013/sys/src/9/port/cache.c:164,1761993/1014/sys/src/9/port/cache.c:216,228
1993/1013    
} 
 
int 
cread(Chan *c, uchar *buf, int len, long offset) 
1993/1014    
cread(Chan *c, uchar *buf, int len, ulong offset) 
1993/1013    
{ 
	KMap *k; 
	Page *p; 
	Mntcache *m; 
	Extent *e, **l; 
	int o, l, total; 
1993/1014    
	Extent *e, **t; 
	int o, l, total, end; 
1993/1013    
 
	m = c->mcp; 
	if(m == 0) 
1993/1013/sys/src/9/port/cache.c:182,1921993/1014/sys/src/9/port/cache.c:234,244
1993/1013    
	} 
 
	end = offset+len; 
	l = &m->list; 
	for(e = *l; e; e = e->next) { 
1993/1014    
	t = &m->list; 
	for(e = *t; e; e = e->next) { 
1993/1013    
		if(e->start >= offset && e->start+e->len < end) 
			break; 
		l = &e->next; 
1993/1014    
		t = &e->next; 
1993/1013    
	} 
 
	if(e == 0) { 
1993/1013/sys/src/9/port/cache.c:196,2041993/1014/sys/src/9/port/cache.c:248,256
1993/1013    
 
	total = 0; 
	while(len) { 
		p = lookpage(&fscache, e->bid); 
1993/1014    
		p = cpage(e); 
1993/1013    
		if(p == 0) { 
			*l = e->next; 
1993/1014    
			*t = e->next; 
1993/1013    
			free(e); 
			qunlock(m); 
			return total; 
1993/1013/sys/src/9/port/cache.c:217,2241993/1014/sys/src/9/port/cache.c:269,275
1993/1013    
		if(l > e->len-o) 
			l = e->len-o; 
 
		p = (uchar*)VA(k) + o; 
		memset(buf, p, l); 
1993/1014    
		memmove(buf, (uchar*)VA(k) + o, l); 
1993/1013    
		kunmap(k); 
		putpage(p); 
 
1993/1013/sys/src/9/port/cache.c:226,2451993/1014/sys/src/9/port/cache.c:277,361
1993/1013    
		len -= l; 
		offset += l; 
		total += l; 
		l = &e->next; 
1993/1014    
		t = &e->next; 
1993/1013    
		e = e->next; 
		if(e == 0 || e->start != offset) 
			break; 
	} 
	qunlock(m) 
1993/1014    
	qunlock(m); 
1993/1013    
	return total; 
} 
 
1993/1014    
Extent* 
cchain(uchar *buf, ulong offset, int len, Extent **tail) 
{ 
	int l; 
	Page *p; 
	KMap *k; 
	Extent *e, *start, **t; 
 
	start = 0; 
	t = &start; 
	while(len) { 
		e = malloc(sizeof(Extent)); 
		if(e == 0) 
			break; 
 
		p = auxpage(); 
		if(p == 0) { 
			free(e); 
			break; 
		} 
		e->cache = p; 
		e->start = offset; 
		l = len; 
		if(l > BY2PG) 
			l = BY2PG; 
 
		e->bid = incref(&cache); 
		p->daddr = e->bid; 
		k = kmap(p); 
		memmove((void*)VA(k), buf, l); 
		kunmap(k); 
 
		cachepage(p, &fscache); 
		putpage(p); 
 
		buf += l; 
		offset += l; 
		len -= l; 
 
		*t = e; 
		*tail = e; 
		t = &e->next; 
	} 
	return start; 
} 
 
int 
cpgmove(Extent *e, uchar *buf, int boff, int len) 
{ 
	Page *p; 
	KMap *k; 
 
	p = cpage(e); 
	if(p == 0) 
		return 0; 
	k = kmap(p); 
	memmove((uchar*)VA(k)+boff, buf, len); 
	kunmap(k); 
	putpage(p); 
 
	return 1; 
} 
 
1993/1013    
void 
cwrite(Chan *c, uchar *buf, int len, long offset) 
1993/1014    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
1993/1013    
{ 
	Extent *e; 
	Mntcache *m; 
1993/1014    
	Extent *tail; 
	Extent *e, *f, *p; 
	int o, ee, eblock;  
1993/1013    
 
	if(offset > MAXCACHE) 
		return; 
1993/1013/sys/src/9/port/cache.c:253,2741993/1014/sys/src/9/port/cache.c:369,459
1993/1013    
		return; 
	} 
 
	if(m->list == 0) { 
		e = malloc(sizeof(Extent)); 
		if(e == 0) 
1993/1014    
	/* 
	 * Find the insertion point 
	 */ 
	p = 0; 
	for(f = m->list; f; f = f->next) { 
		if(f->start >= offset) 
			break; 
		p = f; 
	} 
	if(p == 0) {		/* at the head */ 
		eblock = offset+len; 
		/* trim if there is a successor */ 
		if(f != 0 && eblock >= f->start) { 
			len -= (eblock - f->start); 
			if(len <= 0) { 
				qunlock(m); 
				return; 
			} 
		} 
		e = cchain(buf, offset, len, &tail); 
		m->list = e; 
		if(tail != 0) 
			tail->next = f; 
		qunlock(m); 
		return; 
	} 
 
	/* trim to the predecessor */ 
	ee = p->start+p->len; 
	if(offset < ee) { 
		o = ee - offset; 
		len -= o; 
		if(len <= 0) { 
			qunlock(m); 
1993/1013    
			return; 
		e->start = offset; 
		l = len; 
		if(l > BY2PG) 
			l = BY2PG; 
		p = auxpage(); 
		if(p == 0) 
1993/1014    
		} 
		buf += o; 
		offset += o; 
	} 
 
	/* try and pack data into the predecessor */ 
	if(offset == ee && p->len < BY2PG) { 
		o = len; 
		if(o > BY2PG - p->len) 
			o = BY2PG - p->len; 
		if(len <= 0) { 
			qunlock(m); 
1993/1013    
			return; 
		e->bid = incref(&cache); 
		p->daddr = e->bid; 
		cachepage(p, fscache); 
		k = kmap(p); 
		                 
		kunmap(p); 
1993/1014    
		} 
		if(cpgmove(e, buf, p->len, o)) { 
			e->len += o; 
			buf += o; 
			len -= o; 
			offset += o; 
			if(len <= 0) { 
				qunlock(m); 
				return; 
			} 
		} 
1993/1013    
	} 
1993/1014    
 
	/* append to extent list */ 
	if(f == 0) { 
		p->next = cchain(buf, offset, len, &tail); 
		qunlock(m); 
		return; 
	} 
 
	/* trim data against successor */ 
	eblock = offset+len; 
	if(eblock > f->start) { 
		o = eblock - f->start; 
		if(o < 0) { 
			qunlock(m); 
			return; 
		} 
		len -= o; 
	} 
 
	/* Insert a middle block */ 
	p->next = cchain(buf, offset, len, &tail); 
	if(p->next == 0) 
		p->next = f; 
	else 
		tail->next = f; 
 
	qunlock(m); 
1993/1011    
} 
1993/1014/sys/src/9/port/cache.c:58,641993/1015/sys/src/9/port/cache.c:58,64 (short | long)
1993/1014    
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
	 
	for(i = NFILE; i > 0; i++) { 
1993/1015    
	for(i = 0; i < NFILE; i++) { 
1993/1014    
		m->next = m+1; 
		m->prev = m-1; 
		m++; 
1993/1014/sys/src/9/port/cache.c:95,1071993/1015/sys/src/9/port/cache.c:95,108
1993/1013    
} 
 
void 
1993/1014    
cprint(Mntcache *m) 
1993/1015    
cprint(Mntcache *m, char *s) 
1993/1014    
{ 
	Extent *e; 
1993/1015    
return; 
	print("%s: 0x%lux.0x%lux %d %d\n", 
			s, m->path, m->vers, m->type, m->dev); 
1993/1014    
 
	print("%lux.%lux %d %d\n", m->path, m->vers, m->type, m->dev); 
                 
	while(e) 
1993/1015    
	for(e = m->list; e; e = e->next) 
1993/1014    
		print("\t%4d %5d %4d %lux\n", 
			e->bid, e->start, e->len, e->cache); 
} 
1993/1014/sys/src/9/port/cache.c:129,1401993/1015/sys/src/9/port/cache.c:130,143
1993/1014    
		n = e->next; 
1993/1013    
		free(e); 
	} 
1993/1015    
	m->list = 0; 
1993/1013    
} 
 
void 
ctail(Mntcache *m) 
1993/1015    
ctail(Mntcache *m, int dolock) 
1993/1013    
{ 
	lock(&cache); 
1993/1015    
	if(dolock) 
		lock(&cache); 
1993/1013    
 
	/* Unlink and send to the tail */ 
	if(m->prev)  
1993/1014/sys/src/9/port/cache.c:157,1631993/1015/sys/src/9/port/cache.c:160,167
1993/1013    
		m->prev = m->next = 0; 
	} 
 
	unlock(&cache); 
1993/1015    
	if(dolock) 
		unlock(&cache); 
1993/1013    
} 
 
void 
1993/1014/sys/src/9/port/cache.c:165,1781993/1015/sys/src/9/port/cache.c:169,190
1993/1013    
{ 
	Mntcache *m, *f, **l; 
 
1993/1015    
	if(c->qid.path & CHDIR) 
		return; 
 
1993/1013    
	m = clook(c); 
	if(m != 0) { 
1993/1015    
		c->mcp = m; 
		ctail(m, 1); 
 
1993/1013    
		/* File was updated */ 
1993/1014    
		if(m->vers != c->qid.vers) 
1993/1015    
		if(m->vers != c->qid.vers) { 
cprint(m, "copen mod"); 
1993/1013    
			cnodata(m); 
                 
		ctail(m); 
1993/1015    
			m->vers = c->qid.vers; 
		} 
1993/1013    
		qunlock(m); 
1993/1015    
cprint(m, "copen lru"); 
1993/1013    
		return; 
	} 
 
1993/1014/sys/src/9/port/cache.c:191,2041993/1015/sys/src/9/port/cache.c:203,218
1993/1013    
	l = &cache.hash[c->qid.path%NHASH]; 
	m->hash = *l; 
	*l = m; 
1993/1015    
	ctail(m, 0); 
1993/1014    
	unlock(&cache); 
1993/1015    
 
1993/1014    
	m->Qid = c->qid; 
1993/1013    
	m->dev = c->dev; 
	m->type = c->type; 
	cnodata(m); 
	ctail(m); 
	c->mcp = m; 
	qunlock(m); 
1993/1015    
cprint(m, "copen new"); 
1993/1013    
} 
 
static int 
1993/1014/sys/src/9/port/cache.c:224,2321993/1015/sys/src/9/port/cache.c:238,250
1993/1014    
	Extent *e, **t; 
	int o, l, total, end; 
1993/1013    
 
1993/1015    
	if(c->qid.path & CHDIR) 
		return 0; 
 
1993/1013    
	m = c->mcp; 
	if(m == 0) 
		return 0; 
1993/1015    
 
1993/1013    
	qlock(m); 
	if(cdev(m, c) == 0) { 
		qunlock(m); 
1993/1014/sys/src/9/port/cache.c:306,3171993/1015/sys/src/9/port/cache.c:324,336
1993/1014    
			free(e); 
			break; 
		} 
		e->cache = p; 
		e->start = offset; 
		l = len; 
		if(l > BY2PG) 
			l = BY2PG; 
 
1993/1015    
		e->cache = p; 
		e->start = offset; 
		e->len = l; 
1993/1014    
		e->bid = incref(&cache); 
		p->daddr = e->bid; 
		k = kmap(p); 
1993/1014/sys/src/9/port/cache.c:341,3461993/1015/sys/src/9/port/cache.c:360,366
1993/1014    
	p = cpage(e); 
	if(p == 0) 
		return 0; 
1993/1015    
 
1993/1014    
	k = kmap(p); 
	memmove((uchar*)VA(k)+boff, buf, len); 
	kunmap(k); 
1993/1014/sys/src/9/port/cache.c:355,3651993/1015/sys/src/9/port/cache.c:375,388
1993/1013    
	Mntcache *m; 
1993/1014    
	Extent *tail; 
	Extent *e, *f, *p; 
	int o, ee, eblock;  
1993/1015    
	int o, ee, eblock; 
1993/1013    
 
	if(offset > MAXCACHE) 
1993/1015    
	if(c->qid.path & CHDIR) 
1993/1013    
		return; 
 
1993/1015    
	if(offset > MAXCACHE || len == 0) 
		return; 
 
1993/1013    
	m = c->mcp; 
	if(m == 0) 
		return; 
1993/1014/sys/src/9/port/cache.c:378,3831993/1015/sys/src/9/port/cache.c:401,407
1993/1014    
			break; 
		p = f; 
	} 
1993/1015    
 
1993/1014    
	if(p == 0) {		/* at the head */ 
		eblock = offset+len; 
		/* trim if there is a successor */ 
1993/1014/sys/src/9/port/cache.c:418,4251993/1015/sys/src/9/port/cache.c:442,449
1993/1014    
			qunlock(m); 
1993/1013    
			return; 
1993/1014    
		} 
		if(cpgmove(e, buf, p->len, o)) { 
			e->len += o; 
1993/1015    
		if(cpgmove(p, buf, p->len, o)) { 
			p->len += o; 
1993/1014    
			buf += o; 
			len -= o; 
			offset += o; 
1993/1014/sys/src/9/port/cache.c:448,4541993/1015/sys/src/9/port/cache.c:472,478
1993/1014    
		len -= o; 
	} 
 
	/* Insert a middle block */ 
1993/1015    
	/* insert a middle block */ 
1993/1014    
	p->next = cchain(buf, offset, len, &tail); 
	if(p->next == 0) 
		p->next = f; 
1993/1014/sys/src/9/port/cache.c:456,4591993/1015/sys/src/9/port/cache.c:480,542
1993/1014    
		tail->next = f; 
 
	qunlock(m); 
1993/1015    
} 
 
void 
cwrite(Chan* c, uchar *buf, int len, ulong offset) 
{ 
	int o; 
	Mntcache *m; 
	ulong eblock, ee; 
	Extent *p, *f, *e, *tail; 
 
	if(offset > MAXCACHE || len == 0) 
		return; 
 
	m = c->mcp; 
	if(m == 0) 
		return; 
 
	qlock(m); 
	if(cdev(m, c) == 0) { 
		qunlock(m); 
		return; 
	} 
 
	m->vers++; 
 
	p = 0; 
	for(f = m->list; f; f = f->next) { 
		if(offset >= f->start) 
			break; 
		p = f;		 
	} 
 
	if(p != 0) { 
		ee = p->start+p->len; 
		if(ee > offset) { 
			o = ee - offset; 
			p->len -= o; 
			if(p->len) 
				panic("del empty extent"); 
		} 
	} 
 
	eblock = offset+len; 
	/* free the overlap - its a rare case */ 
	while(f && f->start < eblock) { 
		e = f->next; 
		free(f); 
		f = e; 
	} 
 
	e = cchain(buf, offset, len, &tail); 
	if(p == 0) 
		m->list = e; 
	else 
		p->next = e; 
	if(tail != 0) 
		tail->next = f; 
	qunlock(m); 
cprint(m, "cwrite"); 
1993/1011    
} 
1993/1015/sys/src/9/port/cache.c:58,641993/1016/sys/src/9/port/cache.c:58,64 (short | long)
1993/1014    
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
	 
1993/1015    
	for(i = 0; i < NFILE; i++) { 
1993/1016    
	for(i = 0; i < NFILE-1; i++) { 
1993/1014    
		m->next = m+1; 
		m->prev = m-1; 
		m++; 
1993/1015/sys/src/9/port/cache.c:69,1041993/1016/sys/src/9/port/cache.c:69,79
1993/1014    
	cache.head->prev = 0; 
} 
 
1993/1013    
Mntcache* 
clook(Chan *c) 
1993/1011    
{ 
1993/1013    
	int h; 
1993/1014    
	Mntcache *m; 
1993/1011    
                 
1993/1013    
	h = c->qid.path%NHASH; 
                 
	lock(&cache); 
	for(m = cache.hash[h]; m; m = m->hash) { 
1993/1014    
		if(m->path == c->qid.path) { 
1993/1013    
			qlock(m); 
			if(m->path == c->qid.path) 
			if(m->dev  == c->dev) 
			if(m->type == c->type) { 
				unlock(&cache); 
				return m; 
			} 
			qunlock(m); 
		} 
	} 
	unlock(&cache); 
	return 0; 
} 
                 
void 
1993/1015    
cprint(Mntcache *m, char *s) 
1993/1014    
{ 
	Extent *e; 
1993/1015    
return; 
1993/1016    
 
1993/1015    
	print("%s: 0x%lux.0x%lux %d %d\n", 
			s, m->path, m->vers, m->type, m->dev); 
1993/1014    
 
1993/1015/sys/src/9/port/cache.c:134,1441993/1016/sys/src/9/port/cache.c:109,116
1993/1013    
} 
 
void 
1993/1015    
ctail(Mntcache *m, int dolock) 
1993/1016    
ctail(Mntcache *m) 
1993/1013    
{ 
1993/1015    
	if(dolock) 
		lock(&cache); 
1993/1013    
                 
	/* Unlink and send to the tail */ 
	if(m->prev)  
		m->prev->next = m->next; 
1993/1015/sys/src/9/port/cache.c:159,1671993/1016/sys/src/9/port/cache.c:131,136
1993/1013    
		cache.head = cache.tail = m; 
		m->prev = m->next = 0; 
	} 
                 
1993/1015    
	if(dolock) 
		unlock(&cache); 
1993/1013    
} 
 
void 
1993/1015/sys/src/9/port/cache.c:172,2181993/1016/sys/src/9/port/cache.c:141,189
1993/1015    
	if(c->qid.path & CHDIR) 
		return; 
 
1993/1013    
	m = clook(c); 
	if(m != 0) { 
1993/1015    
		c->mcp = m; 
		ctail(m, 1); 
1993/1016    
	lock(&cache); 
	for(m = cache.hash[c->qid.path%NHASH]; m; m = m->hash) { 
		if(m->path == c->qid.path) 
		if(m->dev == c->dev && m->type == c->type) { 
			c->mcp = m; 
			ctail(m); 
			unlock(&cache); 
1993/1015    
 
1993/1013    
		/* File was updated */ 
1993/1015    
		if(m->vers != c->qid.vers) { 
cprint(m, "copen mod"); 
1993/1013    
			cnodata(m); 
1993/1015    
			m->vers = c->qid.vers; 
1993/1016    
			/* File was updated, invalidate cache */ 
			if(m->vers != c->qid.vers) { 
				qlock(m); 
				cnodata(m); 
				m->vers = c->qid.vers; 
				qunlock(m); 
			} 
			return; 
1993/1015    
		} 
1993/1013    
		qunlock(m); 
1993/1015    
cprint(m, "copen lru"); 
1993/1013    
		return; 
	} 
 
	/* LRU the cache headers */ 
	m = cache.head; 
	qlock(m); 
1993/1014    
	lock(&cache); 
	l = &cache.hash[m->path%NHASH]; 
1993/1013    
	for(f = *l; f; f = f->next) { 
1993/1016    
	for(f = *l; f; f = f->hash) { 
1993/1013    
		if(f == m) { 
			*l = f->next; 
1993/1016    
			*l = f->hash; 
1993/1013    
			break; 
		} 
		l = &f->next; 
1993/1016    
		l = &f->hash; 
1993/1013    
	} 
	l = &cache.hash[c->qid.path%NHASH]; 
	m->hash = *l; 
	*l = m; 
1993/1015    
	ctail(m, 0); 
1993/1014    
	unlock(&cache); 
1993/1016    
	ctail(m); 
1993/1015    
 
1993/1014    
	m->Qid = c->qid; 
1993/1013    
	m->dev = c->dev; 
	m->type = c->type; 
	cnodata(m); 
	c->mcp = m; 
1993/1016    
	unlock(&cache); 
 
	qlock(m); 
	cnodata(m); 
1993/1013    
	qunlock(m); 
1993/1015    
cprint(m, "copen new"); 
1993/1013    
} 
 
static int 
1993/1015/sys/src/9/port/cache.c:254,2611993/1016/sys/src/9/port/cache.c:225,236
1993/1013    
	end = offset+len; 
1993/1014    
	t = &m->list; 
	for(e = *t; e; e = e->next) { 
1993/1013    
		if(e->start >= offset && e->start+e->len < end) 
1993/1016    
		if(offset > e->start && offset < e->start+e->len) 
1993/1013    
			break; 
1993/1016    
		if(offset < e->start) { 
			qunlock(m); 
			return 0; 
		}	 
1993/1014    
		t = &e->next; 
1993/1013    
	} 
 
1993/1015/sys/src/9/port/cache.c:288,2931993/1016/sys/src/9/port/cache.c:263,270
1993/1013    
			l = e->len-o; 
 
1993/1014    
		memmove(buf, (uchar*)VA(k) + o, l); 
1993/1016    
 
		poperror(); 
1993/1013    
		kunmap(k); 
		putpage(p); 
 
1993/1015/sys/src/9/port/cache.c:313,3181993/1016/sys/src/9/port/cache.c:290,296
1993/1014    
	Extent *e, *start, **t; 
 
	start = 0; 
1993/1016    
	*tail = 0; 
1993/1014    
	t = &start; 
	while(len) { 
		e = malloc(sizeof(Extent)); 
1993/1015/sys/src/9/port/cache.c:348,3531993/1016/sys/src/9/port/cache.c:326,332
1993/1014    
		*tail = e; 
		t = &e->next; 
	} 
1993/1016    
 
1993/1014    
	return start; 
} 
 
1993/1015/sys/src/9/port/cache.c:370,3761993/1016/sys/src/9/port/cache.c:349,355
1993/1014    
} 
 
1993/1013    
void 
1993/1014    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
1993/1016    
cxupdate(Chan *c, uchar *buf, int len, ulong offset) 
1993/1013    
{ 
	Mntcache *m; 
1993/1014    
	Extent *tail; 
1993/1015/sys/src/9/port/cache.c:377,3851993/1016/sys/src/9/port/cache.c:356,361
1993/1014    
	Extent *e, *f, *p; 
1993/1015    
	int o, ee, eblock; 
1993/1013    
 
1993/1015    
	if(c->qid.path & CHDIR) 
1993/1013    
		return; 
                 
1993/1015    
	if(offset > MAXCACHE || len == 0) 
		return; 
 
1993/1015/sys/src/9/port/cache.c:413,4211993/1016/sys/src/9/port/cache.c:389,399
1993/1014    
			} 
		} 
		e = cchain(buf, offset, len, &tail); 
		m->list = e; 
		if(tail != 0) 
			tail->next = f; 
1993/1016    
		if(e != 0) { 
			m->list = e; 
			if(tail != 0) 
				tail->next = f; 
		} 
1993/1014    
		qunlock(m); 
		return; 
	} 
1993/1015/sys/src/9/port/cache.c:438,4471993/1016/sys/src/9/port/cache.c:416,421
1993/1014    
		o = len; 
		if(o > BY2PG - p->len) 
			o = BY2PG - p->len; 
		if(len <= 0) { 
			qunlock(m); 
1993/1013    
			return; 
1993/1014    
		} 
1993/1015    
		if(cpgmove(p, buf, p->len, o)) { 
			p->len += o; 
1993/1014    
			buf += o; 
1993/1015/sys/src/9/port/cache.c:465,4751993/1016/sys/src/9/port/cache.c:439,449
1993/1014    
	eblock = offset+len; 
	if(eblock > f->start) { 
		o = eblock - f->start; 
		if(o < 0) { 
1993/1016    
		len -= o; 
		if(len <= 0) { 
1993/1014    
			qunlock(m); 
			return; 
		} 
		len -= o; 
	} 
 
1993/1015    
	/* insert a middle block */ 
1993/1015/sys/src/9/port/cache.c:483,4881993/1016/sys/src/9/port/cache.c:457,469
1993/1015    
} 
 
void 
1993/1016    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
{ 
	cxupdate(c, buf, len, offset); 
	cprint(c->mcp, "cupdate"); 
} 
 
void 
1993/1015    
cwrite(Chan* c, uchar *buf, int len, ulong offset) 
{ 
	int o; 
1993/1015/sys/src/9/port/cache.c:517,5231993/1016/sys/src/9/port/cache.c:498,504
1993/1015    
		if(ee > offset) { 
			o = ee - offset; 
			p->len -= o; 
			if(p->len) 
1993/1016    
			if(p->len == 0) 
1993/1015    
				panic("del empty extent"); 
		} 
	} 
1993/1015/sys/src/9/port/cache.c:531,5421993/1016/sys/src/9/port/cache.c:512,525
1993/1015    
	} 
 
	e = cchain(buf, offset, len, &tail); 
	if(p == 0) 
		m->list = e; 
	else 
		p->next = e; 
	if(tail != 0) 
		tail->next = f; 
1993/1016    
	if(e != 0) { 
		if(p == 0) 
			m->list = e; 
		else 
			p->next = e; 
		if(tail != 0) 
			tail->next = f; 
	} 
1993/1015    
	qunlock(m); 
cprint(m, "cwrite"); 
1993/1011    
} 
1993/1016/sys/src/9/port/cache.c:41,471993/1017/sys/src/9/port/cache.c:41,48 (short | long)
1993/1013    
typedef struct Cache Cache; 
struct Cache 
1993/1011    
{ 
1993/1013    
	Ref; 
1993/1017    
	Lock; 
	int		pgno; 
1993/1013    
	Mntcache	*head; 
	Mntcache	*tail; 
	Mntcache	*hash[NHASH]; 
1993/1016/sys/src/9/port/cache.c:54,601993/1017/sys/src/9/port/cache.c:55,60
1993/1014    
	int i; 
	Mntcache *m; 
 
	cache.ref = 1; 
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
	 
1993/1016/sys/src/9/port/cache.c:70,841993/1017/sys/src/9/port/cache.c:70,86
1993/1014    
} 
 
1993/1013    
void 
1993/1015    
cprint(Mntcache *m, char *s) 
1993/1017    
cprint(Chan *c, Mntcache *m, char *s) 
1993/1014    
{ 
	Extent *e; 
1993/1017    
	char buf[128]; 
1993/1016    
 
1993/1015    
	print("%s: 0x%lux.0x%lux %d %d\n", 
			s, m->path, m->vers, m->type, m->dev); 
1993/1017    
	ptpath(c->path, buf, sizeof(buf)); 
	pprint("%s: 0x%lux.0x%lux %d %d %s\n", 
			s, m->path, m->vers, m->type, m->dev, buf); 
1993/1014    
 
1993/1015    
	for(e = m->list; e; e = e->next) 
1993/1014    
		print("\t%4d %5d %4d %lux\n", 
1993/1017    
		pprint("\t%4d %5d %4d %lux\n", 
1993/1014    
			e->bid, e->start, e->len, e->cache); 
} 
 
1993/1016/sys/src/9/port/cache.c:138,1441993/1017/sys/src/9/port/cache.c:140,146
1993/1013    
{ 
	Mntcache *m, *f, **l; 
 
1993/1015    
	if(c->qid.path & CHDIR) 
1993/1017    
	if((c->qid.path&CHDIR) || (c->flag&CTEXT)) 
1993/1015    
		return; 
 
1993/1016    
	lock(&cache); 
1993/1016/sys/src/9/port/cache.c:207,2131993/1017/sys/src/9/port/cache.c:209,215
1993/1013    
	Page *p; 
	Mntcache *m; 
1993/1014    
	Extent *e, **t; 
	int o, l, total, end; 
1993/1017    
	int o, l, total; 
1993/1013    
 
1993/1015    
	if(c->qid.path & CHDIR) 
		return 0; 
1993/1016/sys/src/9/port/cache.c:222,2361993/1017/sys/src/9/port/cache.c:224,233
1993/1013    
		return 0; 
	} 
 
	end = offset+len; 
1993/1014    
	t = &m->list; 
	for(e = *t; e; e = e->next) { 
1993/1016    
		if(offset > e->start && offset < e->start+e->len) 
1993/1013    
			break; 
1993/1016    
		if(offset < e->start) { 
			qunlock(m); 
			return 0; 
		}	 
1993/1014    
		t = &e->next; 
1993/1013    
	} 
 
1993/1016/sys/src/9/port/cache.c:277,2821993/1017/sys/src/9/port/cache.c:274,280
1993/1013    
		if(e == 0 || e->start != offset) 
			break; 
	} 
1993/1017    
if(len) print("P"); else print("F"); 
1993/1014    
	qunlock(m); 
1993/1013    
	return total; 
} 
1993/1016/sys/src/9/port/cache.c:309,3151993/1017/sys/src/9/port/cache.c:307,316
1993/1015    
		e->cache = p; 
		e->start = offset; 
		e->len = l; 
1993/1014    
		e->bid = incref(&cache); 
1993/1017    
		lock(&cache); 
		e->bid = cache.pgno; 
		cache.pgno += BY2PG; 
		unlock(&cache); 
1993/1014    
		p->daddr = e->bid; 
		k = kmap(p); 
		memmove((void*)VA(k), buf, l); 
1993/1016/sys/src/9/port/cache.c:460,4661993/1017/sys/src/9/port/cache.c:461,466
1993/1016    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
{ 
	cxupdate(c, buf, len, offset); 
	cprint(c->mcp, "cupdate"); 
} 
 
void 
1993/1016/sys/src/9/port/cache.c:485,4941993/1017/sys/src/9/port/cache.c:485,495
1993/1015    
	} 
 
	m->vers++; 
1993/1017    
	c->qid.vers++; 
1993/1015    
 
	p = 0; 
	for(f = m->list; f; f = f->next) { 
		if(offset >= f->start) 
1993/1017    
		if(f->start >= offset) 
1993/1015    
			break; 
		p = f;		 
	} 
1993/1016/sys/src/9/port/cache.c:501,5061993/1017/sys/src/9/port/cache.c:502,522
1993/1016    
			if(p->len == 0) 
1993/1015    
				panic("del empty extent"); 
		} 
1993/1017    
		if(ee == offset && p->len < BY2PG) { 
			o = len; 
			if(o > BY2PG - p->len) 
				o = BY2PG - p->len; 
			if(cpgmove(p, buf, p->len, o)) { 
				p->len += o; 
				buf += o; 
				len -= o; 
				offset += o; 
				if(len <= 0) { 
					qunlock(m); 
					return; 
				} 
			} 
		} 
1993/1015    
	} 
 
	eblock = offset+len; 
1993/1016/sys/src/9/port/cache.c:521,5251993/1017/sys/src/9/port/cache.c:537,540
1993/1016    
			tail->next = f; 
	} 
1993/1015    
	qunlock(m); 
cprint(m, "cwrite"); 
1993/1011    
} 
1993/1017/sys/src/9/port/cache.c:72,871993/1018/sys/src/9/port/cache.c:72,100 (short | long)
1993/1013    
void 
1993/1017    
cprint(Chan *c, Mntcache *m, char *s) 
1993/1014    
{ 
1993/1018    
	ulong o; 
	int nb, ct; 
1993/1014    
	Extent *e; 
1993/1017    
	char buf[128]; 
1993/1016    
                 
1993/1018    
return; 
1993/1017    
	ptpath(c->path, buf, sizeof(buf)); 
	pprint("%s: 0x%lux.0x%lux %d %d %s\n", 
			s, m->path, m->vers, m->type, m->dev, buf); 
1993/1018    
	nb = 0; 
	ct = 1; 
	if(m->list) 
		o = m->list->start; 
	for(e = m->list; e; e = e->next) { 
		nb += e->len; 
		if(o != e->start) 
			ct = 0; 
		o = e->start+e->len; 
	} 
	pprint("%s: 0x%lux.0x%lux %d %d %s (%d %c)\n", 
	s, m->path, m->vers, m->type, m->dev, buf, nb, ct ? 'C' : 'N'); 
1993/1014    
 
1993/1015    
	for(e = m->list; e; e = e->next) 
1993/1017    
		pprint("\t%4d %5d %4d %lux\n", 
1993/1018    
	for(e = m->list; e; e = e->next) { 
		if(0) pprint("\t%4d %5d %4d %lux\n", 
1993/1014    
			e->bid, e->start, e->len, e->cache); 
1993/1018    
	} 
1993/1014    
} 
 
Page* 
1993/1017/sys/src/9/port/cache.c:130,1371993/1018/sys/src/9/port/cache.c:143,152
1993/1013    
		cache.tail = m; 
	} 
	else { 
		cache.head = cache.tail = m; 
		m->prev = m->next = 0; 
1993/1018    
		cache.head = m; 
		cache.tail = m; 
		m->prev = 0; 
		m->next = 0; 
1993/1013    
	} 
} 
 
1993/1017/sys/src/9/port/cache.c:138,1501993/1018/sys/src/9/port/cache.c:153,168
1993/1013    
void 
copen(Chan *c) 
{ 
1993/1018    
	int h; 
	Extent *e, *next; 
1993/1013    
	Mntcache *m, *f, **l; 
 
1993/1017    
	if((c->qid.path&CHDIR) || (c->flag&CTEXT)) 
1993/1018    
	if(c->qid.path&CHDIR) 
1993/1015    
		return; 
 
1993/1018    
	h = c->qid.path%NHASH; 
1993/1016    
	lock(&cache); 
	for(m = cache.hash[c->qid.path%NHASH]; m; m = m->hash) { 
1993/1018    
	for(m = cache.hash[h]; m; m = m->hash) { 
1993/1016    
		if(m->path == c->qid.path) 
		if(m->dev == c->dev && m->type == c->type) { 
			c->mcp = m; 
1993/1017/sys/src/9/port/cache.c:153,1631993/1018/sys/src/9/port/cache.c:171,184
1993/1015    
 
1993/1016    
			/* File was updated, invalidate cache */ 
			if(m->vers != c->qid.vers) { 
1993/1018    
				m->vers = c->qid.vers; 
1993/1016    
				qlock(m); 
				cnodata(m); 
				m->vers = c->qid.vers; 
				qunlock(m); 
1993/1018    
cprint(c, m, "open mod"); 
1993/1016    
			} 
1993/1018    
else 
cprint(c, m, "open cached"); 
1993/1016    
			return; 
1993/1015    
		} 
1993/1013    
	} 
1993/1017/sys/src/9/port/cache.c:167,1911993/1018/sys/src/9/port/cache.c:188,219
1993/1014    
	l = &cache.hash[m->path%NHASH]; 
1993/1016    
	for(f = *l; f; f = f->hash) { 
1993/1013    
		if(f == m) { 
1993/1016    
			*l = f->hash; 
1993/1018    
			*l = m->hash; 
1993/1013    
			break; 
		} 
1993/1016    
		l = &f->hash; 
1993/1013    
	} 
	l = &cache.hash[c->qid.path%NHASH]; 
	m->hash = *l; 
	*l = m; 
1993/1016    
	ctail(m); 
1993/1015    
 
1993/1014    
	m->Qid = c->qid; 
1993/1013    
	m->dev = c->dev; 
	m->type = c->type; 
1993/1018    
 
	l = &cache.hash[h]; 
	m->hash = *l; 
	*l = m; 
	ctail(m); 
 
1993/1013    
	c->mcp = m; 
1993/1018    
	e = m->list; 
	m->list = 0; 
1993/1016    
	unlock(&cache); 
 
	qlock(m); 
	cnodata(m); 
1993/1013    
	qunlock(m); 
1993/1018    
	while(e) { 
		next = e->next; 
		free(e); 
		e = next; 
	} 
cprint(c, m, "open new"); 
1993/1013    
} 
 
static int 
1993/1017/sys/src/9/port/cache.c:193,2041993/1018/sys/src/9/port/cache.c:221,232
1993/1013    
{ 
1993/1014    
	if(m->path != c->qid.path) 
1993/1013    
		return 0; 
1993/1014    
	if(m->vers != c->qid.vers) 
1993/1013    
		return 0; 
	if(m->dev != c->dev) 
		return 0; 
	if(m->type != c->type) 
		return 0; 
1993/1018    
	if(m->vers != c->qid.vers) 
		return 0; 
1993/1013    
	return 1; 
} 
 
1993/1017/sys/src/9/port/cache.c:211,2191993/1018/sys/src/9/port/cache.c:239,244
1993/1014    
	Extent *e, **t; 
1993/1017    
	int o, l, total; 
1993/1013    
 
1993/1015    
	if(c->qid.path & CHDIR) 
		return 0; 
                 
1993/1013    
	m = c->mcp; 
	if(m == 0) 
		return 0; 
1993/1017/sys/src/9/port/cache.c:226,2321993/1018/sys/src/9/port/cache.c:251,257
1993/1013    
 
1993/1014    
	t = &m->list; 
	for(e = *t; e; e = e->next) { 
1993/1016    
		if(offset > e->start && offset < e->start+e->len) 
1993/1018    
		if(offset >= e->start && offset < e->start+e->len) 
1993/1013    
			break; 
1993/1014    
		t = &e->next; 
1993/1013    
	} 
1993/1017/sys/src/9/port/cache.c:274,2801993/1018/sys/src/9/port/cache.c:299,305
1993/1013    
		if(e == 0 || e->start != offset) 
			break; 
	} 
1993/1017    
if(len) print("P"); else print("F"); 
1993/1018    
 
1993/1014    
	qunlock(m); 
1993/1013    
	return total; 
} 
1993/1017/sys/src/9/port/cache.c:307,3161993/1018/sys/src/9/port/cache.c:332,343
1993/1015    
		e->cache = p; 
		e->start = offset; 
		e->len = l; 
1993/1018    
 
1993/1017    
		lock(&cache); 
		e->bid = cache.pgno; 
		cache.pgno += BY2PG; 
		unlock(&cache); 
1993/1018    
 
1993/1014    
		p->daddr = e->bid; 
		k = kmap(p); 
		memmove((void*)VA(k), buf, l); 
1993/1017/sys/src/9/port/cache.c:350,3561993/1018/sys/src/9/port/cache.c:377,383
1993/1014    
} 
 
1993/1013    
void 
1993/1016    
cxupdate(Chan *c, uchar *buf, int len, ulong offset) 
1993/1018    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
1993/1013    
{ 
	Mntcache *m; 
1993/1014    
	Extent *tail; 
1993/1017/sys/src/9/port/cache.c:458,4691993/1018/sys/src/9/port/cache.c:485,490
1993/1015    
} 
 
void 
1993/1016    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
{ 
	cxupdate(c, buf, len, offset); 
} 
                 
void 
1993/1015    
cwrite(Chan* c, uchar *buf, int len, ulong offset) 
{ 
	int o; 
1993/1017/sys/src/9/port/cache.c:502,5071993/1018/sys/src/9/port/cache.c:523,529
1993/1016    
			if(p->len == 0) 
1993/1015    
				panic("del empty extent"); 
		} 
1993/1018    
		/* Pack sequential write if there is space */ 
1993/1017    
		if(ee == offset && p->len < BY2PG) { 
			o = len; 
			if(o > BY2PG - p->len) 
1993/1018/sys/src/9/port/cache.c:555,5601993/1022/sys/src/9/port/cache.c:555,561 (short | long)
1993/1016    
			m->list = e; 
		else 
			p->next = e; 
1993/1022    
 
1993/1016    
		if(tail != 0) 
			tail->next = f; 
	} 
1993/1022/sys/src/9/port/cache.c:76,821993/1028/sys/src/9/port/cache.c:76,82 (short | long)
1993/1018    
	int nb, ct; 
1993/1014    
	Extent *e; 
1993/1017    
	char buf[128]; 
1993/1018    
return; 
1993/1028    
 
1993/1017    
	ptpath(c->path, buf, sizeof(buf)); 
1993/1018    
	nb = 0; 
	ct = 1; 
1993/1022/sys/src/9/port/cache.c:175,1841993/1028/sys/src/9/port/cache.c:175,181
1993/1016    
				qlock(m); 
				cnodata(m); 
				qunlock(m); 
1993/1018    
cprint(c, m, "open mod"); 
1993/1016    
			} 
1993/1018    
else 
cprint(c, m, "open cached"); 
1993/1016    
			return; 
1993/1015    
		} 
1993/1013    
	} 
1993/1022/sys/src/9/port/cache.c:213,2191993/1028/sys/src/9/port/cache.c:210,215
1993/1018    
		free(e); 
		e = next; 
	} 
cprint(c, m, "open new"); 
1993/1013    
} 
 
static int 
1993/1028/sys/src/9/port/cache.c:80,851993/1103/sys/src/9/port/cache.c:80,86 (short | long)
1993/1017    
	ptpath(c->path, buf, sizeof(buf)); 
1993/1018    
	nb = 0; 
	ct = 1; 
1993/1103    
	o = 0; 
1993/1018    
	if(m->list) 
		o = m->list->start; 
	for(e = m->list; e; e = e->next) { 
1993/1028/sys/src/9/port/cache.c:92,981993/1103/sys/src/9/port/cache.c:93,99
1993/1018    
	s, m->path, m->vers, m->type, m->dev, buf, nb, ct ? 'C' : 'N'); 
1993/1014    
 
1993/1018    
	for(e = m->list; e; e = e->next) { 
		if(0) pprint("\t%4d %5d %4d %lux\n", 
1993/1103    
		pprint("\t%4d %5d %4d %lux\n", 
1993/1014    
			e->bid, e->start, e->len, e->cache); 
1993/1018    
	} 
1993/1014    
} 
1993/1103/sys/src/9/port/cache.c:268,2731994/0728/sys/src/9/port/cache.c:268,278 (short | long)
1993/1013    
			return total; 
		} 
 
1994/0728    
		o = offset - e->start; 
		l = len; 
		if(l > e->len-o) 
			l = e->len-o; 
 
1993/1013    
		k = kmap(p); 
		if(waserror()) { 
			kunmap(k); 
1993/1103/sys/src/9/port/cache.c:276,2901994/0728/sys/src/9/port/cache.c:281,291
1993/1013    
			nexterror(); 
		} 
 
		o = offset - e->start; 
		l = len; 
		if(l > e->len-o) 
			l = e->len-o; 
                 
1993/1014    
		memmove(buf, (uchar*)VA(k) + o, l); 
1993/1016    
 
		poperror(); 
1993/1013    
		kunmap(k); 
1994/0728    
 
1993/1013    
		putpage(p); 
 
		buf += l; 
1993/1103/sys/src/9/port/cache.c:337,3431994/0728/sys/src/9/port/cache.c:338,349
1993/1018    
 
1993/1014    
		p->daddr = e->bid; 
		k = kmap(p); 
1994/0728    
		if(waserror()) {		/* buf may be virtual */ 
			kunmap(k); 
			nexterror(); 
		} 
1993/1014    
		memmove((void*)VA(k), buf, l); 
1994/0728    
		poperror(); 
1993/1014    
		kunmap(k); 
 
		cachepage(p, &fscache); 
1993/1103/sys/src/9/port/cache.c:366,3721994/0728/sys/src/9/port/cache.c:372,385
1993/1014    
		return 0; 
1993/1015    
 
1993/1014    
	k = kmap(p); 
1994/0728    
	if(waserror()) {		/* Since buf may be virtual */ 
		kunmap(k); 
		nexterror(); 
	} 
 
1993/1014    
	memmove((uchar*)VA(k)+boff, buf, len); 
1994/0728    
 
	poperror(); 
1993/1014    
	kunmap(k); 
	putpage(p); 
 
1994/0728/sys/src/9/port/cache.c:67,721994/0817/sys/src/9/port/cache.c:67,74 (short | long)
1993/1014    
	cache.tail = m; 
	cache.tail->next = 0; 
	cache.head->prev = 0; 
1994/0817    
 
	fscache.notext = 1; 
1993/1014    
} 
 
1993/1013    
void 
1994/0817/sys/src/9/port/cache.c:4,101996/0223/sys/src/9/port/cache.c:4,9 (short | long)
1993/1011    
#include	"dat.h" 
#include	"fns.h" 
#include	"../port/error.h" 
#include	"devtab.h" 
 
1993/1013    
Image	fscache; 
 
1996/0223/sys/src/9/port/cache.c:498,5041996/0326/sys/src/9/port/cache.c:498,504 (short | long)
1993/1015    
void 
cwrite(Chan* c, uchar *buf, int len, ulong offset) 
{ 
	int o; 
1996/0326    
	int o, n; 
1993/1015    
	Mntcache *m; 
	ulong eblock, ee; 
	Extent *p, *f, *e, *tail; 
1996/0223/sys/src/9/port/cache.c:524,5291996/0326/sys/src/9/port/cache.c:524,549
1993/1017    
		if(f->start >= offset) 
1993/1015    
			break; 
		p = f;		 
1996/0326    
	} 
 
	if(f != 0) { 
		o = offset - f->start; 
		if(o >= 0) { 
			n = f->len - o; 
			if(n > len) 
				n = len; 
			if(n > 0) { 
				if(cpgmove(f, buf, o, n)) { 
					buf += n; 
					len -= n; 
					offset += n; 
				} 
				if(len == 0) { 
					qunlock(m); 
					return; 
				} 
			}	 
		} 
1993/1015    
	} 
 
	if(p != 0) { 
1996/0326/sys/src/9/port/cache.c:526,5481996/0329/sys/src/9/port/cache.c:526,544 (short | long)
1993/1015    
		p = f;		 
1996/0326    
	} 
 
	if(f != 0) { 
1996/0329    
	if(f != 0 && offset < f->start+f->len) { 
1996/0326    
		o = offset - f->start; 
		if(o >= 0) { 
			n = f->len - o; 
			if(n > len) 
				n = len; 
			if(n > 0) { 
				if(cpgmove(f, buf, o, n)) { 
					buf += n; 
					len -= n; 
					offset += n; 
				} 
				if(len == 0) { 
					qunlock(m); 
					return; 
				} 
			}	 
1996/0329    
		n = f->len - o; 
		if(n > len) 
			n = len; 
		if(cpgmove(f, buf, o, n)) { 
			len -= n; 
			if(len == 0) { 
				qunlock(m); 
				return; 
			} 
			offset += n; 
			buf += n; 
1996/0326    
		} 
1993/1015    
	} 
 
1996/0329/sys/src/9/port/cache.c:526,5321996/0402/sys/src/9/port/cache.c:526,532 (short | long)
1993/1015    
		p = f;		 
1996/0326    
	} 
 
1996/0329    
	if(f != 0 && offset < f->start+f->len) { 
1996/0402    
	if(0 && f != 0 && offset < f->start+f->len) { 
1996/0326    
		o = offset - f->start; 
1996/0329    
		n = f->len - o; 
		if(n > len) 
1996/0402/sys/src/9/port/cache.c:202,2071997/0327/sys/src/9/port/cache.c:202,208 (short | long)
1993/1018    
	*l = m; 
	ctail(m); 
 
1997/0327    
	qlock(m); 
1993/1013    
	c->mcp = m; 
1993/1018    
	e = m->list; 
	m->list = 0; 
1996/0402/sys/src/9/port/cache.c:212,2171997/0327/sys/src/9/port/cache.c:213,219
1993/1018    
		free(e); 
		e = next; 
	} 
1997/0327    
	qunlock(m); 
1993/1013    
} 
 
static int 
1997/0327/sys/src/9/port/cache.c:231,2371998/0327/sys/src/9/port/cache.c:231,237 (short | long)
Change dev read and write to use vlong.
rsc Fri Mar 4 12:44:25 2005
1993/1013    
} 
 
int 
1993/1014    
cread(Chan *c, uchar *buf, int len, ulong offset) 
1998/0327    
cread(Chan *c, uchar *buf, int len, vlong off) 
1993/1013    
{ 
	KMap *k; 
	Page *p; 
1997/0327/sys/src/9/port/cache.c:238,2441998/0327/sys/src/9/port/cache.c:238,248
1993/1013    
	Mntcache *m; 
1993/1014    
	Extent *e, **t; 
1993/1017    
	int o, l, total; 
1998/0327    
	ulong offset; 
1993/1013    
 
1998/0327    
	if(off+len > MAXCACHE) 
		return 0; 
 
1993/1013    
	m = c->mcp; 
	if(m == 0) 
		return 0; 
1997/0327/sys/src/9/port/cache.c:249,2541998/0327/sys/src/9/port/cache.c:253,259
1993/1013    
		return 0; 
	} 
 
1998/0327    
	offset = off; 
1993/1014    
	t = &m->list; 
	for(e = *t; e; e = e->next) { 
1993/1018    
		if(offset >= e->start && offset < e->start+e->len) 
1997/0327/sys/src/9/port/cache.c:390,4031998/0327/sys/src/9/port/cache.c:395,409
1993/1014    
} 
 
1993/1013    
void 
1993/1018    
cupdate(Chan *c, uchar *buf, int len, ulong offset) 
1998/0327    
cupdate(Chan *c, uchar *buf, int len, vlong off) 
1993/1013    
{ 
	Mntcache *m; 
1993/1014    
	Extent *tail; 
	Extent *e, *f, *p; 
1993/1015    
	int o, ee, eblock; 
1998/0327    
	ulong offset; 
1993/1013    
 
1993/1015    
	if(offset > MAXCACHE || len == 0) 
1998/0327    
	if(off > MAXCACHE || len == 0) 
1993/1015    
		return; 
 
1993/1013    
	m = c->mcp; 
1997/0327/sys/src/9/port/cache.c:412,4171998/0327/sys/src/9/port/cache.c:418,424
1993/1014    
	/* 
	 * Find the insertion point 
	 */ 
1998/0327    
	offset = off; 
1993/1014    
	p = 0; 
	for(f = m->list; f; f = f->next) { 
		if(f->start >= offset) 
1997/0327/sys/src/9/port/cache.c:498,5111998/0327/sys/src/9/port/cache.c:505,519
1993/1015    
} 
 
void 
cwrite(Chan* c, uchar *buf, int len, ulong offset) 
1998/0327    
cwrite(Chan* c, uchar *buf, int len, vlong off) 
1993/1015    
{ 
1996/0326    
	int o, n; 
1993/1015    
	Mntcache *m; 
	ulong eblock, ee; 
	Extent *p, *f, *e, *tail; 
1998/0327    
	ulong offset; 
1993/1015    
 
	if(offset > MAXCACHE || len == 0) 
1998/0327    
	if(off > MAXCACHE || len == 0) 
1993/1015    
		return; 
 
	m = c->mcp; 
1997/0327/sys/src/9/port/cache.c:518,5231998/0327/sys/src/9/port/cache.c:526,532
1993/1015    
		return; 
	} 
 
1998/0327    
	offset = off; 
1993/1015    
	m->vers++; 
1993/1017    
	c->qid.vers++; 
1993/1015    
 
1998/0327/sys/src/9/port/cache.c:56,621998/0512/sys/src/9/port/cache.c:56,62 (short | long)
Whitespace edit.
rsc Fri Mar 4 12:44:25 2005
1993/1014    
 
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
	                 
1998/0512    
 
1993/1016    
	for(i = 0; i < NFILE-1; i++) { 
1993/1014    
		m->next = m+1; 
		m->prev = m-1; 
1998/0327/sys/src/9/port/cache.c:129,1351998/0512/sys/src/9/port/cache.c:129,135
1993/1016    
ctail(Mntcache *m) 
1993/1013    
{ 
	/* Unlink and send to the tail */ 
	if(m->prev)  
1998/0512    
	if(m->prev) 
1993/1013    
		m->prev->next = m->next; 
	else 
		cache.head = m->next; 
1998/0327/sys/src/9/port/cache.c:534,5401998/0512/sys/src/9/port/cache.c:534,540
1993/1015    
	for(f = m->list; f; f = f->next) { 
1993/1017    
		if(f->start >= offset) 
1993/1015    
			break; 
		p = f;		 
1998/0512    
		p = f; 
1996/0326    
	} 
 
1996/0402    
	if(0 && f != 0 && offset < f->start+f->len) { 
1998/0512/sys/src/9/port/cache.c:5,171999/0508/sys/src/9/port/cache.c:5,16 (short | long)
1993/1011    
#include	"fns.h" 
#include	"../port/error.h" 
 
1993/1013    
Image	fscache; 
                 
1993/1014    
enum 
{ 
	NHASH		= 128, 
	MAXCACHE	= 1024*1024, 
	NFILE		= 4096, 
1999/0508    
	NEXTENT		= 200,		/* extent allocation size */ 
1993/1014    
}; 
 
typedef struct Extent Extent; 
1998/0512/sys/src/9/port/cache.c:46,531999/0508/sys/src/9/port/cache.c:45,105
1993/1013    
	Mntcache	*tail; 
	Mntcache	*hash[NHASH]; 
1993/1011    
}; 
1993/1013    
Cache cache; 
1993/1011    
 
1999/0508    
typedef struct Ecache Ecache; 
struct Ecache 
{ 
	Lock; 
	int	total; 
	int	free; 
	Extent*	head; 
}; 
 
static Image fscache; 
static Cache cache; 
static Ecache ecache; 
 
static void 
extentfree(Extent* e) 
{ 
	lock(&ecache); 
	e->next = ecache.head; 
	ecache.head = e; 
	ecache.free++; 
	unlock(&ecache); 
} 
 
static Extent* 
extentalloc(void) 
{ 
	Extent *e; 
	int i; 
 
	lock(&ecache); 
	if(ecache.head == nil){ 
		e = xalloc(NEXTENT*sizeof(Extent)); 
		if(e == nil){ 
			unlock(&ecache); 
			return nil; 
		} 
		for(i = 0; i < NEXTENT; i++){ 
			e->next = ecache.head; 
			ecache.head = e; 
			e++; 
		} 
		ecache.free += NEXTENT; 
		ecache.total += NEXTENT; 
	} 
 
	e = ecache.head; 
	ecache.head = e->next; 
	memset(e, 0, sizeof(Extent)); 
	ecache.free--; 
	unlock(&ecache); 
 
	return e; 
} 
 
1993/1014    
void 
cinit(void) 
{ 
1998/0512/sys/src/9/port/cache.c:120,1261999/0508/sys/src/9/port/cache.c:172,178
1993/1013    
	 */ 
	for(e = m->list; e; e = n) { 
1993/1014    
		n = e->next; 
1993/1013    
		free(e); 
1999/0508    
		extentfree(e); 
1993/1013    
	} 
1993/1015    
	m->list = 0; 
1993/1013    
} 
1998/0512/sys/src/9/port/cache.c:210,2161999/0508/sys/src/9/port/cache.c:262,268
1993/1016    
 
1993/1018    
	while(e) { 
		next = e->next; 
		free(e); 
1999/0508    
		extentfree(e); 
1993/1018    
		e = next; 
	} 
1997/0327    
	qunlock(m); 
1998/0512/sys/src/9/port/cache.c:271,2771999/0508/sys/src/9/port/cache.c:323,329
1993/1014    
		p = cpage(e); 
1993/1013    
		if(p == 0) { 
1993/1014    
			*t = e->next; 
1993/1013    
			free(e); 
1999/0508    
			extentfree(e); 
1993/1013    
			qunlock(m); 
			return total; 
		} 
1998/0512/sys/src/9/port/cache.c:322,3341999/0508/sys/src/9/port/cache.c:374,386
1993/1016    
	*tail = 0; 
1993/1014    
	t = &start; 
	while(len) { 
		e = malloc(sizeof(Extent)); 
1999/0508    
		e = extentalloc(); 
1993/1014    
		if(e == 0) 
			break; 
 
		p = auxpage(); 
		if(p == 0) { 
			free(e); 
1999/0508    
			extentfree(e); 
1993/1014    
			break; 
		} 
		l = len; 
1998/0512/sys/src/9/port/cache.c:583,5891999/0508/sys/src/9/port/cache.c:635,641
1993/1015    
	/* free the overlap - its a rare case */ 
	while(f && f->start < eblock) { 
		e = f->next; 
		free(f); 
1999/0508    
		extentfree(f); 
1993/1015    
		f = e; 
	} 
 
1999/0508/sys/src/9/port/cache.c:128,1361999/0629/sys/src/9/port/cache.c:128,134 (short | long)
1993/1018    
	ulong o; 
	int nb, ct; 
1993/1014    
	Extent *e; 
1993/1017    
	char buf[128]; 
1993/1028    
 
1993/1017    
	ptpath(c->path, buf, sizeof(buf)); 
1993/1018    
	nb = 0; 
	ct = 1; 
1993/1103    
	o = 0; 
1999/0508/sys/src/9/port/cache.c:143,1491999/0629/sys/src/9/port/cache.c:141,147
1993/1018    
		o = e->start+e->len; 
	} 
	pprint("%s: 0x%lux.0x%lux %d %d %s (%d %c)\n", 
	s, m->path, m->vers, m->type, m->dev, buf, nb, ct ? 'C' : 'N'); 
1999/0629    
	s, m->path, m->vers, m->type, m->dev, c->name, nb, ct ? 'C' : 'N'); 
1993/1014    
 
1993/1018    
	for(e = m->list; e; e = e->next) { 
1993/1103    
		pprint("\t%4d %5d %4d %lux\n", 
1999/0629/sys/src/9/port/cache.c:58,631999/0903/sys/src/9/port/cache.c:58,64 (short | long)
1999/0508    
static Image fscache; 
static Cache cache; 
static Ecache ecache; 
1999/0903    
static int maxcache = MAXCACHE; 
1999/0508    
 
static void 
extentfree(Extent* e) 
1999/0629/sys/src/9/port/cache.c:109,1141999/0903/sys/src/9/port/cache.c:110,118
1993/1014    
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
1998/0512    
 
1999/0903    
	if(conf.npage*BY2PG > 200*MB) 
		maxcache = 10*MAXCACHE; 
 
1993/1016    
	for(i = 0; i < NFILE-1; i++) { 
1993/1014    
		m->next = m+1; 
		m->prev = m-1; 
1999/0629/sys/src/9/port/cache.c:290,2961999/0903/sys/src/9/port/cache.c:294,300
1993/1017    
	int o, l, total; 
1998/0327    
	ulong offset; 
1993/1013    
 
1998/0327    
	if(off+len > MAXCACHE) 
1999/0903    
	if(off+len > maxcache) 
1998/0327    
		return 0; 
 
1993/1013    
	m = c->mcp; 
1999/0629/sys/src/9/port/cache.c:453,4591999/0903/sys/src/9/port/cache.c:457,463
1993/1015    
	int o, ee, eblock; 
1998/0327    
	ulong offset; 
1993/1013    
 
1998/0327    
	if(off > MAXCACHE || len == 0) 
1999/0903    
	if(off > maxcache || len == 0) 
1993/1015    
		return; 
 
1993/1013    
	m = c->mcp; 
1999/0629/sys/src/9/port/cache.c:563,5691999/0903/sys/src/9/port/cache.c:567,573
1993/1015    
	Extent *p, *f, *e, *tail; 
1998/0327    
	ulong offset; 
1993/1015    
 
1998/0327    
	if(off > MAXCACHE || len == 0) 
1999/0903    
	if(off > maxcache || len == 0) 
1993/1015    
		return; 
 
	m = c->mcp; 
1999/0903/sys/src/9/port/cache.c:396,4011999/1022/sys/src/9/port/cache.c:396,409 (short | long)
1993/1017    
		lock(&cache); 
		e->bid = cache.pgno; 
		cache.pgno += BY2PG; 
1999/1022    
		/* wrap the counter; low bits are unused by pghash by checked by lookpage */ 
		if((cache.pgno & ~(BY2PG-1)) == 0){ 
			if(cache.pgno == BY2PG-1){ 
				print("cache wrapped\n"); 
				cache.pgno = 0; 
			}else 
				cache.pgno++; 
		} 
1993/1017    
		unlock(&cache); 
1993/1018    
 
1993/1014    
		p->daddr = e->bid; 
1999/1022/sys/src/9/port/cache.c:396,4021999/1101/sys/src/9/port/cache.c:396,402 (short | long)
1993/1017    
		lock(&cache); 
		e->bid = cache.pgno; 
		cache.pgno += BY2PG; 
1999/1022    
		/* wrap the counter; low bits are unused by pghash by checked by lookpage */ 
1999/1101    
		/* wrap the counter; low bits are unused by pghash but checked by lookpage */ 
1999/1022    
		if((cache.pgno & ~(BY2PG-1)) == 0){ 
			if(cache.pgno == BY2PG-1){ 
				print("cache wrapped\n"); 
1999/1101/sys/src/9/port/cache.c:483,5081999/1227/sys/src/9/port/cache.c:483,508 (short | long)
1998/0327    
	offset = off; 
1993/1014    
	p = 0; 
	for(f = m->list; f; f = f->next) { 
		if(f->start >= offset) 
1999/1227    
		if(f->start > offset) 
1993/1014    
			break; 
		p = f; 
	} 
1993/1015    
 
1993/1014    
	if(p == 0) {		/* at the head */ 
		eblock = offset+len; 
		/* trim if there is a successor */ 
		if(f != 0 && eblock >= f->start) { 
			len -= (eblock - f->start); 
			if(len <= 0) { 
				qunlock(m); 
				return; 
			} 
1999/1227    
	/* trim if there is a successor */ 
	eblock = offset+len; 
	if(f != 0 && eblock > f->start) { 
		len -= (eblock - f->start); 
		if(len <= 0) { 
			qunlock(m); 
			return; 
1993/1014    
		} 
1999/1227    
	} 
 
	if(p == 0) {		/* at the head */ 
1993/1014    
		e = cchain(buf, offset, len, &tail); 
1993/1016    
		if(e != 0) { 
			m->list = e; 
			if(tail != 0) 
				tail->next = f; 
1999/1227    
			tail->next = f; 
1993/1016    
		} 
1993/1014    
		qunlock(m); 
		return; 
1999/1101/sys/src/9/port/cache.c:532,5371999/1227/sys/src/9/port/cache.c:532,538
1993/1014    
			len -= o; 
			offset += o; 
			if(len <= 0) { 
1999/1227    
if (f && p->start + p->len > f->start) print("CACHE: p->start=%uld p->len=%d f->start=%uld\n", p->start, p->len, f->start); 
1993/1014    
				qunlock(m); 
				return; 
			} 
1999/1101/sys/src/9/port/cache.c:538,5681999/1227/sys/src/9/port/cache.c:539,549
1993/1014    
		} 
1993/1013    
	} 
1993/1014    
 
	/* append to extent list */ 
	if(f == 0) { 
		p->next = cchain(buf, offset, len, &tail); 
		qunlock(m); 
		return; 
	} 
                 
	/* trim data against successor */ 
	eblock = offset+len; 
	if(eblock > f->start) { 
		o = eblock - f->start; 
1993/1016    
		len -= o; 
		if(len <= 0) { 
1993/1014    
			qunlock(m); 
			return; 
		} 
	} 
                 
1993/1015    
	/* insert a middle block */ 
1993/1014    
	p->next = cchain(buf, offset, len, &tail); 
	if(p->next == 0) 
		p->next = f; 
	else 
1999/1227    
	e = cchain(buf, offset, len, &tail); 
	if(e != 0) { 
		p->next = e; 
1993/1014    
		tail->next = f; 
                 
1999/1227    
	} 
1993/1014    
	qunlock(m); 
1993/1015    
} 
 
1999/1101/sys/src/9/port/cache.c:569,5751999/1227/sys/src/9/port/cache.c:550,556
1993/1015    
void 
1998/0327    
cwrite(Chan* c, uchar *buf, int len, vlong off) 
1993/1015    
{ 
1996/0326    
	int o, n; 
1999/1227    
	int o, eo; 
1993/1015    
	Mntcache *m; 
	ulong eblock, ee; 
	Extent *p, *f, *e, *tail; 
1999/1101/sys/src/9/port/cache.c:599,6481999/1227/sys/src/9/port/cache.c:580,605
1998/0512    
		p = f; 
1996/0326    
	} 
 
1996/0402    
	if(0 && f != 0 && offset < f->start+f->len) { 
1996/0326    
		o = offset - f->start; 
1996/0329    
		n = f->len - o; 
		if(n > len) 
			n = len; 
		if(cpgmove(f, buf, o, n)) { 
			len -= n; 
			if(len == 0) { 
				qunlock(m); 
				return; 
			} 
			offset += n; 
			buf += n; 
1996/0326    
		} 
1993/1015    
	} 
                 
	if(p != 0) { 
		ee = p->start+p->len; 
		if(ee > offset) { 
			o = ee - offset; 
			p->len -= o; 
1993/1016    
			if(p->len == 0) 
1993/1015    
				panic("del empty extent"); 
		} 
1993/1018    
		/* Pack sequential write if there is space */ 
1993/1017    
		if(ee == offset && p->len < BY2PG) { 
1999/1227    
		eo = offset - p->start; 
		/* pack in predecessor if there is space */ 
		if(offset <= ee && eo < BY2PG) { 
1993/1017    
			o = len; 
			if(o > BY2PG - p->len) 
				o = BY2PG - p->len; 
			if(cpgmove(p, buf, p->len, o)) { 
				p->len += o; 
1999/1227    
			if(o > BY2PG - eo) 
				o = BY2PG - eo; 
			if(cpgmove(p, buf, eo, o)) { 
				if(eo+o > p->len) 
					p->len = eo+o; 
1993/1017    
				buf += o; 
				len -= o; 
				offset += o; 
				if(len <= 0) { 
					qunlock(m); 
					return; 
				} 
			} 
		} 
1993/1015    
	} 
 
1999/1227    
	/* free the overlap -- it's a rare case */ 
1993/1015    
	eblock = offset+len; 
	/* free the overlap - its a rare case */ 
	while(f && f->start < eblock) { 
		e = f->next; 
1999/0508    
		extentfree(f); 
1999/1101/sys/src/9/port/cache.c:649,6631999/1227/sys/src/9/port/cache.c:606,621
1993/1015    
		f = e; 
	} 
 
1999/1227    
	/* link the block (if any) into the middle */ 
1993/1015    
	e = cchain(buf, offset, len, &tail); 
1993/1016    
	if(e != 0) { 
		if(p == 0) 
			m->list = e; 
		else 
			p->next = e; 
1993/1022    
                 
1993/1016    
		if(tail != 0) 
			tail->next = f; 
1999/1227    
		tail->next = f; 
		f = e; 
1993/1016    
	} 
1999/1227    
 
	if(p == 0) 
		m->list = f; 
	else 
		p->next = f; 
1993/1015    
	qunlock(m); 
1993/1011    
} 
1999/1227/sys/src/9/port/cache.c:110,1172000/0609/sys/src/9/port/cache.c:110,120 (short | long)
1993/1014    
	cache.head = xalloc(sizeof(Mntcache)*NFILE); 
	m = cache.head; 
1998/0512    
 
2000/0609    
	/* a better algorithm would be nice */ 
1999/0903    
	if(conf.npage*BY2PG > 200*MB) 
		maxcache = 10*MAXCACHE; 
2000/0609    
	if(conf.npage*BY2PG > 400*MB) 
		maxcache = 50*MAXCACHE; 
1999/0903    
 
1993/1016    
	for(i = 0; i < NFILE-1; i++) { 
1993/1014    
		m->next = m+1; 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)