From da82c9cfc4fe4ed2623d3221482d10c86a19673d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 1 Jun 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-06-01 --- bitsy/devsac.c | 136 ++++++++++++++++++++++++--------------------- bitsy/fns.h | 3 +- bitsy/main.c | 2 +- port/chan.c | 78 +++++++++++++++++++------- port/devloopback.c | 31 +++++------ port/devmnt.c | 39 ++++++------- 6 files changed, 163 insertions(+), 126 deletions(-) diff --git a/bitsy/devsac.c b/bitsy/devsac.c index dcf0da2b78ae86a46d7fc11d7ca4cf8b4f033a75..16a97d7ff52958b1ac1a9d36af458e82a32d19af 100644 --- a/bitsy/devsac.c +++ b/bitsy/devsac.c @@ -99,13 +99,13 @@ static Sac root; static Cache cache[CacheSize]; static ulong cacheage; -static void sacdir(Chan *, SacDir*, char*); +static int sacdir(Chan *, SacDir*, uchar*, int); static ulong getl(void *p); static Sac *saccpy(Sac *s); -static Sac *saclookup(Sac *s, char *name); -static int sacdirread(Chan *, char *p, long off, long cnt); -static void loadblock(void *buf, uchar *offset, int blocksize); -static void sacfree(Sac*); +static Sac *saclookup(Sac *s, char *name); +static int sacdirread(Chan *, uchar *p, long off, long cnt); +static void loadblock(void *buf, uchar *offset, int blocksize); +static void sacfree(Sac*); static void pathtoqid(ulong path, Qid *q) @@ -118,6 +118,17 @@ pathtoqid(ulong path, Qid *q) q->vers = 0; } +static void +omodetomode(ulong om, ulong *m) +{ + ulong nm; + + nm = om & ~(CHDIR|CHAPPEND|CHEXCL|CHMOUNT); + if(om & CHDIR) + nm |= DMDIR; + *m = nm; +} + static void sacinit(void) { @@ -152,7 +163,6 @@ sacattach(char* spec) { Chan *c; int dev; - int opath; dev = atoi(spec); if(dev != 0) @@ -163,29 +173,19 @@ sacattach(char* spec) error("devsac: bad magic"); c = devattach('C', spec); - path = getl(root.qid); - pathtoqid(path, &c->qid; + pathtoqid(getl(root.qid), &c->qid); c->dev = dev; c->aux = saccpy(&root); return c; } -static Chan* -sacclone(Chan *c, Chan *nc) -{ - nc = devclone(c, nc); - nc->aux = saccpy(c->aux); - return nc; -} - static Walkqid* sacwalk(Chan *c, Chan *nc, char **name, int nname) { Sac *sac; - int i, j, alloc; + int j, alloc; Walkqid *wq; char *n; - Dir dir; if(nname > 0) isdir(c); @@ -200,26 +200,35 @@ sacwalk(Chan *c, Chan *nc, char **name, int nname) } if(nc == nil){ nc = devclone(c); - nc->type = 0; /* device doesn't know about this channel yet */ alloc = 1; } wq->clone = nc; for(j=0; jqid[wq->nqid++] = nc->qid; + continue; + } sac = nc->aux; - sac = saclookup(sac, name); + sac = saclookup(sac, n); if(sac == nil) { + if(j == 0) + error(Enonexist); strncpy(up->error, Enonexist, NAMELEN); - return 0; + break; } nc->aux = sac; pathtoqid(getl(sac->qid), &nc->qid); } - return 1; + poperror(); + if(wq->nqid < nname){ + if(alloc) + cclose(wq->clone); + wq->clone = nil; + } + return wq; } static Chan* @@ -260,12 +269,8 @@ sacread(Chan *c, void *a, long n, vlong voff) buf = a; cnt = n; - if(c->qid.path & CHDIR){ - cnt = (cnt/DIRLEN)*DIRLEN; - if(off%DIRLEN) - error("i/o error"); - return sacdirread(c, buf, off, cnt); - } + if(c->qid.type & QTDIR) + return sacdirread(c, a, off, cnt); sac = c->aux; length = getl(sac->length); if(off >= length) @@ -311,11 +316,13 @@ sacclose(Chan* c) sacfree(sac); } - -static void -sacstat(Chan *c, char *db) +static int +sacstat(Chan *c, uchar *db, int n) { - sacdir(c, c->aux, db); + n = sacdir(c, c->aux, db, n); + if(n == 0) + error(Ebadarg); + return n; } static Sac* @@ -361,24 +368,23 @@ sacfree(Sac *s) free(s); } -static void -sacdir(Chan *c, SacDir *s, char *buf) +static int +sacdir(Chan *c, SacDir *s, uchar *db, int n) { Dir dir; - memmove(dir.name, s->name, NAMELEN); - dir.qid = (Qid){getl(s->qid), 0}; - dir.mode = getl(s->mode); + dir.name = s->name; + dir.uid = s->uid; + dir.gid = s->gid; + dir.muid = s->uid; + pathtoqid(getl(s->qid), &dir.qid); + omodetomode(getl(s->mode), &dir.mode); dir.length = getl(s->length); - if(dir.mode &CHDIR) - dir.length *= DIRLEN; - memmove(dir.uid, s->uid, NAMELEN); - memmove(dir.gid, s->gid, NAMELEN); dir.atime = getl(s->atime); dir.mtime = getl(s->mtime); dir.type = devtab[c->type]->dc; dir.dev = c->dev; - convD2M(&dir, buf); + return convD2M(&dir, db, n); } static void @@ -457,41 +463,44 @@ sacparent(Sac *s) return s; } +/* n**2 alg to read a directory */ static int -sacdirread(Chan *c, char *p, long off, long cnt) +sacdirread(Chan *c, uchar *p, long off, long cnt) { uchar *blocks; SacDir *buf; - int iblock, per, i, j, n, ndir; + int per, i, j, n, ndir; + long sofar; Sac *s; s = c->aux; blocks = data + getl(s->blocks); per = blocksize/sizeof(SacDir); ndir = getl(s->length); - off /= DIRLEN; - cnt /= DIRLEN; - if(off >= ndir) - return 0; - if(cnt > ndir-off) - cnt = ndir-off; - iblock = -1; - buf = malloc(per*sizeof(SacDir)); - for(i=off; i ndir-j*per) n = ndir-j*per; loadblock(buf, blocks + j*OffsetSize, n*sizeof(SacDir)); - iblock = j; } - j *= per; - sacdir(c, buf+i-j, p); - p += DIRLEN; + n = sacdir(c, buf+i, p, cnt - sofar); + if(n == 0) + break; + if(off > 0) + off -= n; + else { + p += n; + sofar += n; + } } free(buf); - return cnt*DIRLEN; + + return sofar; } static Sac* @@ -551,7 +560,6 @@ Dev sacdevtab = { devreset, sacinit, sacattach, - sacclone, sacwalk, sacstat, sacopen, diff --git a/bitsy/fns.h b/bitsy/fns.h index f3a43508f3f0a1103a6ef0ce5edb726d26deee45..cc974b6acd06effd3a39fd4d501181165bb28666 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -39,6 +39,7 @@ ulong inl(ulong); void intrenable(int, int, void (*)(Ureg*, void*), void*, char*); int iprint(char*, ...); void irpower(int); +#define kmapinval() void lcdpower(int); void links(void); void* mapmem(ulong, int, int); @@ -75,7 +76,7 @@ void putpid(ulong); void qpanic(char *, ...); void rs232power(int); void uartspecial(Uart*, int, Queue**, Queue**, int (*)(Queue*, int)); -void sa1100_uartsetup(int); +void sa1110_uartsetup(int); void screeninit(void); int screenprint(char*, ...); /* debugging */ void serialµcputs(uchar *str, int n); diff --git a/bitsy/main.c b/bitsy/main.c index 18946d82ec19b6f4ed34057ee7a0384c89ac9f5c..c63dd4aeba8d98da1ba42124f42bb7363fdca52f 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -35,7 +35,7 @@ main(void) mmuinit(); machinit(); trapinit(); - sa1100_uartsetup(1); + sa1110_uartsetup(1); rs232power(1); dmainit(); screeninit(); diff --git a/port/chan.c b/port/chan.c index 599f5b676cbc6bd3c16a65b0fa16a8afb411cc44..3b9c9cd1369d4498f688dd9144c18df1a9c32635 100644 --- a/port/chan.c +++ b/port/chan.c @@ -6,12 +6,12 @@ #include "../port/error.h" int chandebug=0; /* toggled by sysr1 */ +QLock chanprint; /* probably asking for trouble (deadlocks) -rsc */ /* transition BUG */ int client9p = 2; int kernel9p = 2; - int domount(Chan**, Mhead**); Ref mheadcounter; @@ -45,13 +45,26 @@ dumpmount(void) /* DEBUGGING */ 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)\n", t, t->to->name->s, t->to->umh); + print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->name->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev); } } poperror(); runlock(&pg->ns); } + +char* +c2name(Chan *c) /* DEBUGGING */ +{ + if(c == nil) + return ""; + if(c->name == nil) + return ""; + if(c->name->s == nil) + return ""; + return c->name->s; +} + enum { CNAMESLOP = 20 @@ -225,7 +238,6 @@ newchan(void) c->link = chanalloc.list; chanalloc.list = c; unlock(&chanalloc); -if(chandebug) print("newchan %d\n", c->fid); } /* if you get an error before associating with a dev, @@ -676,6 +688,11 @@ undomount(Chan *c, Cname *name) he = &pg->mnthash[MNTHASH]; for(h = pg->mnthash; h < he; h++) { for(f = *h; f; f = f->hash) { + if(strcmp(f->from->name->s, name->s) != 0) + continue; +if(chandebug) +print("[%lud]\tundomount found head %s; need chan (path %.8llux dev %C %lud)\n", + up->pid, name->s, c->qid.path, devtab[c->type]->dc, c->dev); for(t = f->mount; t; t = t->next) { if(eqchan(c, t->to, 1)) { /* @@ -690,6 +707,8 @@ undomount(Chan *c, Cname *name) incref(nc); cclose(c); c = nc; +if(chandebug) +print("[%lud]\tundomount found %s\n", up->pid, c2name(c)); break; } } @@ -722,10 +741,12 @@ walk(Chan **cp, char **names, int nnames, int nomount) mh = nil; if(chandebug){ -print("walk"); +qlock(&chanprint); +print("[%lud] walk %s to ", up->pid, c2name(c)); for(i=0; i\n", c->qid.path, devtab[c->type]->dc, c->dev); +qlock(&chanprint); +print("[%lud]\twalk from %s (path %.8llux dev %C %lud) to ", + up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); for(i=0; idev; if((wq = devtab[type]->walk(c, nil, names, ntry)) == nil){ -if(chandebug) print("walk failed."); +if(chandebug) print("[%lud]\twalk failed.\n", up->pid); /* try a union mount, if any */ if(mh == nil || nomount){ Giveup: -if(chandebug) print("give up\n"); -//delay(2000); +if(chandebug) print("[%lud]\tgive up\n", up->pid); cclose(c); cnameclose(cname); return -1; @@ -784,7 +808,9 @@ if(chandebug) print("give up\n"); } for(f = mh->mount; f; f = f->next) { -if(chandebug) print("\ttry chan: qid %.8llux devchar %C dev %lud ->\n", c->qid.path, devtab[c->type]->dc, c->dev); +if(chandebug) + print("[%lud]\twalk from %s (path %.8llux dev %C %lud)\n", + up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); if((wq = devtab[f->to->type]->walk(f->to, nil, names, ntry)) != nil) break; } @@ -802,34 +828,49 @@ if(chandebug) print("\ttry chan: qid %.8llux devchar %C dev %lud ->\n", c->qid.p if(dotdot) { assert(wq->nqid == 1); assert(wq->clone != nil); -if(chandebug) print("undo wq->clone->name %s cname %s...", wq->clone->name->s, cname->s); + + cname = addelem(cname, ".."); +if(chandebug) +print("[%lud]\tundo wq->clone %s cname %s\n", up->pid, c2name(wq->clone), cname?cname->s:""); nc = undomount(wq->clone, cname); -if(chandebug) print("undidmount nc %s...", nc->name->s); +if(chandebug) +print("[%lud]\tundo returned %s\n", up->pid, c2name(nc)); n = 1; } else { nc = nil; -if(chandebug) print("find."); if(!nomount) for(i=0; inqid && iqid[i])) break; if(nc == nil){ /* no mount points along path */ +if(chandebug) +print("[%lud]\tno mount points along path\n", up->pid); if(wq->clone == nil){ cclose(c); cnameclose(cname); free(wq); -if(chandebug) print("fail\n"); return -1; } n = wq->nqid; nc = wq->clone; }else{ /* stopped early, at a mount point */ +if(chandebug){int j; +qlock(&chanprint); +print("[%lud]\tfound mount point: ", up->pid); +for(j=0; j<=i; j++) + print("%s%s", j?"/":"", names[j]); +print(" becomes "); +print("%s\n", c2name(nc)); +qunlock(&chanprint); +} if(wq->clone != nil){ cclose(wq->clone); wq->clone = nil; } n = i+1; } + for(i=0; is, nnames, devtab[c->type]->dc, c->qid.path); free(wq); } @@ -860,7 +897,8 @@ if(c->umh != nil){ cclose(*cp); *cp = c; -if(chandebug) print("success\n"); +if(chandebug) +print("[%lud]\twalk succeeds; name %s chan (path %.8llux dev %C %lud)\n", up->pid, c2name(c), c->qid.path, devtab[c->type]->dc, c->dev); return 0; } diff --git a/port/devloopback.c b/port/devloopback.c index bb113e4d0f0d11ff457f669212f99fe3839eb77b..84c002aadf5e497754b9f94fb811c118061a0475 100644 --- a/port/devloopback.c +++ b/port/devloopback.c @@ -185,21 +185,6 @@ loopbackattach(char *spec) return c; } -static Chan* -loopbackclone(Chan *c, Chan *nc) -{ - Loop *lb; - - lb = c->aux; - nc = devclone(c, nc); - qlock(lb); - lb->ref++; - if((c->flag & COPEN) && TYPE(c->qid.path) == Qdata) - lb->link[ID(c->qid.path)].ref++; - qunlock(lb); - return nc; -} - static int loopbackgen(Chan *c, char*, Dirtab*, int, int i, Dir *dp) { @@ -247,7 +232,7 @@ loopbackgen(Chan *c, char*, Dirtab*, int, int i, Dir *dp) if(i >= nelem(loopportdir)) return -1; tab = &loopportdir[i]; - mkqid(&qid, QID(ID(c->qid.path), tab->qid.path), 0, QTDIR); + mkqid(&qid, QID(ID(c->qid.path), tab->qid.path), 0, QTFILE); devdir(c, qid, tab->name, tab->length, eve, tab->perm, dp); return 1; default: @@ -273,7 +258,19 @@ loopbackgen(Chan *c, char*, Dirtab*, int, int i, Dir *dp) static Walkqid* loopbackwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, nc, name, nname, nil, 0, loopbackgen); + Walkqid *wq; + Loop *lb; + + wq = devwalk(c, nc, name, nname, nil, 0, loopbackgen); + if(wq != nil && wq->clone != nil && wq->clone != c){ + lb = c->aux; + qlock(lb); + lb->ref++; + if((c->flag & COPEN) && TYPE(c->qid.path) == Qdata) + lb->link[ID(c->qid.path)].ref++; + qunlock(lb); + } + return wq; } static int diff --git a/port/devmnt.c b/port/devmnt.c index cdeec2218e985c8b17b8117326b1f4feab75c245..404d506057262e104224dc6d2cf9e05314edb719 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -80,7 +80,7 @@ static Chan* mntattach(char *muxattach) { Mnt *m; - Chan *c, *mc; + Chan *c; struct bogus{ Chan *chan; char *spec; @@ -155,23 +155,6 @@ mntattach(char *muxattach) mattach(m, c, bogus.spec); poperror(); - /* - * Detect a recursive mount for a mount point served by exportfs. - * If QTDIR is clear in the returned qid, the foreign server is - * requesting the mount point be folded into the connection - * to the exportfs. In this case the remote mount driver does - * the multiplexing. - */ - mc = m->c; - if(mc->type == devno('M', 0) && (c->qid.type&QTDIR) == 0) { - mclose(m, c); - c->qid.type |= QTDIR; - c->mntptr = mc->mntptr; - c->mchan = c->mntptr->c; - c->mqid = c->qid; - incref(c->mntptr); - } - if(bogus.flags & MCACHE) c->flag |= CCACHE; @@ -227,8 +210,8 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) Mnt *m; Mntrpc *r; Walkqid *wq; -extern int chandebug; -if(chandebug){ + +if(0){ print("mntwalk "); for(i=0; ierror, "interrupt") == nil) + nexterror(); + dm = 0; + continue; + } dm = devtab[c->type]->read(c, buf, n-m, 0); + if(uninterruptable) + poperror(); if(dm <= 0) return 0; buf += dm; @@ -703,7 +696,7 @@ mntrpcread(Mnt *m, Mntrpc *r) r->reply.type = 0; r->reply.tag = 0; /* read size, then read exactly the right number of bytes */ - n = mntreadn(m->c, r->rpc, BIT32SZ); + n = mntreadn(m->c, r->rpc, BIT32SZ, 0); if(n != BIT32SZ){ if(n > 0) print("devmnt expected BIT32SZ got %d\n", n); @@ -714,7 +707,7 @@ mntrpcread(Mnt *m, Mntrpc *r) print("devmnt: len %d max messagesize %ld\n", len, m->c->iounit); return -1; } - n += mntreadn(m->c, r->rpc+BIT32SZ, len-BIT32SZ); + n += mntreadn(m->c, r->rpc+BIT32SZ, len-BIT32SZ, 1); if(n != len){ print("devmnt: length %d expected %d\n", n, len); return -1;