void copen(Chan *c) { int h; 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) { /* File was updated, invalidate cache */ if(m->qid.vers != c->qid.vers){ if(!canqlock(m)) goto Busy; m->qid.vers = c->qid.vers; 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) { *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; Update: ctail(m); c->mcp = m; unlock(&cache); cnodata(m); qunlock(m); return; Busy: unlock(&cache); c->mcp = 0; }
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); }