diff --git a/sys/src/cmd/hjfs/9p.c b/sys/src/cmd/hjfs/9p.c index fb3c3a9fd..037914904 100644 --- a/sys/src/cmd/hjfs/9p.c +++ b/sys/src/cmd/hjfs/9p.c @@ -76,15 +76,15 @@ tqueue(Req *req) if(ch->lreq != nil) ((Req *) ch->lreq)->aux = req; ch->lreq = req; - if(ch->qnext == nil){ + if(ch->qnext == nil && (ch->wflags & CHWBUSY) == 0){ ch->qnext = &readych; ch->qprev = ch->qnext->qprev; ch->qnext->qprev = ch; ch->qprev->qnext = ch; + rwakeup(&chanre); } if(req->ifcall.type == Tremove) req->fid->aux = nil; - rwakeup(&chanre); qunlock(&chanqu); } @@ -100,9 +100,17 @@ tdestroyfid(Fid *fid) qlock(&chanqu); ch = fid->aux; fid->aux = nil; + if(ch != nil){ + ch->wflags |= CHWCLUNK; + if(ch->qnext == nil && (ch->wflags & CHWBUSY) == 0){ + ch->qnext = &readych; + ch->qprev = ch->qnext->qprev; + ch->qnext->qprev = ch; + ch->qprev->qnext = ch; + rwakeup(&chanre); + } + } qunlock(&chanqu); - if(ch != nil) - chanclunk(ch); } static void @@ -137,31 +145,29 @@ start9p(char *service, int stdio) threadpostmountsrv(&mysrv, service, nil, 0); } -static char * -tclone(Fid *old, Fid *new, void *) +static int +twalk(Chan *ch, Fid *fid, Fid *nfid, int n, char **name, Qid *qid) { - Chan *ch; - - ch = old->aux; - if(ch->open != 0) - return "trying to clone an open fid"; - new->aux = chanclone(ch); - return nil; -} + int i; -static char * -twalk(Fid *fid, char *name, void *) -{ - Chan *ch; - char buf[ERRMAX]; - - ch = fid->aux; - if(chanwalk(ch, name) < 0){ - rerrstr(buf, ERRMAX); - return strdup(buf); + if(nfid != fid){ + if(ch->open != 0){ + werrstr("trying to clone an open fid"); + return -1; + } + ch = chanclone(ch); + if(ch == nil) + return -1; + nfid->aux = ch; + nfid->qid = ch->loc->Qid; } - fid->qid = ch->loc->Qid; - return nil; + for(i = 0; i < n; i++){ + if(chanwalk(ch, name[i]) <= 0) + return i > 0 ? i : -1; + qid[i] = ch->loc->Qid; + nfid->qid = ch->loc->Qid; + } + return n; } static void @@ -181,6 +187,8 @@ workerproc(void *) ch->qprev->qnext = ch->qnext; ch->qprev = nil; ch->qnext = nil; + assert((ch->wflags & CHWBUSY) == 0); + ch->wflags |= CHWBUSY; while(ch != nil && ch->freq != nil){ req = ch->freq; ch->freq = req->aux; @@ -188,12 +196,15 @@ workerproc(void *) ch->lreq = nil; req->aux = nil; qunlock(&chanqu); + assert(req->responded == 0); i = &req->ifcall; o = &req->ofcall; switch(req->ifcall.type){ case Twalk: - walkandclone(req, twalk, tclone, nil); - goto noret; + rc = twalk(ch, req->fid, req->newfid, i->nwname, i->wname, o->wqid); + if(rc >= 0) + o->nwqid = rc; + break; case Topen: rc = chanopen(ch, i->mode); break; @@ -228,9 +239,13 @@ workerproc(void *) responderror(req); else respond(req, nil); - noret: qlock(&chanqu); } + if(ch != nil){ + ch->wflags &= ~CHWBUSY; + if((ch->wflags & CHWCLUNK) != 0) + chanclunk(ch); + } } } diff --git a/sys/src/cmd/hjfs/auth.c b/sys/src/cmd/hjfs/auth.c index efd026066..07ab35042 100644 --- a/sys/src/cmd/hjfs/auth.c +++ b/sys/src/cmd/hjfs/auth.c @@ -191,7 +191,7 @@ userssave(Fs *fs, Chan *ch) { User *u, *v; int nu, i; - char buf[512], *p, *e; + char buf[512], *p, *e, *s; uvlong off; rlock(&fs->udatal); @@ -206,8 +206,11 @@ userssave(Fs *fs, Chan *ch) p = buf; e = buf + sizeof(buf); p = seprint(p, e, "%d:%s:", v->uid, v->name); - if(v->lead != NOUID) - p = strecpy(p, e, uid2name(fs, v->lead)); + if(v->lead != NOUID){ + s = uid2name(fs, v->lead); + p = strecpy(p, e, s); + free(s); + } if(p < e) *p++ = ':'; for(i = 0; i < v->nmemb; i++){ @@ -215,7 +218,9 @@ userssave(Fs *fs, Chan *ch) continue; if(p < e && i > 0) *p++ = ','; - p = strecpy(p, e, uid2name(fs, v->memb[i])); + s = uid2name(fs, v->memb[i]); + p = strecpy(p, e, s); + free(s); } *p++ = '\n'; if(ch == nil) diff --git a/sys/src/cmd/hjfs/dat.h b/sys/src/cmd/hjfs/dat.h index 6201eb50a..659bb3d32 100644 --- a/sys/src/cmd/hjfs/dat.h +++ b/sys/src/cmd/hjfs/dat.h @@ -185,6 +185,9 @@ enum { CHFDUMP = 1, CHFNOLOCK = 2, CHFRO = 4, + + CHWBUSY = 1, + CHWCLUNK = 2, }; @@ -203,6 +206,7 @@ struct Chan { /* workers */ void *freq, *lreq; Chan *qnext, *qprev; + int wflags; }; extern QLock chanqu; diff --git a/sys/src/cmd/hjfs/fs2.c b/sys/src/cmd/hjfs/fs2.c index 747932e7d..173cc7da7 100644 --- a/sys/src/cmd/hjfs/fs2.c +++ b/sys/src/cmd/hjfs/fs2.c @@ -111,7 +111,7 @@ chancreat(Chan *ch, char *name, int perm, int mode) chend(ch); return -1; } - if(!namevalid || ch->open != 0){ + if(!namevalid(name) || ch->open != 0){ werrstr(Einval); chend(ch); return -1; @@ -520,6 +520,7 @@ chandirread(Chan *ch, void *buf, ulong n, uvlong off) free(di.uid); free(di.gid); free(di.muid); + free(di.name); if(rc <= BIT16SZ) break; wr += rc; diff --git a/sys/src/cmd/hjfs/main.c b/sys/src/cmd/hjfs/main.c index c3668a47a..85c06ed6b 100644 --- a/sys/src/cmd/hjfs/main.c +++ b/sys/src/cmd/hjfs/main.c @@ -13,6 +13,8 @@ char Eperm[] = "permission denied"; char Eexists[] = "file exists"; char Elocked[] = "file locked"; +int mainstacksize = 65536; + void* emalloc(int c) {