X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fport%2Fchan.c;h=cce88ba3e4d6c1e21fa9c7e10782d15fa5c2a32f;hb=a609c1a2f8d58d21727c13970725445ce4d2f6fa;hp=9577eb8d30fc8299bebafd5eb158953ae14467ef;hpb=c4153b7755e3a4f3cab57ad8cbe85d18cc7cbd77;p=plan9front.git diff --git a/sys/src/9/port/chan.c b/sys/src/9/port/chan.c index 9577eb8d3..cce88ba3e 100644 --- a/sys/src/9/port/chan.c +++ b/sys/src/9/port/chan.c @@ -5,9 +5,6 @@ #include "fns.h" #include "../port/error.h" -int chandebug=0; /* toggled by sysr1 */ -#define DBG if(chandebug)iprint - enum { PATHSLOP = 20, @@ -38,43 +35,6 @@ struct Elemlist #define SEP(c) ((c) == 0 || (c) == '/') -static void -dumpmount(void) /* DEBUGGING */ -{ - Pgrp *pg; - Mount *t; - Mhead **h, **he, *f; - - if(up == nil){ - print("no process for dumpmount\n"); - return; - } - pg = up->pgrp; - if(pg == nil){ - print("no pgrp for dumpmount\n"); - return; - } - rlock(&pg->ns); - if(waserror()){ - runlock(&pg->ns); - nexterror(); - } - - he = &pg->mnthash[MNTHASH]; - for(h = pg->mnthash; h < he; h++){ - for(f = *h; f; f = f->hash){ - print("head: %#p: %s %#llux.%lud %C %lud -> \n", f, - f->from->path->s, f->from->qid.path, - f->from->qid.vers, devtab[f->from->type]->dc, - f->from->dev); - for(t = f->mount; t; t = t->next) - print("\t%#p: %s (umh %#p) (path %#.8llux dev %C %lud)\n", t, t->to->path->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev); - } - } - poperror(); - runlock(&pg->ns); -} - char* chanpath(Chan *c) { @@ -96,25 +56,27 @@ isdotdot(char *p) long incref(Ref *r) { - long x; + long old, new; - lock(r); - x = ++r->ref; - unlock(r); - return x; + do { + old = r->ref; + new = old+1; + } while(!cmpswap(&r->ref, old, new)); + return new; } long decref(Ref *r) { - long x; - - lock(r); - x = --r->ref; - unlock(r); - if(x < 0) - panic("decref pc=%#p", getcallerpc(&r)); - return x; + long old, new; + + do { + old = r->ref; + if(old <= 0) + panic("decref pc=%#p", getcallerpc(&r)); + new = old-1; + } while(!cmpswap(&r->ref, old, new)); + return new; } /* @@ -194,6 +156,8 @@ chandevreset(void) devtab[i]->reset(); } +static void closeproc(void*); + void chandevinit(void) { @@ -201,6 +165,7 @@ chandevinit(void) for(i=0; devtab[i] != nil; i++) devtab[i]->init(); + kproc("closeproc", closeproc, nil); } void @@ -222,20 +187,19 @@ newchan(void) lock(&chanalloc); c = chanalloc.free; - if(c != 0){ + if(c != nil){ chanalloc.free = c->next; - c->next = 0; - } - unlock(&chanalloc); - - if(c == nil){ + c->next = nil; + } else { + unlock(&chanalloc); c = smalloc(sizeof(Chan)); lock(&chanalloc); - c->fid = ++chanalloc.fid; c->link = chanalloc.list; chanalloc.list = c; - unlock(&chanalloc); } + if(c->fid == 0) + c->fid = ++chanalloc.fid; + unlock(&chanalloc); /* if you get an error before associating with a dev, close calls rootclose, a nop */ @@ -246,22 +210,24 @@ newchan(void) c->offset = 0; c->devoffset = 0; c->iounit = 0; - c->umh = 0; + c->umh = nil; + c->umc = nil; c->uri = 0; c->dri = 0; - c->aux = 0; - c->mchan = 0; - c->mcp = 0; - c->mux = 0; - memset(&c->mqid, 0, sizeof(c->mqid)); - c->path = 0; + c->dirrock = nil; + c->nrock = 0; + c->mrock = 0; c->ismtpt = 0; + c->mcp = nil; + c->mux = nil; + c->aux = nil; + c->mchan = nil; + memset(&c->mqid, 0, sizeof(c->mqid)); + c->path = nil; return c; } -Ref npath; - Path* newpath(char *s) { @@ -275,14 +241,13 @@ newpath(char *s) p->s = smalloc(p->alen); memmove(p->s, s, i+1); p->ref = 1; - incref(&npath); /* * Cannot use newpath for arbitrary names because the mtpt * array will not be populated correctly. The names #/ and / are * allowed, but other names with / in them draw warnings. */ - if(strchr(s, '/') && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0) + if(strchr(s, '/') != nil && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0) print("newpath: %s from %#p\n", s, getcallerpc(&s)); p->mlen = 1; @@ -299,8 +264,6 @@ copypath(Path *p) pp = smalloc(sizeof(Path)); pp->ref = 1; - incref(&npath); - DBG("copypath %s %p => %p\n", p->s, p, pp); pp->len = p->len; pp->alen = p->alen; @@ -312,7 +275,7 @@ copypath(Path *p) pp->mtpt = smalloc(p->malen*sizeof pp->mtpt[0]); for(i=0; imlen; i++){ pp->mtpt[i] = p->mtpt[i]; - if(pp->mtpt[i]) + if(pp->mtpt[i] != nil) incref(pp->mtpt[i]); } @@ -323,23 +286,14 @@ void pathclose(Path *p) { int i; - - if(p == nil) - return; -//XXX - DBG("pathclose %p %s ref=%ld =>", p, p->s, p->ref); - for(i=0; imlen; i++) - DBG(" %p", p->mtpt[i]); - DBG("\n"); - if(decref(p)) + if(p == nil || decref(p)) return; - decref(&npath); - free(p->s); for(i=0; imlen; i++) - if(p->mtpt[i]) + if(p->mtpt[i] != nil) cclose(p->mtpt[i]); free(p->mtpt); + free(p->s); free(p); } @@ -397,8 +351,9 @@ addelem(Path *p, char *s, Chan *from) p = uniquepath(p); i = strlen(s); - if(p->len+1+i+1 > p->alen){ - a = p->len+1+i+1 + PATHSLOP; + a = p->len+1+i+1; + if(a > p->alen){ + a += PATHSLOP; t = smalloc(a); memmove(t, p->s, p->len+1); free(p->s); @@ -412,8 +367,7 @@ addelem(Path *p, char *s, Chan *from) p->len += i; if(isdotdot(s)){ fixdotdotname(p); - DBG("addelem %s .. => rm %p\n", p->s, p->mtpt[p->mlen-1]); - if(p->mlen>1 && (c = p->mtpt[--p->mlen])){ + if(p->mlen > 1 && (c = p->mtpt[--p->mlen]) != nil){ p->mtpt[p->mlen] = nil; cclose(c); } @@ -425,9 +379,8 @@ addelem(Path *p, char *s, Chan *from) free(p->mtpt); p->mtpt = tt; } - DBG("addelem %s %s => add %p\n", p->s, s, from); p->mtpt[p->mlen++] = from; - if(from) + if(from != nil) incref(from); } return p; @@ -440,7 +393,7 @@ chanfree(Chan *c) if(c->dirrock != nil){ free(c->dirrock); - c->dirrock = 0; + c->dirrock = nil; c->nrock = 0; c->mrock = 0; } @@ -477,7 +430,7 @@ struct { Chan *head; Chan *tail; ulong nqueued; - ulong nclosed; + ulong nclosed; Lock l; QLock q; Rendez r; @@ -489,60 +442,72 @@ clunkwork(void*) return clunkq.head != nil; } -static void -closeproc(void*) -{ - Chan *c; - - for(;;){ - if(clunkq.head == nil){ - if(!waserror()){ - tsleep(&clunkq.r, clunkwork, nil, 5000); - poperror(); - } - } - qunlock(&clunkq.q); - lock(&clunkq.l); - c = clunkq.head; - if(c == nil){ - unlock(&clunkq.l); - pexit("no work", 1); - } - clunkq.head = c->next; - clunkq.nclosed++; - unlock(&clunkq.l); - if(!waserror()){ - devtab[c->type]->close(c); - poperror(); - } - chanfree(c); - qlock(&clunkq.q); - } -} - static void closechanq(Chan *c) { lock(&clunkq.l); clunkq.nqueued++; c->next = nil; - if(clunkq.head) + if(clunkq.head != nil) clunkq.tail->next = c; else clunkq.head = c; clunkq.tail = c; unlock(&clunkq.l); + wakeup(&clunkq.r); +} - if(up != 0 && palloc.Lock.p != up && canqlock(&clunkq.q)){ - c = up->dot; - up->dot = nil; +static Chan* +closechandeq(void) +{ + Chan *c; + + lock(&clunkq.l); + c = clunkq.head; + if(c != nil) { + clunkq.head = c->next; + clunkq.nclosed++; + } + unlock(&clunkq.l); + return c; +} + +static void +closeproc(void *) +{ + Chan *c; + + for(;;){ + c = closechandeq(); + if(c == nil) { + qlock(&clunkq.q); + if(!waserror()) { + tsleep(&clunkq.r, clunkwork, nil, 500); + poperror(); + } + c = closechandeq(); + if(c == nil) { + if(clunkq.q.head != nil) { + qunlock(&clunkq.q); + pexit("no work", 1); + } + qunlock(&clunkq.q); + continue; + } + if(clunkq.q.head == nil) { + if(!waserror()) { + kproc("closeproc", closeproc, nil); + poperror(); + } + } + qunlock(&clunkq.q); + } if(!waserror()){ - kproc("closeproc", closeproc, nil); + devtab[c->type]->close(c); poperror(); } - up->dot = c; - }else - wakeup(&clunkq.r); + chanfree(c); + } } void @@ -551,13 +516,11 @@ cclose(Chan *c) if(c == nil || c->ref < 1 || c->flag&CFREE) panic("cclose %#p", getcallerpc(&c)); - DBG("cclose %p name=%s ref=%ld\n", c, chanpath(c), c->ref); - if(decref(c)) return; if(devtab[c->type]->dc == L'M') - if((c->flag&(CRCLOSE|CCACHE)) == CCACHE) + if((c->flag&COPEN) == 0 || (c->flag&(CRCLOSE|CCACHE)) == CCACHE) if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0) if((clunkq.nqueued - clunkq.nclosed) < 64){ closechanq(c); @@ -577,12 +540,8 @@ ccloseq(Chan *c) if(c == nil || c->ref < 1 || c->flag&CFREE) panic("ccloseq %#p", getcallerpc(&c)); - DBG("ccloseq %p name=%s ref=%ld\n", c, chanpath(c), c->ref); - - if(decref(c)) - return; - - closechanq(c); + if(decref(c) == 0) + closechanq(c); } /* @@ -648,6 +607,35 @@ newmhead(Chan *from) return mh; } +/* + * This is necessary because there are many + * pointers to the top of a given mount list: + * + * - the mhead in the namespace hash table + * - the mhead in chans returned from findmount: + * used in namec and then by unionread. + * - the mhead in chans returned from createdir: + * used in the open/create race protect, which is gone. + * + * The RWlock in the Mhead protects the mount list it contains. + * The mount list is deleted in cunmount() and closepgrp(). + * The RWlock ensures that nothing is using the mount list at that time. + * + * It is okay to replace c->mh with whatever you want as + * long as you are sure you have a unique reference to it. + * + * This comment might belong somewhere else. + */ +void +putmhead(Mhead *m) +{ + if(m != nil && decref(m) == 0){ + assert(m->mount == nil); + cclose(m->from); + free(m); + } +} + int cmount(Chan **newp, Chan *old, int flag, char *spec) { @@ -660,12 +648,12 @@ cmount(Chan **newp, Chan *old, int flag, char *spec) if(QTDIR & (old->qid.type^(*newp)->qid.type)) error(Emount); - if(old->umh) + if(old->umh != nil) print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp)); order = flag&MORDER; - if((old->qid.type&QTDIR)==0 && order != MREPL) + if((old->qid.type&QTDIR) == 0 && order != MREPL) error(Emount); new = *newp; @@ -689,15 +677,15 @@ cmount(Chan **newp, Chan *old, int flag, char *spec) * This is far more complicated than it should be, but I don't * see an easier way at the moment. */ - if((flag&MCREATE) && mh && mh->mount - && (mh->mount->next || !(mh->mount->mflag&MCREATE))) + if((flag&MCREATE) != 0 && mh != nil && mh->mount != nil + && (mh->mount->next != nil || (mh->mount->mflag&MCREATE) == 0)) error(Emount); pg = up->pgrp; wlock(&pg->ns); l = &MOUNTH(pg, old->qid); - for(m = *l; m; m = m->hash){ + for(m = *l; m != nil; m = m->hash){ if(eqchan(m->from, old, 1)) break; l = &m->hash; @@ -716,7 +704,7 @@ cmount(Chan **newp, Chan *old, int flag, char *spec) * node to the mount chain. */ if(order != MREPL) - m->mount = newmount(m, old, 0, 0); + m->mount = newmount(old, 0, nil); } wlock(&m->lock); if(waserror()){ @@ -725,7 +713,7 @@ cmount(Chan **newp, Chan *old, int flag, char *spec) } wunlock(&pg->ns); - nm = newmount(m, new, flag, spec); + nm = newmount(new, flag, spec); if(mh != nil && mh->mount != nil){ /* * copy a union when binding it onto a directory @@ -735,32 +723,31 @@ cmount(Chan **newp, Chan *old, int flag, char *spec) flg = MAFTER; h = &nm->next; um = mh->mount; - for(um = um->next; um; um = um->next){ - f = newmount(m, um->to, flg, um->spec); + for(um = um->next; um != nil; um = um->next){ + f = newmount(um->to, flg, um->spec); *h = f; h = &f->next; } } - if(m->mount && order == MREPL){ + if(m->mount != nil && order == MREPL){ mountfree(m->mount); - m->mount = 0; + m->mount = nil; } if(flag & MCREATE) nm->mflag |= MCREATE; - if(m->mount && order == MAFTER){ - for(f = m->mount; f->next; f = f->next) + if(m->mount != nil && order == MAFTER){ + for(f = m->mount; f->next != nil; f = f->next) ; f->next = nm; }else{ - for(f = nm; f->next; f = f->next) + for(f = nm; f->next != nil; f = f->next) ; f->next = m->mount; m->mount = nm; } - wunlock(&m->lock); poperror(); return nm->mountid; @@ -773,7 +760,7 @@ cunmount(Chan *mnt, Chan *mounted) Mhead *m, **l; Mount *f, **p; - if(mnt->umh) /* should not happen */ + if(mnt->umh != nil) /* should not happen */ print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh); /* @@ -789,47 +776,44 @@ cunmount(Chan *mnt, Chan *mounted) wlock(&pg->ns); l = &MOUNTH(pg, mnt->qid); - for(m = *l; m; m = m->hash){ + for(m = *l; m != nil; m = m->hash){ if(eqchan(m->from, mnt, 1)) break; l = &m->hash; } - if(m == 0){ + if(m == nil){ wunlock(&pg->ns); error(Eunmount); } wlock(&m->lock); - if(mounted == 0){ + f = m->mount; + if(mounted == nil){ *l = m->hash; - wunlock(&pg->ns); - mountfree(m->mount); m->mount = nil; - cclose(m->from); wunlock(&m->lock); + wunlock(&pg->ns); + mountfree(f); putmhead(m); return; } - - p = &m->mount; - for(f = *p; f; f = f->next){ - /* BUG: Needs to be 2 pass */ + for(p = &m->mount; f != nil; f = f->next){ if(eqchan(f->to, mounted, 1) || - (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){ + (f->to->mchan != nil && eqchan(f->to->mchan, mounted, 1))){ *p = f->next; - f->next = 0; - mountfree(f); + f->next = nil; if(m->mount == nil){ *l = m->hash; - cclose(m->from); wunlock(&m->lock); wunlock(&pg->ns); + mountfree(f); putmhead(m); return; } wunlock(&m->lock); wunlock(&pg->ns); + mountfree(f); return; } p = &f->next; @@ -852,8 +836,7 @@ cclone(Chan *c) error("clone failed"); nc = wq->clone; free(wq); - nc->path = c->path; - if(c->path) + if((nc->path = c->path) != nil) incref(c->path); return nc; } @@ -862,36 +845,31 @@ cclone(Chan *c) int findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid) { + Chan *to; Pgrp *pg; Mhead *m; pg = up->pgrp; rlock(&pg->ns); - for(m = MOUNTH(pg, qid); m; m = m->hash){ - rlock(&m->lock); - if(m->from == nil){ - print("m %p m->from 0\n", m); - runlock(&m->lock); - continue; - } + for(m = MOUNTH(pg, qid); m != nil; m = m->hash){ if(eqchantdqid(m->from, type, dev, qid, 1)){ + rlock(&m->lock); runlock(&pg->ns); - if(mp != nil){ + if(mp != nil) incref(m); - if(*mp != nil) - putmhead(*mp); + to = m->mount->to; + incref(to); + runlock(&m->lock); + if(mp != nil){ + putmhead(*mp); *mp = m; } if(*cp != nil) cclose(*cp); - incref(m->mount->to); - *cp = m->mount->to; - runlock(&m->lock); + *cp = to; return 1; } - runlock(&m->lock); } - runlock(&pg->ns); return 0; } @@ -902,24 +880,24 @@ findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid) static int domount(Chan **cp, Mhead **mp, Path **path) { - Chan **lc; + Chan **lc, *from; Path *p; if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0) return 0; - if(path){ + if(path != nil){ p = *path; p = uniquepath(p); if(p->mlen <= 0) print("domount: path %s has mlen==%d\n", p->s, p->mlen); else{ + from = (*mp)->from; + incref(from); lc = &p->mtpt[p->mlen-1]; -DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]); - incref((*mp)->from); - if(*lc) + if(*lc != nil) cclose(*lc); - *lc = (*mp)->from; + *lc = from; } *path = p; } @@ -940,8 +918,7 @@ undomount(Chan *c, Path *path) print("undomount: path %s ref %ld mlen %d caller %#p\n", path->s, path->ref, path->mlen, getcallerpc(&c)); - if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){ -DBG("undomount %p %s => remove %p\n", path, path->s, nc); + if(path->mlen > 0 && (nc = path->mtpt[path->mlen-1]) != nil){ cclose(c); path->mtpt[path->mlen-1] = nil; c = nc; @@ -1000,14 +977,13 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) */ didmount = 0; for(nhave=0; nhaveqid.type&QTDIR)==0){ + if((c->qid.type&QTDIR) == 0){ if(nerror) *nerror = nhave; pathclose(path); cclose(c); kstrcpy(up->errstr, Enotdir, ERRMAX); - if(mh != nil) - putmhead(mh); + putmhead(mh); return -1; } ntry = nnames - nhave; @@ -1033,7 +1009,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){ /* try a union mount, if any */ - if(mh && !nomount){ + if(mh != nil && !nomount){ /* * mh->mount->to == c, so start at mh->mount->next */ @@ -1053,8 +1029,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) pathclose(path); if(nerror) *nerror = nhave+1; - if(mh != nil) - putmhead(mh); + putmhead(mh); return -1; } } @@ -1083,7 +1058,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) if(wq->clone == nil){ cclose(c); pathclose(path); - if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){ + if(wq->nqid == 0 || (wq->qid[wq->nqid-1].type&QTDIR) != 0){ if(nerror) *nerror = nhave+wq->nqid+1; kstrcpy(up->errstr, Edoesnotexist, ERRMAX); @@ -1093,8 +1068,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) kstrcpy(up->errstr, Enotdir, ERRMAX); } free(wq); - if(mh != nil) - putmhead(mh); + putmhead(mh); return -1; } n = wq->nqid; @@ -1109,7 +1083,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) } for(i=0; ifrom; path = addelem(path, names[nhave+i], mtpt); } @@ -1120,11 +1094,8 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) mh = nmh; free(wq); } - putmhead(mh); - c = cunique(c); - if(c->umh != nil){ //BUG print("walk umh\n"); putmhead(c->umh); @@ -1155,8 +1126,8 @@ createdir(Chan *c, Mhead *m) runlock(&m->lock); nexterror(); } - for(f = m->mount; f; f = f->next){ - if(f->mflag&MCREATE){ + for(f = m->mount; f != nil; f = f->next){ + if((f->mflag&MCREATE) != 0){ nc = cclone(f->to); runlock(&m->lock); poperror(); @@ -1180,7 +1151,7 @@ growparse(Elemlist *e) int *inew; enum { Delta = 8 }; - if(e->nelems % Delta == 0){ + if((e->nelems % Delta) == 0){ new = smalloc((e->nelems+Delta) * sizeof(char*)); memmove(new, e->elems, e->nelems*sizeof(char*)); free(e->elems); @@ -1231,30 +1202,9 @@ parsename(char *aname, Elemlist *e) *slash++ = '\0'; name = slash; } - - if(0 && chandebug){ - int i; - - print("parsename %s:", e->name); - for(i=0; i<=e->nelems; i++) - print(" %d", e->off[i]); - print("\n"); - } -} - -void* -memrchr(void *va, int c, long n) -{ - uchar *a, *e; - - a = va; - for(e=a+n-1; e>a; e--) - if(*e == c) - return e; - return nil; } -void +static void namelenerror(char *aname, int len, char *err) { char *ename, *name, *next; @@ -1275,9 +1225,11 @@ namelenerror(char *aname, int len, char *err) next = ename; do{ name = next; - next = memrchr(aname, '/', name-aname); - if(next == nil) - next = aname; + if(next == aname) + break; + while(next > aname) + if(*--next == '/') + break; len = ename-next; }while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3); @@ -1325,12 +1277,13 @@ Chan* namec(char *aname, int amode, int omode, ulong perm) { int len, n, t, nomount; - Chan *c, *cnew; - Path *path; + Chan *c; + Chan *volatile cnew; + Path *volatile path; Elemlist e; Rune r; Mhead *m; - char *createerr, tmperrbuf[ERRMAX]; + char *err; char *name; if(aname[0] == '\0') @@ -1340,7 +1293,6 @@ namec(char *aname, int amode, int omode, ulong perm) free(aname); nexterror(); } - DBG("namec %s %d %d\n", aname, amode, omode); name = aname; /* @@ -1378,9 +1330,6 @@ namec(char *aname, int amode, int omode, ulong perm) * any others left unprotected) */ n = chartorune(&r, up->genbuf+1)+1; - /* actually / is caught by parsing earlier */ - if(utfrune("M", r)) - error(Enoattach); if(up->pgrp->noattach && utfrune("|decp", r)==nil) error(Enoattach); t = devno(r, 1); @@ -1411,15 +1360,15 @@ namec(char *aname, int amode, int omode, ulong perm) */ if(e.nerror == 0) nexterror(); - strcpy(tmperrbuf, up->errstr); if(e.off[e.nerror]==0) print("nerror=%d but off=%d\n", e.nerror, e.off[e.nerror]); - if(0 && chandebug) - print("showing %d+%d/%d (of %d) of %s (%d %d)\n", e.prefix, e.off[e.nerror], e.nerror, e.nelems, aname, e.off[0], e.off[1]); len = e.prefix+e.off[e.nerror]; free(e.off); - namelenerror(aname, len, tmperrbuf); + err = up->errstr; + up->errstr = up->syserrstr; + up->syserrstr = err; + namelenerror(aname, len, err); } /* @@ -1451,10 +1400,10 @@ namec(char *aname, int amode, int omode, ulong perm) nexterror(); } - if(e.mustbedir && !(c->qid.type&QTDIR)) + if(e.mustbedir && (c->qid.type&QTDIR) == 0) error("not a directory"); - if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR)) + if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR) != 0) error("cannot exec directory"); switch(amode){ @@ -1463,8 +1412,7 @@ namec(char *aname, int amode, int omode, ulong perm) m = nil; if(!nomount) domount(&c, &m, nil); - if(c->umh != nil) - putmhead(c->umh); + putmhead(c->umh); c->umh = m; break; @@ -1502,13 +1450,13 @@ namec(char *aname, int amode, int omode, ulong perm) case Aopen: case Acreate: -if(c->umh != nil){ - print("cunique umh Open\n"); - putmhead(c->umh); - c->umh = nil; -} + if(c->umh != nil){ + print("cunique umh Open\n"); + putmhead(c->umh); + c->umh = nil; + } /* only save the mount head if it's a multiple element union */ - if(m && m->mount && m->mount->next) + if(m != nil && m->mount != nil && m->mount->next != nil) c->umh = m; else putmhead(m); @@ -1531,7 +1479,7 @@ if(c->umh != nil){ * Directories (e.g. for cd) are left before the mount point, * so one may mount on / or . and see the effect. */ - if(!(c->qid.type & QTDIR)) + if((c->qid.type&QTDIR) == 0) error(Enotdir); break; @@ -1625,8 +1573,7 @@ if(c->umh != nil){ cnew->flag |= CCEXEC; if(omode & ORCLOSE) cnew->flag |= CRCLOSE; - if(m) - putmhead(m); + putmhead(m); cclose(c); c = cnew; c->path = addelem(c->path, e.elems[e.nelems-1], nil); @@ -1635,19 +1582,20 @@ if(c->umh != nil){ /* create failed */ cclose(cnew); - if(m) - putmhead(m); + putmhead(m); if(omode & OEXCL) nexterror(); /* save error */ - createerr = up->errstr; - up->errstr = tmperrbuf; + err = up->errstr; + up->errstr = up->syserrstr; + up->syserrstr = err; /* note: we depend that walk does not error */ - if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){ - up->errstr = createerr; - error(createerr); /* report true error */ - } - up->errstr = createerr; + if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0) + error(err); /* report true error */ + /* restore error */ + err = up->syserrstr; + up->syserrstr = up->errstr; + up->errstr = err; omode |= OTRUNC; goto Open; @@ -1706,14 +1654,14 @@ char isfrog[256]={ * to access unchecked addresses.) */ static char* -validname0(char *aname, int slashok, int dup, ulong pc) +validname0(char *aname, int slashok, int dup, uintptr pc) { char *ename, *name, *s; int c, n; Rune r; name = aname; - if((ulong)name < KZERO){ + if((uintptr)name < KZERO){ if(!dup) print("warning: validname called from %#p with user pointer", pc); ename = vmemchr(name, 0, (1<<16)); @@ -1721,7 +1669,7 @@ validname0(char *aname, int slashok, int dup, ulong pc) ename = memchr(name, 0, (1<<16)); if(ename==nil || ename-name>=(1<<16)) - error("name too long"); + error(Etoolong); s = nil; if(dup){ @@ -1741,10 +1689,10 @@ validname0(char *aname, int slashok, int dup, ulong pc) name += chartorune(&r, name); else{ if(isfrog[c]) - if(!slashok || c!='/'){ - snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname); - free(s); - error(up->genbuf); + if(!slashok || c!='/'){ + snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname); + free(s); + error(up->genbuf); } name++; } @@ -1771,32 +1719,3 @@ isdir(Chan *c) return; error(Enotdir); } - -/* - * This is necessary because there are many - * pointers to the top of a given mount list: - * - * - the mhead in the namespace hash table - * - the mhead in chans returned from findmount: - * used in namec and then by unionread. - * - the mhead in chans returned from createdir: - * used in the open/create race protect, which is gone. - * - * The RWlock in the Mhead protects the mount list it contains. - * The mount list is deleted when we cunmount. - * The RWlock ensures that nothing is using the mount list at that time. - * - * It is okay to replace c->mh with whatever you want as - * long as you are sure you have a unique reference to it. - * - * This comment might belong somewhere else. - */ -void -putmhead(Mhead *m) -{ - if(m && decref(m) == 0){ - m->mount = (Mount*)0xCafeBeef; - free(m); - } -} -