diff options
| -rw-r--r-- | sys/src/cmd/upas/fs/cache.c | 56 | ||||
| -rw-r--r-- | sys/src/cmd/upas/fs/dat.h | 20 | ||||
| -rw-r--r-- | sys/src/cmd/upas/fs/fs.c | 156 | ||||
| -rw-r--r-- | sys/src/cmd/upas/fs/idx.c | 10 | ||||
| -rw-r--r-- | sys/src/cmd/upas/fs/mbox.c | 146 | ||||
| -rw-r--r-- | sys/src/cmd/upas/fs/mkfile | 2 |
6 files changed, 189 insertions, 201 deletions
diff --git a/sys/src/cmd/upas/fs/cache.c b/sys/src/cmd/upas/fs/cache.c index 8ac23a1ad..6620670fa 100644 --- a/sys/src/cmd/upas/fs/cache.c +++ b/sys/src/cmd/upas/fs/cache.c @@ -31,17 +31,29 @@ notecache(Mailbox *mb, Message *m, long sz) addlru(mb, m); } -static void -cachefree0(Mailbox *mb, Message *m, int force) +void +cachefree(Mailbox *mb, Message *m, int force) { - long sz, i; - Message *s; + long i; + Message *s, **ll; if(!force && mb->fetch == nil) return; + if(Topmsg(mb, m)){ + for(ll = &mb->lru; *ll != nil; ll = &((*ll)->lru)){ + if(*ll == m){ + mb->nlru--; + *ll = m->lru; + m->lru = nil; + break; + } + } + if(mb->decache) + mb->decache(mb, m); + mb->cached -= m->csize; + } for(s = m->part; s; s = s->next) cachefree(mb, s, force); - dprint("cachefree: %D %p, %p\n", m->fileid, m, m->start); if(m->mallocd){ free(m->start); m->mallocd = 0; @@ -58,7 +70,6 @@ cachefree0(Mailbox *mb, Message *m, int force) free(m->references[i]); m->references[i] = 0; } - sz = m->csize; m->csize = 0; m->start = 0; m->end = 0; @@ -69,30 +80,10 @@ cachefree0(Mailbox *mb, Message *m, int force) m->bend = 0; m->mheader = 0; m->mhend = 0; - if(mb->decache) - mb->decache(mb, m); m->decoded = 0; m->converted = 0; m->badchars = 0; m->cstate &= ~(Cheader|Cbody); - if(Topmsg(mb, m)) - mb->cached -= sz; -} - -void -cachefree(Mailbox *mb, Message *m, int force) -{ - Message **ll; - - for(ll = &mb->lru; *ll != nil; ll = &((*ll)->lru)){ - if(*ll == m){ - mb->nlru--; - *ll = m->lru; - m->lru = nil; - break; - } - } - cachefree0(mb, m, force); } void @@ -277,7 +268,8 @@ middlecache(Mailbox *mb, Message *m) } if(y == 0) return 0; - dprint("middlecache %d [%D] %lud %lud\n", m->id, m->fileid, (ulong)(m->end - m->start), m->size); + dprint("middlecache %lud [%D] %lud %lud\n", + m->id, m->fileid, (ulong)(m->end - m->start), m->size); return cachebody(mb, m); } @@ -292,7 +284,7 @@ cacheheaders(Mailbox *mb, Message *m) return 0; if(!Topmsg(mb, m)) return middlecache(mb, m); - dprint("cacheheaders %d %D\n", m->id, m->fileid); + dprint("cacheheaders %lud %D\n", m->id, m->fileid); if(m->size < 10000) r = fetch(mb, m, 0, m->size); else for(r = 0; (o = m->end - m->start) < m->size; ){ @@ -327,7 +319,7 @@ digestmessage(Mailbox *mb, Message *m) m->deleted = Dup; /* no dups allowed */ }else mtreeadd(mb, m); - dprint("%d %#A\n", m->id, m->digest); + dprint("%lud %#A\n", m->id, m->digest); } int @@ -337,10 +329,10 @@ cachebody(Mailbox *mb, Message *m) while(!Topmsg(mb, m)) m = m->whole; - if(!mb->fetch || m->cstate&Cbody) + if(mb->fetch == nil || m->cstate&Cbody) return 0; o = m->end - m->start; - dprint("cachebody %d [%D] %lud %lud %s", m->id, m->fileid, o, m->size, cstate(m)); + dprint("cachebody %lud [%D] %lud %lud %s", m->id, m->fileid, o, m->size, cstate(m)); if(o < m->size) if(fetch(mb, m, o, m->size - o) < 0) return -1; @@ -389,7 +381,7 @@ insurecache(Mailbox *mb, Message *m) { if(m->deleted || !m->inmbox) return -1; - msgincref(m); + msgincref(mb, m); cacheidx(mb, m); if((m->cstate & Cidx) == 0){ logmsg(m, "%s: can't cache: %s: %r", mb->path, m->name); diff --git a/sys/src/cmd/upas/fs/dat.h b/sys/src/cmd/upas/fs/dat.h index ff55a9960..653232383 100644 --- a/sys/src/cmd/upas/fs/dat.h +++ b/sys/src/cmd/upas/fs/dat.h @@ -74,7 +74,7 @@ struct Idx { typedef struct Message Message; struct Message { - int id; + ulong id; int refs; int subname; char name[12]; @@ -152,7 +152,7 @@ typedef struct Mailbox Mailbox; struct Mailbox { int refs; Mailbox *next; - int id; + ulong id; int flags; char rmflags; char dolock; /* lock when syncing? */ @@ -209,7 +209,6 @@ int insurecache(Mailbox*, Message*); void putcache(Mailbox*, Message*); /* asymmetricial */ void cachefree(Mailbox*, Message*, int); -Message* gettopmsg(Mailbox*, Message*); char* syncmbox(Mailbox*, int); void* emalloc(ulong); void* erealloc(void*, ulong); @@ -223,13 +222,12 @@ int wraptls(int, char*); void eprint(char*, ...); void iprint(char *, ...); -int newid(void); char* newmbox(char*, char*, int, Mailbox**); void freembox(char*); char* removembox(char*, int); void syncallmboxes(void); void logmsg(Message*, char*, ...); -void msgincref(Message*); +void msgincref(Mailbox*, Message*); void msgdecref(Mailbox*, Message*); void mboxincref(Mailbox*); void mboxdecref(Mailbox*); @@ -306,7 +304,7 @@ enum { Qmboxctl, }; -#define PATH(id, f) ((((id) & 0xfffff)<<10) | (f)) +#define PATH(id, f) (((uvlong)(id)<<10) | (f)) #define FILE(p) ((p) & 0x3ff) /* hash table to aid in name lookup, all files have an entry */ @@ -314,16 +312,16 @@ typedef struct Hash Hash; struct Hash { Hash *next; char *name; - ulong ppath; + uvlong ppath; Qid qid; Mailbox *mb; Message *m; }; -uint hash(char*); -Hash *hlook(ulong, char*); -void henter(ulong, char*, Qid, Message*, Mailbox*); -void hfree(ulong, char*); +ulong hash(char*); +Hash *hlook(uvlong, char*); +void henter(uvlong, char*, Qid, Message*, Mailbox*); +void hfree(uvlong, char*); char *intern(char*); void idxfree(Idx*); diff --git a/sys/src/cmd/upas/fs/fs.c b/sys/src/cmd/upas/fs/fs.c index 9f7ba2b64..52e7cc6ab 100644 --- a/sys/src/cmd/upas/fs/fs.c +++ b/sys/src/cmd/upas/fs/fs.c @@ -14,7 +14,6 @@ struct Fid Fid *next; Mailbox *mb; Message *m; - Message *mtop; /* top level message */ long foff; /* offset/DIRLEN of finger */ Message *fptr; /* pointer to message at off */ @@ -132,8 +131,6 @@ static QLock synclock; void sanemsg(Message *m) { - assert(m->refs < 100); - assert(m->next != m); if(m->end < m->start) abort(); if(m->ballocd && (m->start <= m->body && m->end >= m->body)) @@ -769,13 +766,10 @@ doclone(Fid *f, int nfid) return nil; nf->busy = 1; nf->open = 0; - nf->mb = f->mb; - if(nf->mb) + if(nf->mb = f->mb) mboxincref(nf->mb); if(nf->m = f->m) - msgincref(gettopmsg(nf->mb, nf->m)); - if(nf->mtop = f->mtop) - msgincref(nf->mtop); + msgincref(nf->mb, nf->m); nf->qid = f->qid; return nf; } @@ -798,9 +792,10 @@ dowalk(Fid *f, char *name) { char *rv, *p; int t, t1; - Mailbox *mb; Hash *h; + if(f->qid.type != QTDIR) + return Enotdir; t = FILE(f->qid.path); rv = Enotexist; @@ -815,26 +810,16 @@ retry: }else h = hlook(f->qid.path, name); if(h != nil){ + if(h->mb) + mboxincref(h->mb); + if(h->m) + msgincref(h->mb, h->m); if(f->m) - msgdecref(f->mb, gettopmsg(f->mb, f->m)); - if(f->mb && f->mb != h->mb) + msgdecref(f->mb, f->m); + if(f->mb) mboxdecref(f->mb); - f->mb = h->mb; f->m = h->m; - if(f->m) - msgincref(gettopmsg(f->mb, f->m)); - switch(t){ - case Qtop: - if(f->mb) - mboxincref(f->mb); - break; - case Qmbox: - if(f->m){ - msgincref(f->m); - f->mtop = f->m; - } - break; - } + f->mb = h->mb; f->qid = h->qid; if(t1 < Qmax) f->qid.path = PATH(f->m->id, t1); /* sleezy speedup */ @@ -842,18 +827,9 @@ retry: }else if((p = strchr(name, '.')) != nil && *name != '.'){ *p = 0; goto retry; - } - - if(rv == nil) - return rv; - - if(strcmp(name, ".") == 0) - return nil; - - if(f->qid.type != QTDIR) - return Enotdir; - - if(strcmp(name, "..") == 0){ + } else if(strcmp(name, ".") == 0){ + rv = nil; + } else if(strcmp(name, "..") == 0){ switch(t){ case Qtop: f->qid.path = PATH(0, Qtop); @@ -864,20 +840,19 @@ retry: f->qid.path = PATH(0, Qtop); f->qid.type = QTDIR; f->qid.vers = 0; - mb = f->mb; + mboxdecref(f->mb); f->mb = nil; - mboxdecref(mb); break; case Qdir: if(Topmsg(f->mb, f->m)){ f->qid.path = PATH(f->mb->id, Qmbox); f->qid.type = QTDIR; f->qid.vers = f->mb->vers; - msgdecref(f->mb, f->mtop); msgdecref(f->mb, f->m); - f->m = f->mtop = nil; + f->m = nil; } else { - /* refs don't change; still the same message */ + msgincref(f->mb, f->m->whole); + msgdecref(f->mb, f->m); f->m = f->m->whole; f->qid.path = PATH(f->m->id, Qdir); f->qid.type = QTDIR; @@ -987,6 +962,8 @@ readtopdir(Fid*, uchar *buf, long off, int cnt, int blen) pos += m; for(mb = mbl; mb != nil; mb = mb->next){ + assert(mb->refs > 0); + mkstat(&d, mb, nil, Qmbox); m = convD2M(&d, &buf[n], blen - n); if(off <= pos){ @@ -1008,6 +985,8 @@ readmboxdir(Fid *f, uchar *buf, long off, int cnt, int blen) long pos; Message *msg; + assert(f->mb->refs > 0); + if(off == 0) syncmbox(f->mb, 1); @@ -1198,7 +1177,6 @@ rwrite(Fid *f) { char *argvbuf[1024], **argv, file[Pathlen], *err, *v0; int i, t, argc, flags; - Message *m; t = FILE(f->qid.path); rhdr.count = thdr.count; @@ -1288,21 +1266,19 @@ rwrite(Fid *f) } return Ebadctl; case Qmboxctl: - if(f->mb && f->mb->ctl){ - argc = tokenize(thdr.data, argv, nelem(argvbuf)); - if(argc == 0) - return Ebadctl; - return f->mb->ctl(f->mb, argc, argv); - } - break; + if(f->mb->ctl == nil) + break; + argc = tokenize(thdr.data, argv, nelem(argvbuf)); + if(argc == 0) + return Ebadctl; + return f->mb->ctl(f->mb, argc, argv); case Qflags: /* * modifying flags on subparts is a little strange. */ - if(!f->mb || !f->m) + if(!Topmsg(f->mb, f->m)) break; - m = gettopmsg(f->mb, f->m); - return modflags(f->mb, m, thdr.data); + return modflags(f->mb, f->m, thdr.data); } return Eperm; } @@ -1310,21 +1286,17 @@ rwrite(Fid *f) char* rclunk(Fid *f) { - Mailbox *mb; - f->busy = 1; /* coherence(); */ f->fid = -1; f->open = 0; - mb = f->mb; - if(f->mtop) - msgdecref(mb, f->mtop); - if(f->m) - msgdecref(mb, gettopmsg(mb, f->m)); - f->m = f->mtop = nil; - if(mb){ + if(f->m != nil){ + msgdecref(f->mb, f->m); + f->m = nil; + } + if(f->mb != nil){ + mboxdecref(f->mb); f->mb = nil; - mboxdecref(mb); } f->busy = 0; return 0; @@ -1333,7 +1305,7 @@ rclunk(Fid *f) char * rremove(Fid *f) { - if(f->m != nil && f->m->deleted == 0) + if(f->mb != nil && f->m != nil && Topmsg(f->mb, f->m) && f->m->deleted == 0) f->m->deleted = Deleted; return rclunk(f); } @@ -1357,6 +1329,28 @@ rwstat(Fid*) return Eperm; } +static Fid* +checkfid(Fid *f) +{ + switch(FILE(f->qid.path)){ + case Qtop: + case Qctl: + assert(f->mb == nil); + assert(f->m == nil); + break; + case Qmbox: + case Qmboxctl: + assert(f->mb != nil && f->mb->refs > 0); + assert(f->m == nil); + break; + default: + assert(f->mb != nil && f->mb->refs > 0); + assert(f->m != nil && f->m->refs > 0); + break; + } + return f; +} + Fid* newfid(int fid) { @@ -1365,7 +1359,7 @@ newfid(int fid) ff = 0; for(f = fids; f; f = f->next) if(f->fid == fid) - return f; + return checkfid(f); else if(!ff && !f->busy) ff = f; if(ff){ @@ -1475,20 +1469,6 @@ reader(void) } } -int -newid(void) -{ - int rv; - static int id; - static Lock idlock; - - lock(&idlock); - rv = ++id; - unlock(&idlock); - - return rv; -} - void error(char *s) { @@ -1600,10 +1580,10 @@ readheader(Message *m, char *buf, int off, int cnt) return to - buf; } -uint +ulong hash(char *s) { - uint c, h; + ulong c, h; h = 0; while(c = *s++) @@ -1613,9 +1593,9 @@ hash(char *s) } Hash* -hlook(ulong ppath, char *name) +hlook(uvlong ppath, char *name) { - int h; + ulong h; Hash *hp; h = (hash(name)+ppath) % nelem(htab); @@ -1626,9 +1606,9 @@ hlook(ulong ppath, char *name) } void -henter(ulong ppath, char *name, Qid qid, Message *m, Mailbox *mb) +henter(uvlong ppath, char *name, Qid qid, Message *m, Mailbox *mb) { - int h; + ulong h; Hash *hp, **l; h = (hash(name)+ppath) % nelem(htab); @@ -1650,9 +1630,9 @@ henter(ulong ppath, char *name, Qid qid, Message *m, Mailbox *mb) } void -hfree(ulong ppath, char *name) +hfree(uvlong ppath, char *name) { - int h; + ulong h; Hash *hp, **l; h = (hash(name)+ppath) % nelem(htab); diff --git a/sys/src/cmd/upas/fs/idx.c b/sys/src/cmd/upas/fs/idx.c index 975211760..cce59c1b5 100644 --- a/sys/src/cmd/upas/fs/idx.c +++ b/sys/src/cmd/upas/fs/idx.c @@ -366,18 +366,20 @@ dead: /* * read in mutable information. * currently this is only flags + * and nparts. */ redux++; if(level == 0) m->deleted &= ~Dmark; - if(m->nparts) + n = m->nparts; + m->nparts = strtoul(f[21], 0, 0); if(rdidx(b, mb, m, m->nparts, level + 1) == -1) goto dead; ll = &m->next; - idprint("%d seen before %d... %.2ux", level, m->id, m->cstate); + idprint("%d seen before %lud... %.2ux", level, m->id, m->cstate); flags = m->flags; m->flags |= strtoul(f[1], 0, 16); - if(flags != m->flags) + if(flags != m->flags || n != m->nparts) m->cstate |= Cidxstale; m->cstate |= Cidx; idprint("→%.2ux\n", m->cstate); @@ -385,7 +387,7 @@ dead: continue; } m = newmessage(parent); - idprint("%d new %d %#A\n", level, m->id, digest); + idprint("%d new %lud %#A\n", level, m->id, digest); m->digest = digest; m->flags = strtoul(f[1], 0, 16); m->fileid = rdfileid(f[2], level); diff --git a/sys/src/cmd/upas/fs/mbox.c b/sys/src/cmd/upas/fs/mbox.c index 9c6e23c02..a77996fd4 100644 --- a/sys/src/cmd/upas/fs/mbox.c +++ b/sys/src/cmd/upas/fs/mbox.c @@ -191,6 +191,20 @@ initheaders(void) head[i].len = strlen(head[i].type); } +static ulong +newid(void) +{ + ulong rv; + static ulong id; + static Lock idlock; + + lock(&idlock); + rv = ++id; + unlock(&idlock); + + return rv; +} + char* newmbox(char *path, char *name, int flags, Mailbox **r) { @@ -271,50 +285,42 @@ freembox(char *name) { Mailbox **l, *mb; - for(l=&mbl; *l != nil; l=&(*l)->next) - if(strcmp(name, (*l)->name) == 0){ - mb = *l; + for(l = &mbl; (mb = *l) != nil; l = &mb->next) + if(strcmp(name, mb->name) == 0){ *l = mb->next; + mb->next = nil; + hfree(PATH(0, Qtop), mb->name); + if(mb->ctl) + hfree(PATH(mb->id, Qmbox), "ctl"); mboxdecref(mb); break; } - hfree(PATH(0, Qtop), name); -} - -void -syncallmboxes(void) -{ - char *err; - Mailbox *m; - - for(m = mbl; m != nil; m = m->next) - if(err = syncmbox(m, 0)) - eprint("syncmbox: %s\n", err); } - char* removembox(char *name, int flags) { - int found; - Mailbox **l, *mb; + Mailbox *mb; - found = 0; - for(l=&mbl; *l != nil; l=&(*l)->next) - if(strcmp(name, (*l)->path) == 0){ - mb = *l; - *l = mb->next; + for(mb = mbl; mb != nil; mb = mb->next) + if(strcmp(name, mb->path) == 0){ mb->flags |= ORCLOSE; mb->rmflags = flags; - mboxdecref(mb); - found = 1; - break; + freembox(mb->name); + return 0; } - hfree(PATH(0, Qtop), name); + return "maibox not found"; +} - if(found == 0) - return "maibox not found"; - return 0; +void +syncallmboxes(void) +{ + Mailbox *mb; + char *err; + + for(mb = mbl; mb != nil; mb = mb->next) + if(err = syncmbox(mb, 0)) + eprint("syncmbox: %s\n", err); } /* @@ -347,7 +353,7 @@ rxtotm(Message *m, Tm *tm) return r; } -Message* +static Message* gettopmsg(Mailbox *mb, Message *m) { while(!Topmsg(mb, m)) @@ -355,7 +361,7 @@ gettopmsg(Mailbox *mb, Message *m) return m; } -void +static void datesec(Mailbox *mb, Message *m) { vlong v; @@ -1011,31 +1017,32 @@ delmessage(Mailbox *mb, Message *m) { Message **l; + assert(m->refs == 0); + while(m->part) + delmessage(mb, m->part); + mb->vers++; msgfreed++; - if(m->whole != m){ + if(m != m->whole){ /* unchain from parent */ for(l = &m->whole->part; *l && *l != m; l = &(*l)->next) ; if(*l != nil) *l = m->next; - + m->next = nil; /* clear out of name lookup hash table */ if(m->whole->whole == m->whole) hfree(PATH(mb->id, Qmbox), m->name); else hfree(PATH(m->whole->id, Qdir), m->name); hfree(PATH(m->id, Qdir), "xxx"); /* sleezy speedup */ - } - if(Topmsg(mb, m)){ - if(m != mb->root) + + if(Topmsg(mb, m)) mtreedelete(mb, m); cachefree(mb, m, 1); + idxfree(m); } - idxfree(m); - while(m->part) - delmessage(mb, m->part); free(m->unixfrom); free(m->unixheader); free(m->date822); @@ -1093,7 +1100,7 @@ flagmessages(int argc, char **argv) if(argc%2) return "bad flags"; - for(mb = mbl; mb; mb = mb->next) + for(mb = mbl; mb != nil; mb = mb->next) if(strcmp(*argv, mb->name) == 0) break; if(mb == nil) @@ -1114,21 +1121,33 @@ flagmessages(int argc, char **argv) } void -msgincref(Message *m) +msgincref(Mailbox *mb, Message *m) { - m->refs++; + assert(mb->refs > 0); + for(;; m = m->whole){ + assert(m->refs >= 0); + m->refs++; + if(Topmsg(mb, m)) + break; + } } void msgdecref(Mailbox *mb, Message *m) { - assert(m->refs > 0); - m->refs--; - if(m->refs == 0){ - if(m->deleted) - syncmbox(mb, 1); - else - putcache(mb, m); + assert(mb->refs >= 0); + for(;; m = m->whole){ + assert(m->refs > 0); + m->refs--; + if(Topmsg(mb, m)){ + if(m->refs == 0){ + if(m->deleted) + syncmbox(mb, 1); + else + putcache(mb, m); + } + break; + } } } @@ -1156,21 +1175,18 @@ void mboxdecref(Mailbox *mb) { assert(mb->refs > 0); - mb->refs--; - if(mb->refs == 0){ - syncmbox(mb, 1); - delmessage(mb, mb->root); - if(mb->ctl) - hfree(PATH(mb->id, Qmbox), "ctl"); - if(mb->close) - mb->close(mb); - if(mb->flags & ORCLOSE && mb->remove) - if(mb->remove(mb, mb->rmflags)) - rmidx(mb->path, mb->rmflags); - free(mb->mtree); - free(mb->d); - free(mb); - } + if(--mb->refs) + return; + syncmbox(mb, 1); + delmessage(mb, mb->root); + if(mb->close) + mb->close(mb); + if(mb->flags & ORCLOSE && mb->remove) + if(mb->remove(mb, mb->rmflags)) + rmidx(mb->path, mb->rmflags); + free(mb->mtree); + free(mb->d); + free(mb); } diff --git a/sys/src/cmd/upas/fs/mkfile b/sys/src/cmd/upas/fs/mkfile index 28bf669e9..bbf141fc3 100644 --- a/sys/src/cmd/upas/fs/mkfile +++ b/sys/src/cmd/upas/fs/mkfile @@ -1,7 +1,7 @@ </$objtype/mkfile <../mkupas -TARG= fs\ +TARG=fs OFILES=\ cache.$O\ |
