| plan 9 kernel history: overview | file list | diff list |
1993/1014/port/cache.c (diff list | history)
| 1993/1013/sys/src/9/port/cache.c:8,19 – 1993/1014/sys/src/9/port/cache.c:8,27 (short | long | prev | next) | ||
| 1993/1011 | ||
| 1993/1013 | Image fscache; | |
| 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,29 – 1993/1014/sys/src/9/port/cache.c:31,37 | ||
| 1993/1011 | Qid; | |
| 1993/1013 | int dev; int type; | |
| 1993/1014 | QLock; | |
| 1993/1013 | Extent *list; Mntcache *hash; Mntcache *prev; | |
| 1993/1013/sys/src/9/port/cache.c:40,55 – 1993/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) { | |
| 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,70 – 1993/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,80 – 1993/1014/sys/src/9/port/cache.c:126,132 | ||
| 1993/1013 | * Image lru will waste the pages */ for(e = m->list; e; e = n) { | |
| 1993/1014 | n = e->next; | |
| 1993/1013 | free(e); } } | |
| 1993/1013/sys/src/9/port/cache.c:116,122 – 1993/1014/sys/src/9/port/cache.c:168,174 | ||
| 1993/1013 | m = clook(c); if(m != 0) { /* File was updated */ | |
| 1993/1014 | if(m->vers != c->qid.vers) | |
| 1993/1013 | cnodata(m); ctail(m); | |
| 1993/1013/sys/src/9/port/cache.c:127,134 – 1993/1014/sys/src/9/port/cache.c:179,186 | ||
| 1993/1013 | /* 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) { if(f == m) { *l = f->next; | |
| 1993/1013/sys/src/9/port/cache.c:139,146 – 1993/1014/sys/src/9/port/cache.c:191,198 | ||
| 1993/1013 | l = &cache.hash[c->qid.path%NHASH]; m->hash = *l; *l = m; | |
| 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,160 – 1993/1014/sys/src/9/port/cache.c:204,212 | ||
| 1993/1013 | static int cdev(Mntcache *m, Chan *c) { | |
| 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; | |
| 1993/1013/sys/src/9/port/cache.c:164,176 – 1993/1014/sys/src/9/port/cache.c:216,228 | ||
| 1993/1013 | } int | |
| 1993/1014 | cread(Chan *c, uchar *buf, int len, ulong offset) | |
| 1993/1013 | { KMap *k; Page *p; Mntcache *m; | |
| 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,192 – 1993/1014/sys/src/9/port/cache.c:234,244 | ||
| 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) break; | |
| 1993/1014 | t = &e->next; | |
| 1993/1013 | } if(e == 0) { | |
| 1993/1013/sys/src/9/port/cache.c:196,204 – 1993/1014/sys/src/9/port/cache.c:248,256 | ||
| 1993/1013 | total = 0; while(len) { | |
| 1993/1014 | p = cpage(e); | |
| 1993/1013 | if(p == 0) { | |
| 1993/1014 | *t = e->next; | |
| 1993/1013 | free(e); qunlock(m); return total; | |
| 1993/1013/sys/src/9/port/cache.c:217,224 – 1993/1014/sys/src/9/port/cache.c:269,275 | ||
| 1993/1013 | if(l > e->len-o) l = e->len-o; | |
| 1993/1014 | memmove(buf, (uchar*)VA(k) + o, l); | |
| 1993/1013 | kunmap(k); putpage(p); | |
| 1993/1013/sys/src/9/port/cache.c:226,245 – 1993/1014/sys/src/9/port/cache.c:277,361 | ||
| 1993/1013 | len -= l; offset += l; total += l; | |
| 1993/1014 | t = &e->next; | |
| 1993/1013 | e = e->next; if(e == 0 || e->start != offset) break; } | |
| 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 | |
| 1993/1014 | cupdate(Chan *c, uchar *buf, int len, ulong offset) | |
| 1993/1013 | { | |
| 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,274 – 1993/1014/sys/src/9/port/cache.c:369,459 | ||
| 1993/1013 | return; } | |
| 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; | |
| 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; | |
| 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 | } | |