diff --git a/sys/src/9/port/cache.c b/sys/src/9/port/cache.c index 2322822d9..3bef6d4e9 100644 --- a/sys/src/9/port/cache.c +++ b/sys/src/9/port/cache.c @@ -113,10 +113,8 @@ cinit(void) panic("cinit: no memory"); /* a better algorithm would be nice */ -// if(conf.npage*BY2PG > 200*MB) -// maxcache = 10*MAXCACHE; -// if(conf.npage*BY2PG > 400*MB) -// maxcache = 50*MAXCACHE; + if(conf.npage*BY2PG > 200*MB) + maxcache = 10*MAXCACHE; for(i = 0; i < NFILE-1; i++) { m->next = m+1; @@ -171,17 +169,16 @@ cpage(Extent *e) void cnodata(Mntcache *m) { - Extent *e, *n; + Extent *e; /* * Invalidate all extent data * Image lru will waste the pages */ - for(e = m->list; e; e = n) { - n = e->next; + while(e = m->list){ + m->list = e->next; extentfree(e); } - m->list = 0; } void @@ -215,36 +212,35 @@ 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; lock(&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); - unlock(&cache); - /* File was updated, invalidate cache */ - if(m->qid.vers != c->qid.vers) { + if(m->qid.vers != c->qid.vers){ + if(!canqlock(m)) + goto Busy; m->qid.vers = c->qid.vers; - qlock(m); - cnodata(m); - qunlock(m); + goto Update; } + ctail(m); + c->mcp = m; + unlock(&cache); return; } } /* LRU the cache headers */ m = cache.head; + if(!canqlock(m)) + goto Busy; l = &cache.hash[m->qid.path%NHASH]; for(f = *l; f; f = f->hash) { if(f == m) { @@ -261,20 +257,16 @@ copen(Chan *c) l = &cache.hash[h]; m->hash = *l; *l = m; +Update: ctail(m); - - qlock(m); c->mcp = m; - e = m->list; - m->list = 0; unlock(&cache); - - while(e) { - next = e->next; - extentfree(e); - e = next; - } + cnodata(m); qunlock(m); + return; +Busy: + unlock(&cache); + c->mcp = 0; } static int @@ -313,6 +305,7 @@ cread(Chan *c, uchar *buf, int len, vlong off) qlock(m); if(cdev(m, c) == 0) { qunlock(m); + c->mcp = 0; return 0; } @@ -483,6 +476,7 @@ cupdate(Chan *c, uchar *buf, int len, vlong off) qlock(m); if(cdev(m, c) == 0) { qunlock(m); + c->mcp = 0; return; } @@ -541,7 +535,9 @@ cupdate(Chan *c, uchar *buf, int len, vlong off) len -= o; offset += o; if(len <= 0) { -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); + 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); qunlock(m); return; } @@ -575,6 +571,7 @@ cwrite(Chan* c, uchar *buf, int len, vlong off) qlock(m); if(cdev(m, c) == 0) { qunlock(m); + c->mcp = 0; return; } diff --git a/sys/src/9/port/chan.c b/sys/src/9/port/chan.c index 28ac86e13..a50565ba0 100644 --- a/sys/src/9/port/chan.c +++ b/sys/src/9/port/chan.c @@ -1488,9 +1488,6 @@ if(c->umh != nil){ /* save registers else error() in open has wrong value of c saved */ saveregisters(); - if(omode == OEXEC) - c->flag &= ~CCACHE; - c = devtab[c->type]->open(c, omode&~OCEXEC); if(omode & OCEXEC) diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c index 841f3ce71..adb65155b 100644 --- a/sys/src/9/port/devmnt.c +++ b/sys/src/9/port/devmnt.c @@ -409,6 +409,7 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) * Therefore set type to 0 for now; rootclose is known to be safe. */ nc->type = 0; + nc->flag |= (c->flag & CCACHE); alloc = 1; } wq->clone = nc; diff --git a/sys/src/9/port/fault.c b/sys/src/9/port/fault.c index 5854d796c..4a1cbdbff 100644 --- a/sys/src/9/port/fault.c +++ b/sys/src/9/port/fault.c @@ -200,7 +200,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) Page *new; KMap *k; Chan *c; - int n, ask; + int n, ask, cache; char *kaddr; ulong daddr; Page *loadrec; @@ -238,15 +238,18 @@ retry: k = kmap(new); kaddr = (char*)VA(k); + cache = c->flag & CCACHE; while(waserror()) { + c->flag |= cache; if(strcmp(up->errstr, Eintr) == 0) continue; kunmap(k); putpage(new); faulterror(Eioload, c, 0); } - + c->flag &= ~CCACHE; n = devtab[c->type]->read(c, kaddr, ask, daddr); + c->flag |= cache; if(n != ask) faulterror(Eioload, c, 0); if(ask < BY2PG)