code: plan9front

Download patch

ref: cac03f355caa29a6bd5cafd7d0d6ca362149cb27
parent: 9e363c506eccb783dd4d1d31f14c9d8dba98f65e
author: Jacob Moody <moody@posixcafe.org>
date: Wed Jun 29 13:35:27 EDT 2022

kernel: revert /srv/clone

--- a/sys/man/3/srv
+++ b/sys/man/3/srv
@@ -5,8 +5,6 @@
 .nf
 .B bind #s /srv
 
-.BI #s/ clone
-.BI #s/ n
 .BI #s/ service1
 .BI #s/ service2
  ...
@@ -14,7 +12,7 @@
 .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 @@
 .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 ,
--- a/sys/src/9/port/devsrv.c
+++ b/sys/src/9/port/devsrv.c
@@ -5,213 +5,61 @@
 #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
-{
-	Link;
-	RWlock;
-	Ref;
+static QLock	srvlk;
+static Srv	*srv;
+static int	qidpath;
 
-	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)
+static Srv*
+srvlookup(char *name, ulong qidpath)
 {
-	Link *lp;
+	Srv *sp;
 
-	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)
+	qlock(&srvlk);
+	if(name != nil)
+		sp = srvlookup(name, -1);
+	else {
+		for(sp = srv; sp != nil && s > 0; sp = sp->link)
 			s--;
-		for(ch = b->child; ch != nil && s > 0; ch = ch->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;
 }
 
@@ -218,36 +66,19 @@
 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 @@
 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,7 +103,7 @@
 			break;
 		}
 	}
-	runlock(b);
+	qunlock(&srvlk);
 	return s;
 }
 
@@ -281,10 +110,8 @@
 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 @@
 		c->offset = 0;
 		return c;
 	}
-	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);
+	qlock(&srvlk);
 	if(waserror()){
-		runlock(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 || sp->chan == nil)
 		error(Eshutdown);
 
+	if(omode&OTRUNC)
+		error(Eexist);
+	if(omode&ORCLOSE)
+		error(Eperm);
 	if(openmode(omode)!=sp->chan->mode && sp->chan->mode!=ORDWR)
 		error(Eperm);
 	devpermcheck(sp->owner, sp->perm, omode);
@@ -350,7 +144,7 @@
 	nc = sp->chan;
 	incref(nc);
 
-	runlock(b);
+	qunlock(&srvlk);
 	poperror();
 
 	cclose(c);
@@ -360,7 +154,6 @@
 static Chan*
 srvcreate(Chan *c, char *name, int omode, ulong perm)
 {
-	Board *b;
 	Srv *sp;
 
 	if(openmode(omode) != OWRITE)
@@ -373,33 +166,27 @@
 	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)
+	if(srvlookup(name, -1) != nil)
 		error(Eexist);
-	if(lookup(b->child, name, ~0UL) != 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 @@
 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 @@
 	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,7 +245,6 @@
 static int
 srvwstat(Chan *c, uchar *dp, int n)
 {
-	Board *b;
 	char *strs;
 	Srv *sp;
 	Dir d;
@@ -466,11 +251,6 @@
 
 	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 @@
 	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 @@
 			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 @@
 	if(d.mode != ~0UL)
 		sp->perm = d.mode & 0777;
 
-	wunlock(b);
+	qunlock(&srvlk);
 	poperror();
 
 	free(strs);
@@ -525,47 +298,22 @@
 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 @@
 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 @@
 
 	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 @@
 
 	sp->chan = c1;
 
-	wunlock(b);
+	qunlock(&srvlk);
 	poperror();
 	return n;
 }
@@ -639,14 +380,12 @@
 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);
 }