From 6aed9711b41746fc6fc3428d27b2a99c4e4d36d8 Mon Sep 17 00:00:00 2001 From: aiju Date: Sat, 30 Jul 2011 14:30:27 +0200 Subject: [PATCH] =?UTF-8?q?devshr:=20changed=20#=CF=83c=20to=20contain=20d?= =?UTF-8?q?irectories=20nusb:=20detaching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sys/include/9p.h | 8 +- sys/src/9/boot/nusbrc | 4 + sys/src/9/port/devshr.c | 358 ++++++++++++++++++----------------- sys/src/cmd/nusb/disk/disk.c | 4 +- sys/src/cmd/nusb/usbd/fns.h | 1 + sys/src/cmd/nusb/usbd/hub.c | 5 +- sys/src/cmd/nusb/usbd/usbd.c | 20 +- sys/src/lib9p/post.c | 4 +- sys/src/lib9p/rfork.c | 4 +- sys/src/lib9p/srv.c | 6 +- sys/src/lib9p/thread.c | 4 +- 11 files changed, 228 insertions(+), 190 deletions(-) diff --git a/sys/include/9p.h b/sys/include/9p.h index fb2862438..85e2304ba 100644 --- a/sys/include/9p.h +++ b/sys/include/9p.h @@ -216,17 +216,17 @@ struct Srv { void srv(Srv*); void postmountsrv(Srv*, char*, char*, int); void _postmountsrv(Srv*, char*, char*, int); -void postsharesrv(Srv*, char*, char*, char*, char*); -void _postsharesrv(Srv*, char*, char*, char*, char*); +void postsharesrv(Srv*, char*, char*, char*); +void _postsharesrv(Srv*, char*, char*, char*); void listensrv(Srv*, char*); void _listensrv(Srv*, char*); int postfd(char*, int); -int sharefd(char*, char*, char*, int); +int sharefd(char*, char*, int); int chatty9p; void respond(Req*, char*); void responderror(Req*); void threadpostmountsrv(Srv*, char*, char*, int); -void threadpostsharesrv(Srv*, char*, char*, char*, char*); +void threadpostsharesrv(Srv*, char*, char*, char*); void threadlistensrv(Srv *s, char *addr); /* diff --git a/sys/src/9/boot/nusbrc b/sys/src/9/boot/nusbrc index c7f439ed9..2496cb3e0 100644 --- a/sys/src/9/boot/nusbrc +++ b/sys/src/9/boot/nusbrc @@ -2,6 +2,7 @@ if(! bind -a '#u' /dev) exit +mkdir '#σc/usb' if(! nusb/usbd) exit @@ -15,5 +16,8 @@ fn dev { nusb/disk $1 } } +fn rmdev { + rm -f '#σc/usb/'*'-'^$2 +} rc next; free(m); } - if(sp->desc != nil) - free(sp->desc); free(sp->owner); free(sp->name); free(sp); @@ -69,10 +65,10 @@ shrgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) return -1; } - mkqid(&q, sp->path, 0, c->dev ? QTFILE : QTDIR); + mkqid(&q, sp->path, 0, QTDIR); /* make sure name string continues to exist after we release lock */ kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); - devdir(c, q, up->genbuf, 0, sp->owner, sp->perm & (c->dev ? ~0111 : ~0), dp); + devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); qunlock(&shrlk); return 1; } @@ -100,15 +96,56 @@ shrattach(char *spec) } static Shr* -shrlookup(char *name, ulong qidpath) +shrlookup(char *name, uvlong qidpath) { Shr *sp; + qidpath &= 0xFFFFFFFF00000000ULL; for(sp = shr; sp; sp = sp->link) if(sp->path == qidpath || (name && strcmp(sp->name, name) == 0)) return sp; return nil; } +static Mount* +mntlookup(Shr *sp, char *name, uvlong qidpath) +{ + Mount *m; + qidpath &= 0xFFFFFFFFULL; + for(m = sp->umh.mount; m != nil; m = m->next) + if(m->mountid == qidpath || (name && strcmp((char*)(m + 1), name) == 0)) + return m; + return nil; +} + +static int +shrcnfgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) +{ + Shr *sp; + Mount *m; + Qid q; + + qlock(&shrlk); + sp = shrlookup(nil, c->qid.path); + if(sp == nil){ + qunlock(&shrlk); + return -1; + } + rlock(&sp->umh.lock); + for(m = sp->umh.mount; m != nil && s > 0; m = m->next) + s--; + if(m == nil){ + runlock(&sp->umh.lock); + qunlock(&shrlk); + return -1; + } + kstrcpy(up->genbuf, (char*)(m + 1), sizeof up->genbuf); + mkqid(&q, sp->path | m->mountid, 0, QTFILE); + devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); + runlock(&sp->umh.lock); + qunlock(&shrlk); + return 1; +} + static int shrremovemnt(Shr *sp, int id) { @@ -130,10 +167,6 @@ shrremovemnt(Shr *sp, int id) wunlock(&sp->umh.lock); return -1; } - qlock(&sp->desclock); - free(sp->desc); - sp->desc = nil; - qunlock(&sp->desclock); wunlock(&sp->umh.lock); return 0; } @@ -191,12 +224,12 @@ shrwalk(Chan *c, Chan *nc, char **name, int nname) } devpermcheck(sp->owner, sp->perm, OEXEC); poperror(); - mkqid(&nc->qid, sp->path, 0, c->dev ? QTFILE : QTDIR); + mkqid(&nc->qid, sp->path, 0, QTDIR); } qunlock(&shrlk); if(sp == nil) goto Error; - } else { + } else if(c->dev == 0) { qlock(&shrlk); sp = shrlookup(nil, nc->qid.path); if(sp != nil) @@ -225,6 +258,25 @@ shrwalk(Chan *c, Chan *nc, char **name, int nname) poperror(); return wq; } + else{ + qlock(&shrlk); + sp = shrlookup(nil, nc->qid.path); + if(sp == nil){ + qunlock(&shrlk); + goto Error; + } + rlock(&sp->umh.lock); + f = mntlookup(sp, n, -1); + if(f == nil){ + runlock(&sp->umh.lock); + qunlock(&shrlk); + goto Error; + } + nc->qid.path |= f->mountid; + nc->qid.type = QTFILE; + runlock(&sp->umh.lock); + qunlock(&shrlk); + } wq->qid[wq->nqid++] = nc->qid; } @@ -247,7 +299,43 @@ Done: static int shrstat(Chan *c, uchar *db, int n) { - return devstat(c, db, n, 0, 0, shrgen); + Shr *sp; + Mount *f; + Dir dir; + int rc; + + if(c->qid.path == 0) + devdir(c, c->qid, c->dev ? "#σc" : "#σ", 0, eve, 0555, &dir); + else { + qlock(&shrlk); + if(waserror()){ + qunlock(&shrlk); + nexterror(); + } + sp = shrlookup(nil, c->qid.path); + if(sp == nil) + error(Enonexist); + if((c->qid.path & 0xFFFF) == 0){ + kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); + devdir(c, c->qid, up->genbuf, 0, sp->owner, sp->perm, &dir); + }else{ + rlock(&sp->umh.lock); + f = mntlookup(sp, nil, c->qid.path); + if(f == nil){ + runlock(&sp->umh.lock); + error(Enonexist); + } + kstrcpy(up->genbuf, (char*)(f + 1), sizeof up->genbuf); + devdir(c, c->qid, up->genbuf, 0, sp->owner, sp->perm, &dir); + runlock(&sp->umh.lock); + } + qunlock(&shrlk); + poperror(); + } + rc = convD2M(&dir, db, n); + if(rc == 0) + error(Ebadarg); + return rc; } static Chan* @@ -266,7 +354,7 @@ shropen(Chan *c, int omode) sp = shrlookup(nil, c->qid.path); if(sp == nil) error(Enonexist); - if(c->qid.type == QTDIR) + if(c->dev == 0) c->umh = &sp->umh; devpermcheck(sp->owner, sp->perm, openmode(omode)); qunlock(&shrlk); @@ -281,43 +369,42 @@ shropen(Chan *c, int omode) } static void -shrunioncreate(Chan *c, char *name, int omode, ulong perm) +shrcnfcreate(Chan *c, char *name, int omode, ulong) { Shr *sp; - Mount *m; - Walkqid *wq; - - error(Enocreate); /* code below is broken */ + Mount *m, *mm; qlock(&shrlk); - sp = shrlookup(nil, c->qid.path); - if(sp != nil) - incref(sp); - qunlock(&shrlk); - if(sp == nil) - error(Enonexist); if(waserror()){ - shrdecref(sp); + qunlock(&shrlk); nexterror(); } - for(m = sp->umh.mount; m != nil; m = m->next) - if(m->mflag & MCREATE) - break; - if(m == nil) - error(Enocreate); - - wq = devtab[m->to->type]->walk(m->to, c, nil, 0); - if(wq == nil) - error(Egreg); - if(wq->clone != c){ - cclose(wq->clone); - free(wq); - error(Egreg); + sp = shrlookup(nil, c->qid.path); + if(sp == nil) + error(Enonexist); + wlock(&sp->umh.lock); + if(mntlookup(sp, name, -1)){ + wunlock(&sp->umh.lock); + error(Eexist); } - free(wq); - devtab[c->type]->create(c, name, omode, perm); - shrdecref(sp); + m = smalloc(sizeof(Mount) + strlen(name) + 1); + m->mountid = ++mntid; + mkqid(&c->qid, m->mountid | sp->path, 0, QTFILE); + strcpy((char*)(m + 1), name); + if(sp->umh.mount != nil) { + for(mm = sp->umh.mount; mm->next != nil; mm = mm->next) + ; + mm->next = m; + } else { + m->next = sp->umh.mount; + sp->umh.mount = m; + } + wunlock(&sp->umh.lock); + qunlock(&shrlk); poperror(); + + c->flag |= COPEN; + c->mode = openmode(omode); } static void @@ -326,17 +413,20 @@ shrcreate(Chan *c, char *name, int omode, ulong perm) char *sname; Shr *sp; - if(c->qid.path != 0) { - shrunioncreate(c, name, omode, perm); - return; - } - - if(c->dev != 1) - error(Eperm); - if(omode & OCEXEC) /* can't happen */ panic("someone broke namec"); + if(c->dev == 0 && c->qid.path != 0) + error(Enocreate); + + if(c->qid.path != 0){ + shrcnfcreate(c, name, omode, perm); + return; + } + + if(c->dev != 1 || (perm & DMDIR) == 0 || openmode(omode) != OREAD) + error(Eperm); + sp = smalloc(sizeof *sp); sname = smalloc(strlen(name)+1); @@ -352,22 +442,22 @@ shrcreate(Chan *c, char *name, int omode, ulong perm) if(shrlookup(name, -1)) error(Eexist); - sp->path = qidpath++; + sp->path = ((uvlong)qidpath++) << 32; sp->link = shr; strcpy(sname, name); sp->name = sname; incref(sp); - c->qid.type = QTFILE; + c->qid.type = QTDIR; c->qid.path = sp->path; shr = sp; qunlock(&shrlk); poperror(); kstrdup(&sp->owner, up->user); - sp->perm = (perm&0777) | ((perm&0444)>>2); + sp->perm = perm & 0777; c->flag |= COPEN; - c->mode = OWRITE; + c->mode = OREAD; } static void @@ -385,13 +475,20 @@ shrremove(Chan *c) } l = &shr; for(sp = *l; sp; sp = sp->link) { - if(sp->path == c->qid.path) + if(sp->path == (c->qid.path & 0xFFFFFFFF00000000ULL)) break; l = &sp->link; } if(sp == 0) error(Enonexist); + if(c->qid.path & 0xFFFFFFFF){ + if(shrremovemnt(sp, c->qid.path) < 0) + error(Enonexist); + qunlock(&shrlk); + poperror(); + return; + } if(strcmp(sp->owner, eve) == 0 && !iseve()) error(Eperm); @@ -462,159 +559,82 @@ shrclose(Chan *c) } static long -shrread(Chan *c, void *va, long n, vlong off) +shrread(Chan *c, void *va, long n, vlong) { - Shr *sp; - long ret; - int nn; - Mount *f; - char *s, *e; - if(c->qid.path == 0) return devdirread(c, va, n, 0, 0, shrgen); - if(c->qid.type & QTDIR) + if(c->dev == 0) return unionread(c, va, n); - qlock(&shrlk); - sp = shrlookup(nil, c->qid.path); - if(sp != nil) - incref(sp); - qunlock(&shrlk); - if(sp == nil) - error(Enonexist); - qlock(&sp->desclock); - if(sp->desc == nil){ - nn = 0; - rlock(&sp->umh.lock); - for(f = sp->umh.mount; f != nil; f = f->next) - nn += 32 + strlen((char*)(f + 1)); - s = sp->desc = smalloc(nn + 1); - e = s + nn; - for(f = sp->umh.mount; f != nil; f = f->next) - s = seprint(s, e, "%lud %s %C %lud %lld\n", f->mountid, (char*)(f + 1), devtab[f->to->mchan->type]->dc, f->to->mchan->dev, f->to->qid.path); - runlock(&sp->umh.lock); - } - ret = readstr(off, va, n, sp->desc); - qunlock(&sp->desclock); - shrdecref(sp); - return ret; + if((long)c->qid.path == 0) + return devdirread(c, va, n, 0, 0, shrcnfgen); + + error(Egreg); + return 0; } static long shrwrite(Chan *c, void *va, long n, vlong) { Shr *sp; - char *buf, *p, *desc, *aname; - int mode, fd, id; + char *buf, *p, *aname; + int fd; Chan *bc, *c0; - Mount *m, *mm; + Mount *m; struct{ Chan *chan; Chan *authchan; char *spec; int flags; }bogus; - - qlock(&shrlk); - sp = shrlookup(nil, c->qid.path); - if(sp != nil) - incref(sp); - qunlock(&shrlk); - if(sp == nil) - error(Enonexist); + buf = smalloc(n+1); if(waserror()){ - shrdecref(sp); free(buf); nexterror(); } memmove(buf, va, n); buf[n] = 0; - if(*buf == 'u'){ - p = buf + 1; - while(*p <= ' ' && *p != '\n') - p++; - if(*p == 0 || *p == '\n') - error(Ebadarg); - id = strtol(p, 0, 10); - if(shrremovemnt(sp, id) < 0) - error(Ebadarg); - shrdecref(sp); - free(buf); - poperror(); - return n; - } - - p = buf; - mode = 0; - for(; *p > ' '; p++) - switch(*p) { - case 'a': mode |= MAFTER; break; - case 'b': mode |= MBEFORE; break; - case 'c': mode |= MCREATE; break; - case 'C': mode |= MCACHE; break; - default: error(Ebadarg); - } - - if((mode & (MAFTER|MBEFORE)) == 0 || (mode & (MAFTER|MBEFORE)) == (MAFTER|MBEFORE)) + fd = strtol(buf, &p, 10); + if(p == buf || (*p != 0 && *p != '\n')) error(Ebadarg); - while(*p <= ' ' && *p != '\n') - p++; - if(*p == 0 || *p == '\n') - error(Ebadarg); - fd = strtol(p, &p, 10); - while(*p <= ' ' && *p != '\n') - p++; - if(*p != 0 && *p != '\n') { - desc = p; - p = strchr(desc, '\n'); - if(p != nil) - *p = 0; - } else - desc = ""; - aname = strchr(buf, '\n'); - if(aname != nil && *++aname == 0) + if(*p == '\n' && *(p+1) != 0) + aname = p + 1; + else aname = nil; - if(strlen(desc) > 128) - error(Ebadarg); - + bc = fdtochan(fd, ORDWR, 0, 1); if(waserror()) { cclose(bc); nexterror(); } - bogus.flags = mode & MCACHE; + bogus.flags = 0; bogus.chan = bc; bogus.authchan = nil; bogus.spec = aname; c0 = devtab[devno('M', 0)]->attach((char*)&bogus); cclose(bc); poperror(); - - m = smalloc(sizeof(Mount) + strlen(desc) + 1); - strcpy((char*)(m + 1), desc); - m->to = c0; - m->mflag = mode; qlock(&shrlk); - m->mountid = ++mntid; - qunlock(&shrlk); - wlock(&sp->umh.lock); - if((mode & MAFTER) != 0 && sp->umh.mount != nil) { - for(mm = sp->umh.mount; mm->next != nil; mm = mm->next) - ; - mm->next = m; - } else { - m->next = sp->umh.mount; - sp->umh.mount = m; + sp = shrlookup(nil, c->qid.path); + if(sp == nil){ + qunlock(&shrlk); + cclose(c0); + error(Enonexist); } - wunlock(&sp->umh.lock); - qlock(&sp->desclock); - free(sp->desc); - sp->desc = nil; - qunlock(&sp->desclock); - shrdecref(sp); + rlock(&sp->umh.lock); + m = mntlookup(sp, nil, c->qid.path); + if(m == nil){ + runlock(&sp->umh.lock); + qunlock(&shrlk); + cclose(c0); + error(Enonexist); + } + m->to = c0; + runlock(&sp->umh.lock); + qunlock(&shrlk); free(buf); poperror(); return n; @@ -651,4 +671,4 @@ shrrenameuser(char *old, char *new) if(sp->owner!=nil && strcmp(old, sp->owner)==0) kstrdup(&sp->owner, new); qunlock(&shrlk); -} \ No newline at end of file +} diff --git a/sys/src/cmd/nusb/disk/disk.c b/sys/src/cmd/nusb/disk/disk.c index 171b9930e..edf2e6a40 100644 --- a/sys/src/cmd/nusb/disk/disk.c +++ b/sys/src/cmd/nusb/disk/disk.c @@ -1011,6 +1011,7 @@ main(int argc, char **argv) { Umsc *lun; int i; + char buf[20]; ARGBEGIN{ case 'd': @@ -1046,6 +1047,7 @@ main(int argc, char **argv) snprint(lun->name, sizeof(lun->name), "sdU%d.%d", dev->id, i); makeparts(lun); } - postsharesrv(&diskfs, "usbdisk", "usb", "disk", "b"); + snprint(buf, sizeof buf, "disk-%s", *argv); + postsharesrv(&diskfs, nil, "usb", buf); exits(nil); } diff --git a/sys/src/cmd/nusb/usbd/fns.h b/sys/src/cmd/nusb/usbd/fns.h index f6f2add65..2a2fff84b 100644 --- a/sys/src/cmd/nusb/usbd/fns.h +++ b/sys/src/cmd/nusb/usbd/fns.h @@ -1,3 +1,4 @@ int startdev(Port*); +int removedev(Port*); void work(void); Hub* newhub(char *, Dev *); diff --git a/sys/src/cmd/nusb/usbd/hub.c b/sys/src/cmd/nusb/usbd/hub.c index 6d64c001d..50c9ad7e2 100644 --- a/sys/src/cmd/nusb/usbd/hub.c +++ b/sys/src/cmd/nusb/usbd/hub.c @@ -622,9 +622,10 @@ enumhub(Hub *h, int p) if(portattach(h, p, sts) != nil) if(startdev(pp) < 0) portdetach(h, p); - }else if(portgone(pp, sts)) + }else if(portgone(pp, sts)){ + removedev(pp); portdetach(h, p); - else if(portresetwanted(h, p)) + }else if(portresetwanted(h, p)) portreset(h, p); else if(pp->sts != sts){ dprint(2, "%s: %s port %d: sts %s %#x ->", diff --git a/sys/src/cmd/nusb/usbd/usbd.c b/sys/src/cmd/nusb/usbd/usbd.c index 84e121957..2e3c24aeb 100644 --- a/sys/src/cmd/nusb/usbd/usbd.c +++ b/sys/src/cmd/nusb/usbd/usbd.c @@ -203,12 +203,12 @@ usbdstat(Req *req) } static char * -formatdev(Dev *d) +formatdev(Dev *d, int type) { Usbdev *u; u = d->usb; - return smprint("dev %d %.4x %.4x %.8lx\n", d->id, u->vid, u->did, u->csp); + return smprint("%s %d %.4x %.4x %.8lx\n", type ? "rmdev" : "dev", d->id, u->vid, u->did, u->csp); } static void @@ -224,7 +224,7 @@ enumerate(Event **l) if(p->dev == nil || p->dev->usb == nil || p->hub != nil) continue; e = emallocz(sizeof(Event), 1); - e->data = formatdev(p->dev); + e->data = formatdev(p->dev, 0); e->len = strlen(e->data); e->prev = 1; *l = e; @@ -323,7 +323,17 @@ startdev(Port *p) } close(d->dfd); d->dfd = -1; - pushevent(formatdev(d)); + pushevent(formatdev(d, 0)); + return 0; +} + +int +removedev(Port *p) +{ + Dev *d; + if((d = p->dev) == nil || p->dev->usb == nil) + return -1; + pushevent(formatdev(d, 1)); return 0; } @@ -358,6 +368,6 @@ main(int argc, char **argv) for(i = 0; i < argc; i++) rendezvous(work, strdup(argv[i])); rendezvous(work, nil); - postsharesrv(&usbdsrv, nil, "usb", "usbd", "b"); + postsharesrv(&usbdsrv, nil, "usb", "usbd"); exits(nil); } diff --git a/sys/src/lib9p/post.c b/sys/src/lib9p/post.c index 37dcfd5dc..8abddfbd1 100644 --- a/sys/src/lib9p/post.c +++ b/sys/src/lib9p/post.c @@ -57,7 +57,7 @@ _postmountsrv(Srv *s, char *name, char *mtpt, int flag) } void -_postsharesrv(Srv *s, char *name, char *mtpt, char *desc, char *flag) +_postsharesrv(Srv *s, char *name, char *mtpt, char *desc) { int fd[2]; @@ -99,7 +99,7 @@ _postsharesrv(Srv *s, char *name, char *mtpt, char *desc, char *flag) } if(mtpt){ - if(sharefd(mtpt, desc, flag, s->srvfd) < 0) + if(sharefd(mtpt, desc, s->srvfd) < 0) sysfatal("sharefd %s: %r", mtpt); }else close(s->srvfd); diff --git a/sys/src/lib9p/rfork.c b/sys/src/lib9p/rfork.c index 37cf6448b..45bf59365 100644 --- a/sys/src/lib9p/rfork.c +++ b/sys/src/lib9p/rfork.c @@ -33,8 +33,8 @@ postmountsrv(Srv *s, char *name, char *mtpt, int flag) } void -postsharesrv(Srv *s, char *name, char *mtpt, char *desc, char *flag) +postsharesrv(Srv *s, char *name, char *mtpt, char *desc) { _forker = rforker; - _postsharesrv(s, name, mtpt, desc, flag); + _postsharesrv(s, name, mtpt, desc); } diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c index bbe025b46..a0b89cba8 100644 --- a/sys/src/lib9p/srv.c +++ b/sys/src/lib9p/srv.c @@ -852,12 +852,12 @@ postfd(char *name, int pfd) } int -sharefd(char *name, char *desc, char *flags, int pfd) +sharefd(char *name, char *desc, int pfd) { int fd; char buf[80]; - snprint(buf, sizeof buf, "#σc/%s", name); + snprint(buf, sizeof buf, "#σc/%s/%s", name, desc); if(chatty9p) fprint(2, "sharefd %s\n", buf); fd = create(buf, OWRITE, 0600); @@ -866,7 +866,7 @@ sharefd(char *name, char *desc, char *flags, int pfd) fprint(2, "create fails: %r\n"); return -1; } - if(fprint(fd, "%s %d %s\n", flags, pfd, desc) < 0){ + if(fprint(fd, "%d\n", pfd) < 0){ if(chatty9p) fprint(2, "write fails: %r\n"); close(fd); diff --git a/sys/src/lib9p/thread.c b/sys/src/lib9p/thread.c index 61de5823e..445791be4 100644 --- a/sys/src/lib9p/thread.c +++ b/sys/src/lib9p/thread.c @@ -25,8 +25,8 @@ threadpostmountsrv(Srv *s, char *name, char *mtpt, int flag) } void -threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc, char* flag) +threadpostsharesrv(Srv *s, char *name, char *mtpt, char *desc) { _forker = tforker; - _postsharesrv(s, name, mtpt, desc, flag); + _postsharesrv(s, name, mtpt, desc); }