From cac03f355caa29a6bd5cafd7d0d6ca362149cb27 Mon Sep 17 00:00:00 2001 From: Jacob Moody Date: Wed, 29 Jun 2022 17:35:27 +0000 Subject: [PATCH] kernel: revert /srv/clone --- sys/man/3/srv | 16 +- sys/src/9/port/devsrv.c | 431 ++++++++-------------------------------- 2 files changed, 86 insertions(+), 361 deletions(-) diff --git a/sys/man/3/srv b/sys/man/3/srv index b68f00887..820c849db 100644 --- a/sys/man/3/srv +++ b/sys/man/3/srv @@ -5,8 +5,6 @@ srv \- server registry .nf .B bind #s /srv -.BI #s/ clone -.BI #s/ n .BI #s/ service1 .BI #s/ service2 ... @@ -14,7 +12,7 @@ srv \- server registry .SH DESCRIPTION The .I srv -device provides a tree of directories holding +device provides a one-level directory holding already-open channels to services. In effect, .I srv @@ -42,18 +40,6 @@ releases that reference. .PP It is an error to write more than one number into a server file, or to create a file with a name that is already being used. -.PP -Opening the -.I clone -file allocates a new service directory. Reading -.I clone -returns the id of the new directory. This new service -directory can then be accessed at -.BR /srv/id . -Directories are recursable; each new service directory -contains its own -.I clone -file. .SH EXAMPLE To drop one end of a pipe into .BR /srv , diff --git a/sys/src/9/port/devsrv.c b/sys/src/9/port/devsrv.c index e1b7856f9..8128569a1 100644 --- a/sys/src/9/port/devsrv.c +++ b/sys/src/9/port/devsrv.c @@ -5,249 +5,80 @@ #include "fns.h" #include "../port/error.h" -#include "netif.h" - -typedef struct Link Link; -struct Link -{ - void *link; - char *name; - ulong path; -}; typedef struct Srv Srv; struct Srv { - Link; - + char *name; char *owner; ulong perm; Chan *chan; + Srv *link; + ulong path; }; -typedef struct Board Board; -struct Board +static QLock srvlk; +static Srv *srv; +static int qidpath; + +static Srv* +srvlookup(char *name, ulong qidpath) { - Link; - RWlock; - Ref; + Srv *sp; - Board *parent; - Board *child; - Srv *srv; - long id; - int qidpath; - int closed; -}; - -struct{ - QLock; - long path; -} boards; - -enum{ - Qroot, - Qclone, - Qlease, - - Qend, -}; - -Board root; - -static char Eexpired[] = "expired lease"; - -static void* -lookup(Link *l, char *name, ulong qidpath) -{ - Link *lp; - - if(qidpath != ~0UL) - qidpath = NETTYPE(qidpath); - for(lp = l; lp != nil; lp = lp->link){ - if(qidpath != ~0UL && lp->path == qidpath) - return lp; - if(name != nil && strcmp(lp->name, name) == 0) - return lp; + for(sp = srv; sp != nil; sp = sp->link) { + if(sp->path == qidpath || (name != nil && strcmp(sp->name, name) == 0)) + return sp; } return nil; } -static void* -remove(Link **l, char *name, ulong qidpath) -{ - Link *lp; - Link **last; - - if(qidpath != ~0UL) - qidpath = NETTYPE(qidpath); - last = l; - for(lp = *l; lp != nil; lp = lp->link){ - if(qidpath != ~0UL && lp->path == qidpath) - break; - if(name != nil && strcmp(lp->name, name) == 0) - break; - last = &lp->link; - } - if(lp == nil) - return nil; - - *last = lp->link; - lp->link = nil; - return lp; -} - -static void -boardclunk(Board *b, int close) -{ - Srv *sp, *prv; - Board *ch; - long ref; - - /* caller holds a wlock */ - if(b == &root){ - wunlock(b); - return; - } - - if(close){ - assert(b->closed == 0); - b->closed++; - for(sp = b->srv; sp != nil; sp = prv){ - prv = sp->link; - free(sp->owner); - free(sp->name); - if(sp->chan != nil) - cclose(sp->chan); - free(sp); - } - b->srv = nil; - } - ref = decref(b); - - /* - * All boards must be walkable from root. So a board - * is allowed to sit at zero references as long as it - * still has active children. For leaf nodes we then - * have to walk up the tree to clear now empty parents. - */ - while(b->closed && b->child == nil && ref == 0){ - //Root should never be closed - assert(b->parent != nil); - wlock(b->parent); - ch = remove((Link**)&b->parent->child, b->name, b->path); - assert(ch == b); - - b = ch->parent; - free(ch->name); - wunlock(ch); - free(ch); - } - wunlock(b); -} - static int srvgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) { Srv *sp; - Board *b, *ch; Qid q; - if(name != nil && strlen(name) >= sizeof(up->genbuf)) - return -1; - - b = c->aux; - ch = nil; - mkqid(&q, ~0L, 0, QTFILE); - rlock(b); - if(waserror()){ - runlock(b); - return -1; - } if(s == DEVDOTDOT){ - ch = b->parent; - if(ch == nil) - ch = &root; - goto Child; - + devdir(c, c->qid, "#s", 0, eve, 0555, dp); + return 1; } - if(name != nil){ - if(strcmp("clone", name) == 0) - goto Clone; - sp = lookup(b->srv, name, ~0UL); - if(sp == nil) - ch = lookup(b->child, name, ~0UL); - } else { - if(s == 0) - goto Clone; - s--; - for(sp = b->srv; sp != nil && s > 0; sp = sp->link) - s--; - for(ch = b->child; ch != nil && s > 0; ch = ch->link) + qlock(&srvlk); + if(name != nil) + sp = srvlookup(name, -1); + else { + for(sp = srv; sp != nil && s > 0; sp = sp->link) s--; } - if(sp != nil){ - kstrcpy(up->genbuf, sp->name, sizeof up->genbuf); - q.vers = NETID(c->qid.path); - q.path = NETQID(q.vers, sp->path); - devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp); - } else if(ch != nil){ -Child: - kstrcpy(up->genbuf, ch->name, sizeof up->genbuf); - q.vers = ch->id; - q.path = NETQID(q.vers, ch->path); - q.type = QTDIR; - devdir(c, q, up->genbuf, 0, eve, 0555|DMDIR, dp); - /* dirread's and stats shouldn't alter c->aux */ - if(name != nil) - c->aux = ch; - } else if(0){ -Clone: - q.vers = NETID(c->qid.path); - q.path = NETQID(q.vers, Qclone); - devdir(c, q, "clone", 0, eve, 0444, dp); - } else - error(Enonexist); - - runlock(b); - poperror(); + if(sp == nil || (name != nil && (strlen(sp->name) >= sizeof(up->genbuf)))) { + qunlock(&srvlk); + return -1; + } + mkqid(&q, sp->path, 0, QTFILE); + /* 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, dp); + qunlock(&srvlk); return 1; } static void srvinit(void) { - root.qidpath = Qend; - root.name = "#s"; + qidpath = 1; } static Chan* srvattach(char *spec) { - Chan *c; - - c = devattach('s', spec); - c->aux = &root; - return c; + return devattach('s', spec); } static Walkqid* srvwalk(Chan *c, Chan *nc, char **name, int nname) { - Board *b; - Walkqid *wq; - - wq = devwalk(c, nc, name, nname, 0, 0, srvgen); - if(wq == nil || wq->clone == nil) - return wq; - - b = wq->clone->aux; - if(b == &root) - return wq; - - incref(b); - return wq; + return devwalk(c, nc, name, nname, 0, 0, srvgen); } static int @@ -259,14 +90,12 @@ srvstat(Chan *c, uchar *db, int n) char* srvname(Chan *c) { - Board *b; Srv *sp; char *s; s = nil; - b = &root; - rlock(b); - for(sp = b->srv; sp != nil; sp = sp->link) { + qlock(&srvlk); + for(sp = srv; sp != nil; sp = sp->link) { if(sp->chan == c){ s = malloc(3+strlen(sp->name)+1); if(s != nil) @@ -274,17 +103,15 @@ srvname(Chan *c) break; } } - runlock(b); + qunlock(&srvlk); return s; } static Chan* srvopen(Chan *c, int omode) { - Board *b, *ch; Srv *sp; Chan *nc; - char buf[64]; if(c->qid.type == QTDIR){ if(omode & ORCLOSE) @@ -296,53 +123,20 @@ srvopen(Chan *c, int omode) c->offset = 0; return c; } + qlock(&srvlk); + if(waserror()){ + qunlock(&srvlk); + nexterror(); + } + + sp = srvlookup(nil, c->qid.path); + if(sp == nil || sp->chan == nil) + error(Eshutdown); + if(omode&OTRUNC) error(Eexist); if(omode&ORCLOSE) error(Eperm); - - b = c->aux; - if(NETTYPE(c->qid.path) == Qclone){; - wlock(b); - if(b->closed){ - wunlock(b); - error(Eexpired); - } - ch = smalloc(sizeof *ch); - ch->qidpath = Qend; - ch->ref = 1; - do { - qlock(&boards); - ch->id = ++boards.path; - qunlock(&boards); - snprint(buf, sizeof buf, "%ld", ch->id); - } while(lookup(b->srv, buf, ~0UL) != nil); - - ch->parent = b; - ch->path = b->qidpath++; - kstrdup(&ch->name, buf); - - ch->link = b->child; - b->child = ch; - c->aux = ch; - c->qid.vers = ch->id; - c->qid.path = NETQID(ch->id, Qlease); - boardclunk(b, 0); //unlock - return c; - } - - rlock(b); - if(waserror()){ - runlock(b); - nexterror(); - } - if(b->closed) - error(Eexpired); - - sp = lookup(b->srv, nil, c->qid.path); - if(sp == nil || sp->chan == nil) - error(Eshutdown); - if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR) error(Eperm); devpermcheck(sp->owner, sp->perm, omode); @@ -350,7 +144,7 @@ srvopen(Chan *c, int omode) nc = sp->chan; incref(nc); - runlock(b); + qunlock(&srvlk); poperror(); cclose(c); @@ -360,7 +154,6 @@ srvopen(Chan *c, int omode) static Chan* srvcreate(Chan *c, char *name, int omode, ulong perm) { - Board *b; Srv *sp; if(openmode(omode) != OWRITE) @@ -373,33 +166,27 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) kstrdup(&sp->name, name); kstrdup(&sp->owner, up->user); - b = c->aux; - wlock(b); + qlock(&srvlk); if(waserror()){ - wunlock(b); + qunlock(&srvlk); free(sp->owner); free(sp->name); free(sp); nexterror(); } - if(b->closed) - error(Eexpired); - if(lookup(b->srv, name, ~0UL) != nil) - error(Eexist); - if(lookup(b->child, name, ~0UL) != nil) + if(srvlookup(name, -1) != nil) error(Eexist); sp->perm = perm&0777; - sp->path = b->qidpath++; + sp->path = qidpath++; - c->qid.path = NETQID(b->id, sp->path); - c->qid.vers = b->id; + c->qid.path = sp->path; c->qid.type = QTFILE; - sp->link = b->srv; - b->srv = sp; + sp->link = srv; + srv = sp; - wunlock(b); + qunlock(&srvlk); poperror(); c->flag |= COPEN; @@ -411,24 +198,22 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) static void srvremove(Chan *c) { - Board *b; - Srv *sp; + Srv *sp, **l; if(c->qid.type == QTDIR) error(Eperm); - switch(NETTYPE(c->qid.path)){ - case Qlease: - case Qclone: - error(Eperm); - } - b = c->aux; - wlock(b); + qlock(&srvlk); if(waserror()){ - wunlock(b); + qunlock(&srvlk); nexterror(); } - sp = lookup(b->srv, nil, c->qid.path); + l = &srv; + for(sp = *l; sp != nil; sp = *l) { + if(sp->path == c->qid.path) + break; + l = &sp->link; + } if(sp == nil) error(Enonexist); @@ -444,9 +229,10 @@ srvremove(Chan *c) if((sp->perm&7) != 7 && strcmp(sp->owner, up->user) && !iseve()) error(Eperm); - remove((Link**)&b->srv, nil, c->qid.path); + *l = sp->link; + sp->link = nil; - boardclunk(b, 0); //unlock + qunlock(&srvlk); poperror(); if(sp->chan != nil) @@ -459,18 +245,12 @@ srvremove(Chan *c) static int srvwstat(Chan *c, uchar *dp, int n) { - Board *b; char *strs; Srv *sp; Dir d; if(c->qid.type & QTDIR) error(Eperm); - switch(NETTYPE(c->qid.path)){ - case Qlease: - case Qclone: - error(Eperm); - } strs = smalloc(n); if(waserror()){ @@ -481,16 +261,13 @@ srvwstat(Chan *c, uchar *dp, int n) if(n == 0) error(Eshortstat); - b = c->aux; - wlock(b); + qlock(&srvlk); if(waserror()){ - wunlock(b); + qunlock(&srvlk); nexterror(); } - if(b->closed) - error(Eexpired); - sp = lookup(b->srv, nil, c->qid.path); + sp = srvlookup(nil, c->qid.path); if(sp == nil) error(Enonexist); @@ -502,10 +279,6 @@ srvwstat(Chan *c, uchar *dp, int n) error(Ebadchar); if(strlen(d.name) >= sizeof(up->genbuf)) error(Etoolong); - if(lookup(b->srv, d.name, ~0UL) != nil) - error(Eexist); - if(lookup(b->child, d.name, ~0UL) != nil) - error(Eexist); kstrdup(&sp->name, d.name); } if(d.uid != nil && *d.uid) @@ -513,7 +286,7 @@ srvwstat(Chan *c, uchar *dp, int n) if(d.mode != ~0UL) sp->perm = d.mode & 0777; - wunlock(b); + qunlock(&srvlk); poperror(); free(strs); @@ -525,47 +298,22 @@ srvwstat(Chan *c, uchar *dp, int n) static void srvclose(Chan *c) { - Board *b; - int expired; - - expired = 0; - if(NETTYPE(c->qid.path) == Qlease) - expired++; - else if(c->flag & CRCLOSE){ - /* - * in theory we need to override any changes in removability - * since open, but since all that's checked is the owner, - * which is immutable, all is well. - */ + /* + * in theory we need to override any changes in removability + * since open, but since all that's checked is the owner, + * which is immutable, all is well. + */ + if(c->flag & CRCLOSE){ if(waserror()) - goto Clunk; + return; srvremove(c); poperror(); - return; } -Clunk: - b = c->aux; - wlock(b); - boardclunk(b, expired); //unlock } static long -srvread(Chan *c, void *va, long n, vlong off) +srvread(Chan *c, void *va, long n, vlong) { - Board *b; - - if(NETTYPE(c->qid.path) == Qlease){ - b = c->aux; - rlock(b); - if(waserror()){ - runlock(b); - nexterror(); - } - n = readstr((ulong)off, va, n, b->name); - runlock(b); - poperror(); - return n; - } isdir(c); return devdirread(c, va, n, 0, 0, srvgen); } @@ -573,15 +321,11 @@ srvread(Chan *c, void *va, long n, vlong off) static long srvwrite(Chan *c, void *va, long n, vlong) { - Board *b; Srv *sp; Chan *c1; int fd; char buf[32]; - if(NETTYPE(c->qid.path) == Qlease) - error(Eperm); - if(n >= sizeof buf) error(Etoobig); memmove(buf, va, n); /* so we can NUL-terminate */ @@ -590,18 +334,15 @@ srvwrite(Chan *c, void *va, long n, vlong) c1 = fdtochan(fd, -1, 0, 1); /* error check and inc ref */ - b = c->aux; - wlock(b); + qlock(&srvlk); if(waserror()) { - wunlock(b); + qunlock(&srvlk); cclose(c1); nexterror(); } - if(b->closed) - error(Eexpired); if(c1->qid.type & QTAUTH) error("cannot post auth file in srv"); - sp = lookup(b->srv, nil, c->qid.path); + sp = srvlookup(nil, c->qid.path); if(sp == nil) error(Enonexist); @@ -610,7 +351,7 @@ srvwrite(Chan *c, void *va, long n, vlong) sp->chan = c1; - wunlock(b); + qunlock(&srvlk); poperror(); return n; } @@ -639,14 +380,12 @@ Dev srvdevtab = { void srvrenameuser(char *old, char *new) { - Board *b; Srv *sp; - b = &root; - wlock(b); - for(sp = b->srv; sp != nil; sp = sp->link) { + qlock(&srvlk); + for(sp = srv; sp != nil; sp = sp->link) { if(sp->owner != nil && strcmp(old, sp->owner) == 0) kstrdup(&sp->owner, new); } - wunlock(b); + qunlock(&srvlk); }