| 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,31 – 1993/1013/sys/src/9/port/cache.c:6,274 (short | long) | ||
| 1993/1011 | #include "../port/error.h" #include "devtab.h" | |
| 1993/1013 | Image fscache; typedef Extent Extent; struct Extent | |
| 1993/1011 | { | |
| 1993/1013 | int bid; ulong start; int len; Extent *next; }; typedef struct Mntcache Mntcache; struct Mntcache { | |
| 1993/1011 | Qid; | |
| 1993/1013 | int dev; int type; Qlock; Extent *list; Mntcache *hash; Mntcache *prev; Mntcache *next; | |
| 1993/1011 | }; | |
| 1993/1013 | typedef struct Cache Cache; struct Cache | |
| 1993/1011 | { | |
| 1993/1013 | Ref; Mntcache *head; Mntcache *tail; Mntcache *hash[NHASH]; | |
| 1993/1011 | }; | |
| 1993/1013 | Cache cache; | |
| 1993/1011 |
| |
| 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,19 – 1993/1014/sys/src/9/port/cache.c:8,27 (short | long) | ||
| 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 | } | |
| 1993/1014/sys/src/9/port/cache.c:58,64 – 1993/1015/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/1014 | m->next = m+1; m->prev = m-1; m++; | |
| 1993/1014/sys/src/9/port/cache.c:95,107 – 1993/1015/sys/src/9/port/cache.c:95,108 | ||
| 1993/1013 | } void | |
| 1993/1014 |
| |
| 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 |
| |
| 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,140 – 1993/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 | |
| 1993/1015 | ctail(Mntcache *m, int dolock) | |
| 1993/1013 | { | |
| 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,163 – 1993/1015/sys/src/9/port/cache.c:160,167 | ||
| 1993/1013 | m->prev = m->next = 0; } | |
| 1993/1015 | if(dolock) unlock(&cache); | |
| 1993/1013 | } void | |
| 1993/1014/sys/src/9/port/cache.c:165,178 – 1993/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 |
| |
| 1993/1015 | if(m->vers != c->qid.vers) { cprint(m, "copen mod"); | |
| 1993/1013 | cnodata(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,204 – 1993/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); | |
| 1993/1015 | cprint(m, "copen new"); | |
| 1993/1013 | } static int | |
| 1993/1014/sys/src/9/port/cache.c:224,232 – 1993/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,317 – 1993/1015/sys/src/9/port/cache.c:324,336 | ||
| 1993/1014 | free(e); break; } | |
| 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,346 – 1993/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,365 – 1993/1015/sys/src/9/port/cache.c:375,388 | ||
| 1993/1013 | Mntcache *m; | |
| 1993/1014 | Extent *tail; 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/1013 | m = c->mcp; if(m == 0) return; | |
| 1993/1014/sys/src/9/port/cache.c:378,383 – 1993/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,425 – 1993/1015/sys/src/9/port/cache.c:442,449 | ||
| 1993/1014 | qunlock(m); | |
| 1993/1013 | return; | |
| 1993/1014 | } | |
| 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,454 – 1993/1015/sys/src/9/port/cache.c:472,478 | ||
| 1993/1014 | len -= o; } | |
| 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,459 – 1993/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,64 – 1993/1016/sys/src/9/port/cache.c:58,64 (short | long) | ||
| 1993/1014 | cache.head = xalloc(sizeof(Mntcache)*NFILE); m = cache.head; | |
| 1993/1015 |
| |
| 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,104 – 1993/1016/sys/src/9/port/cache.c:69,79 | ||
| 1993/1014 | cache.head->prev = 0; } | |
| 1993/1013 |
| |
| 1993/1011 |
| |
| 1993/1013 |
| |
| 1993/1014 |
| |
| 1993/1011 | ||
| 1993/1013 |
| |
| 1993/1014 |
| |
| 1993/1013 |
| |
| 1993/1015 | cprint(Mntcache *m, char *s) | |
| 1993/1014 | { Extent *e; | |
| 1993/1015 |
| |
| 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,144 – 1993/1016/sys/src/9/port/cache.c:109,116 | ||
| 1993/1013 | } void | |
| 1993/1015 |
| |
| 1993/1016 | ctail(Mntcache *m) | |
| 1993/1013 | { | |
| 1993/1015 |
| |
| 1993/1013 |
| |
| 1993/1015/sys/src/9/port/cache.c:159,167 – 1993/1016/sys/src/9/port/cache.c:131,136 | ||
| 1993/1013 | cache.head = cache.tail = m; m->prev = m->next = 0; } | |
| 1993/1015 |
| |
| 1993/1013 | } void | |
| 1993/1015/sys/src/9/port/cache.c:172,218 – 1993/1016/sys/src/9/port/cache.c:141,189 | ||
| 1993/1015 | if(c->qid.path & CHDIR) return; | |
| 1993/1013 |
| |
| 1993/1015 |
| |
| 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 |
| |
| 1993/1015 |
| |
| 1993/1013 |
| |
| 1993/1015 |
| |
| 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 |
| |
| 1993/1015 |
| |
| 1993/1013 |
| |
| 1993/1014 |
| |
| 1993/1013 |
| |
| 1993/1016 | for(f = *l; f; f = f->hash) { | |
| 1993/1013 | if(f == m) { | |
| 1993/1016 | *l = f->hash; | |
| 1993/1013 | break; } | |
| 1993/1016 | l = &f->hash; | |
| 1993/1013 | } l = &cache.hash[c->qid.path%NHASH]; m->hash = *l; *l = m; | |
| 1993/1015 |
| |
| 1993/1014 |
| |
| 1993/1016 | ctail(m); | |
| 1993/1015 | ||
| 1993/1014 | m->Qid = c->qid; | |
| 1993/1013 | m->dev = c->dev; m->type = c->type; | |
| 1993/1016 | unlock(&cache); qlock(m); cnodata(m); | |
| 1993/1013 | qunlock(m); | |
| 1993/1015 |
| |
| 1993/1013 | } static int | |
| 1993/1015/sys/src/9/port/cache.c:254,261 – 1993/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 |
| |
| 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,293 – 1993/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,318 – 1993/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,353 – 1993/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,376 – 1993/1016/sys/src/9/port/cache.c:349,355 | ||
| 1993/1014 | } | |
| 1993/1013 | void | |
| 1993/1014 |
| |
| 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,385 – 1993/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 |
| |
| 1993/1013 |
| |
| 1993/1015 | if(offset > MAXCACHE || len == 0) return; | |
| 1993/1015/sys/src/9/port/cache.c:413,421 – 1993/1016/sys/src/9/port/cache.c:389,399 | ||
| 1993/1014 | } } e = cchain(buf, offset, len, &tail); | |
| 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,447 – 1993/1016/sys/src/9/port/cache.c:416,421 | ||
| 1993/1014 | o = len; if(o > BY2PG - p->len) o = BY2PG - p->len; | |
| 1993/1013 |
| |
| 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,475 – 1993/1016/sys/src/9/port/cache.c:439,449 | ||
| 1993/1014 | 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/1015/sys/src/9/port/cache.c:483,488 – 1993/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,523 – 1993/1016/sys/src/9/port/cache.c:498,504 | ||
| 1993/1015 | if(ee > offset) { o = ee - offset; p->len -= o; | |
| 1993/1016 | if(p->len == 0) | |
| 1993/1015 | panic("del empty extent"); } } | |
| 1993/1015/sys/src/9/port/cache.c:531,542 – 1993/1016/sys/src/9/port/cache.c:512,525 | ||
| 1993/1015 | } e = cchain(buf, offset, len, &tail); | |
| 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,47 – 1993/1017/sys/src/9/port/cache.c:41,48 (short | long) | ||
| 1993/1013 | typedef struct Cache Cache; struct Cache | |
| 1993/1011 | { | |
| 1993/1013 |
| |
| 1993/1017 | Lock; int pgno; | |
| 1993/1013 | Mntcache *head; Mntcache *tail; Mntcache *hash[NHASH]; | |
| 1993/1016/sys/src/9/port/cache.c:54,60 – 1993/1017/sys/src/9/port/cache.c:55,60 | ||
| 1993/1014 | int i; Mntcache *m; | |
| 1993/1016/sys/src/9/port/cache.c:70,84 – 1993/1017/sys/src/9/port/cache.c:70,86 | ||
| 1993/1014 | } | |
| 1993/1013 | void | |
| 1993/1015 |
| |
| 1993/1017 | cprint(Chan *c, Mntcache *m, char *s) | |
| 1993/1014 | { Extent *e; | |
| 1993/1017 | char buf[128]; | |
| 1993/1016 | ||
| 1993/1015 |
| |
| 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 |
| |
| 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,144 – 1993/1017/sys/src/9/port/cache.c:140,146 | ||
| 1993/1013 | { Mntcache *m, *f, **l; | |
| 1993/1015 |
| |
| 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,213 – 1993/1017/sys/src/9/port/cache.c:209,215 | ||
| 1993/1013 | Page *p; Mntcache *m; | |
| 1993/1014 | Extent *e, **t; | |
| 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,236 – 1993/1017/sys/src/9/port/cache.c:224,233 | ||
| 1993/1013 | return 0; } | |
| 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 |
| |
| 1993/1014 | t = &e->next; | |
| 1993/1013 | } | |
| 1993/1016/sys/src/9/port/cache.c:277,282 – 1993/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,315 – 1993/1017/sys/src/9/port/cache.c:307,316 | ||
| 1993/1015 | e->cache = p; e->start = offset; e->len = l; | |
| 1993/1014 |
| |
| 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,466 – 1993/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); | |
| 1993/1016/sys/src/9/port/cache.c:485,494 – 1993/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) { | |
| 1993/1017 | if(f->start >= offset) | |
| 1993/1015 | break; p = f; } | |
| 1993/1016/sys/src/9/port/cache.c:501,506 – 1993/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,525 – 1993/1017/sys/src/9/port/cache.c:537,540 | ||
| 1993/1016 | tail->next = f; } | |
| 1993/1015 | qunlock(m); | |
| 1993/1011 | } | |
| 1993/1017/sys/src/9/port/cache.c:72,87 – 1993/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)); | |
| 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 |
| |
| 1993/1017 |
| |
| 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,137 – 1993/1018/sys/src/9/port/cache.c:143,152 | ||
| 1993/1013 | cache.tail = m; } else { | |
| 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,150 – 1993/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 |
| |
| 1993/1018 | if(c->qid.path&CHDIR) | |
| 1993/1015 | return; | |
| 1993/1018 | h = c->qid.path%NHASH; | |
| 1993/1016 | lock(&cache); | |
| 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,163 – 1993/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); | |
| 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,191 – 1993/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 |
| |
| 1993/1018 | *l = m->hash; | |
| 1993/1013 | break; } | |
| 1993/1016 | l = &f->hash; | |
| 1993/1013 | } | |
| 1993/1016 |
| |
| 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); | |
| 1993/1013 |
| |
| 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,204 – 1993/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 |
| |
| 1993/1013 |
| |
| 1993/1018 | if(m->vers != c->qid.vers) return 0; | |
| 1993/1013 | return 1; } | |
| 1993/1017/sys/src/9/port/cache.c:211,219 – 1993/1018/sys/src/9/port/cache.c:239,244 | ||
| 1993/1014 | Extent *e, **t; | |
| 1993/1017 | int o, l, total; | |
| 1993/1013 | ||
| 1993/1015 |
| |
| 1993/1013 | m = c->mcp; if(m == 0) return 0; | |
| 1993/1017/sys/src/9/port/cache.c:226,232 – 1993/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 |
| |
| 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,280 – 1993/1018/sys/src/9/port/cache.c:299,305 | ||
| 1993/1013 | if(e == 0 || e->start != offset) break; } | |
| 1993/1017 |
| |
| 1993/1018 | ||
| 1993/1014 | qunlock(m); | |
| 1993/1013 | return total; } | |
| 1993/1017/sys/src/9/port/cache.c:307,316 – 1993/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,356 – 1993/1018/sys/src/9/port/cache.c:377,383 | ||
| 1993/1014 | } | |
| 1993/1013 | void | |
| 1993/1016 |
| |
| 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,469 – 1993/1018/sys/src/9/port/cache.c:485,490 | ||
| 1993/1015 | } void | |
| 1993/1016 |
| |
| 1993/1015 | cwrite(Chan* c, uchar *buf, int len, ulong offset) { int o; | |
| 1993/1017/sys/src/9/port/cache.c:502,507 – 1993/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,560 – 1993/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,82 – 1993/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 |
| |
| 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,184 – 1993/1028/sys/src/9/port/cache.c:175,181 | ||
| 1993/1016 | qlock(m); cnodata(m); qunlock(m); | |
| 1993/1018 |
| |
| 1993/1016 | } | |
| 1993/1018 |
| |
| 1993/1016 | return; | |
| 1993/1015 | } | |
| 1993/1013 | } | |
| 1993/1022/sys/src/9/port/cache.c:213,219 – 1993/1028/sys/src/9/port/cache.c:210,215 | ||
| 1993/1018 | free(e); e = next; } | |
| 1993/1013 | } static int | |
| 1993/1028/sys/src/9/port/cache.c:80,85 – 1993/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,98 – 1993/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) { | |
| 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,273 – 1994/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,290 – 1994/0728/sys/src/9/port/cache.c:281,291 | ||
| 1993/1013 | nexterror(); } | |
| 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,343 – 1994/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,372 – 1994/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,72 – 1994/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,10 – 1996/0223/sys/src/9/port/cache.c:4,9 (short | long) | ||
| 1993/1011 | #include "dat.h" #include "fns.h" #include "../port/error.h" | |
| 1993/1013 | Image fscache; | |
| 1996/0223/sys/src/9/port/cache.c:498,504 – 1996/0326/sys/src/9/port/cache.c:498,504 (short | long) | ||
| 1993/1015 | void cwrite(Chan* c, uchar *buf, int len, ulong offset) { | |
| 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,529 – 1996/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,548 – 1996/0329/sys/src/9/port/cache.c:526,544 (short | long) | ||
| 1993/1015 | p = f; | |
| 1996/0326 | } | |
| 1996/0329 | if(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 | } | |
| 1996/0329/sys/src/9/port/cache.c:526,532 – 1996/0402/sys/src/9/port/cache.c:526,532 (short | long) | ||
| 1993/1015 | p = f; | |
| 1996/0326 | } | |
| 1996/0329 |
| |
| 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,207 – 1997/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,217 – 1997/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,237 – 1998/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 |
| |
| 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,244 – 1998/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,254 – 1998/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,403 – 1998/0327/sys/src/9/port/cache.c:395,409 | ||
| 1993/1014 | } | |
| 1993/1013 | void | |
| 1993/1018 |
| |
| 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 |
| |
| 1998/0327 | if(off > MAXCACHE || len == 0) | |
| 1993/1015 | return; | |
| 1993/1013 | m = c->mcp; | |
| 1997/0327/sys/src/9/port/cache.c:412,417 – 1998/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,511 – 1998/0327/sys/src/9/port/cache.c:505,519 | ||
| 1993/1015 | } void | |
| 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 |
| |
| 1998/0327 | if(off > MAXCACHE || len == 0) | |
| 1993/1015 | return; m = c->mcp; | |
| 1997/0327/sys/src/9/port/cache.c:518,523 – 1998/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,62 – 1998/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,135 – 1998/0512/sys/src/9/port/cache.c:129,135 | ||
| 1993/1016 | ctail(Mntcache *m) | |
| 1993/1013 | { /* Unlink and send to the tail */ | |
| 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,540 – 1998/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; | |
| 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,17 – 1999/0508/sys/src/9/port/cache.c:5,16 (short | long) | ||
| 1993/1011 | #include "fns.h" #include "../port/error.h" | |
| 1993/1013 |
| |
| 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,53 – 1999/0508/sys/src/9/port/cache.c:45,105 | ||
| 1993/1013 | Mntcache *tail; Mntcache *hash[NHASH]; | |
| 1993/1011 | }; | |
| 1993/1013 |
| |
| 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,126 – 1999/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 |
| |
| 1999/0508 | extentfree(e); | |
| 1993/1013 | } | |
| 1993/1015 | m->list = 0; | |
| 1993/1013 | } | |
| 1998/0512/sys/src/9/port/cache.c:210,216 – 1999/0508/sys/src/9/port/cache.c:262,268 | ||
| 1993/1016 | ||
| 1993/1018 | while(e) { next = e->next; | |
| 1999/0508 | extentfree(e); | |
| 1993/1018 | e = next; } | |
| 1997/0327 | qunlock(m); | |
| 1998/0512/sys/src/9/port/cache.c:271,277 – 1999/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 |
| |
| 1999/0508 | extentfree(e); | |
| 1993/1013 | qunlock(m); return total; } | |
| 1998/0512/sys/src/9/port/cache.c:322,334 – 1999/0508/sys/src/9/port/cache.c:374,386 | ||
| 1993/1016 | *tail = 0; | |
| 1993/1014 | t = &start; while(len) { | |
| 1999/0508 | e = extentalloc(); | |
| 1993/1014 | if(e == 0) break; p = auxpage(); if(p == 0) { | |
| 1999/0508 | extentfree(e); | |
| 1993/1014 | break; } l = len; | |
| 1998/0512/sys/src/9/port/cache.c:583,589 – 1999/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; | |
| 1999/0508 | extentfree(f); | |
| 1993/1015 | f = e; } | |
| 1999/0508/sys/src/9/port/cache.c:128,136 – 1999/0629/sys/src/9/port/cache.c:128,134 (short | long) | ||
| 1993/1018 | ulong o; int nb, ct; | |
| 1993/1014 | Extent *e; | |
| 1993/1017 |
| |
| 1993/1028 | ||
| 1993/1017 |
| |
| 1993/1018 | nb = 0; ct = 1; | |
| 1993/1103 | o = 0; | |
| 1999/0508/sys/src/9/port/cache.c:143,149 – 1999/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", | |
| 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,63 – 1999/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,114 – 1999/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,296 – 1999/0903/sys/src/9/port/cache.c:294,300 | ||
| 1993/1017 | int o, l, total; | |
| 1998/0327 | ulong offset; | |
| 1993/1013 | ||
| 1998/0327 |
| |
| 1999/0903 | if(off+len > maxcache) | |
| 1998/0327 | return 0; | |
| 1993/1013 | m = c->mcp; | |
| 1999/0629/sys/src/9/port/cache.c:453,459 – 1999/0903/sys/src/9/port/cache.c:457,463 | ||
| 1993/1015 | int o, ee, eblock; | |
| 1998/0327 | ulong offset; | |
| 1993/1013 | ||
| 1998/0327 |
| |
| 1999/0903 | if(off > maxcache || len == 0) | |
| 1993/1015 | return; | |
| 1993/1013 | m = c->mcp; | |
| 1999/0629/sys/src/9/port/cache.c:563,569 – 1999/0903/sys/src/9/port/cache.c:567,573 | ||
| 1993/1015 | Extent *p, *f, *e, *tail; | |
| 1998/0327 | ulong offset; | |
| 1993/1015 | ||
| 1998/0327 |
| |
| 1999/0903 | if(off > maxcache || len == 0) | |
| 1993/1015 | return; m = c->mcp; | |
| 1999/0903/sys/src/9/port/cache.c:396,401 – 1999/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,402 – 1999/1101/sys/src/9/port/cache.c:396,402 (short | long) | ||
| 1993/1017 | lock(&cache); e->bid = cache.pgno; cache.pgno += BY2PG; | |
| 1999/1022 |
| |
| 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,508 – 1999/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) { | |
| 1999/1227 | if(f->start > offset) | |
| 1993/1014 | break; p = f; } | |
| 1993/1015 | ||
| 1993/1014 |
| |
| 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; | |
| 1999/1227 | tail->next = f; | |
| 1993/1016 | } | |
| 1993/1014 | qunlock(m); return; | |
| 1999/1101/sys/src/9/port/cache.c:532,537 – 1999/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,568 – 1999/1227/sys/src/9/port/cache.c:539,549 | ||
| 1993/1014 | } | |
| 1993/1013 | } | |
| 1993/1014 |
| |
| 1993/1016 |
| |
| 1993/1014 |
| |
| 1993/1015 |
| |
| 1993/1014 |
| |
| 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,575 – 1999/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 |
| |
| 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,648 – 1999/1227/sys/src/9/port/cache.c:580,605 | ||
| 1998/0512 | p = f; | |
| 1996/0326 | } | |
| 1996/0402 |
| |
| 1996/0326 |
| |
| 1996/0329 |
| |
| 1996/0326 |
| |
| 1993/1015 |
| |
| 1993/1016 |
| |
| 1993/1015 |
| |
| 1993/1018 |
| |
| 1993/1017 |
| |
| 1999/1227 | eo = offset - p->start; /* pack in predecessor if there is space */ if(offset <= ee && eo < BY2PG) { | |
| 1993/1017 | o = len; | |
| 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; | |
| 1993/1015 | } | |
| 1999/1227 | /* free the overlap -- it's a rare case */ | |
| 1993/1015 | eblock = offset+len; | |
| 1999/0508 | extentfree(f); | |
| 1999/1101/sys/src/9/port/cache.c:649,663 – 1999/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) { | |
| 1993/1022 | ||
| 1993/1016 |
| |
| 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,117 – 2000/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. | ||