shithub: gefs

Download patch

ref: 898b283a3c6c6df204e648269a9283cb7c026df8
parent: 6daa822ef03349606fc5936fddbb4591f6abae2d
author: Michael Forney <[email protected]>
date: Tue Mar 22 01:03:56 EDT 2022

add support for announcing on networks
Handle fsattach in runread and remove runfs from quiescers.

Add a Conn structure to track open fids per connection.  Move iounit
and versioned variables into this structure.

Make readmsg distinguish between EOF and errors.

--- a/dat.h
+++ b/dat.h
@@ -23,6 +23,7 @@
 typedef struct Mount	Mount;
 typedef struct User	User;
 typedef struct Stats	Stats;
+typedef struct Conn	Conn;
 
 enum {
 	KiB	= 1024ULL,
@@ -345,7 +346,7 @@
 
 struct Fmsg {
 	Fcall;
-	int	fd;	/* the fd to repsond on */
+	Conn	*conn;
 	int	sz;	/* the size of the message buf */
 	Amsg	*a;	/* admin messages */
 	uchar	buf[];
@@ -416,6 +417,9 @@
 	Mount	*mounts;
 	Tree	*osnap;
 
+	Lock	connlk;
+	Conn	*conns;
+
 	Chan	*wrchan;
 	Chan	*rdchan;
 	int	nquiesce;
@@ -438,10 +442,6 @@
 	User	*users;
 	int	nusers;
 
-	/* fid hash table */
-	Lock	fidtablk;
-	Fid	*fidtab[Nfidtab];
-
 	/* dent hash table */
 	Lock	dtablk;
 	Dent	*dtab[Ndtab];
@@ -506,6 +506,17 @@
 	vlong	gen;
 	char	*name;
 	Tree	*root;
+};
+
+struct Conn {
+	Conn	*next;
+	int	fd;
+	int	iounit;
+	int	versioned;
+
+	/* fid hash table */
+	Lock	fidtablk;
+	Fid	*fidtab[Nfidtab];
 };
 
 struct Fid {
--- a/fs.c
+++ b/fs.c
@@ -172,9 +172,9 @@
 	dprint("→ %F\n", r);
 	if((n = convS2M(r, buf, sizeof(buf))) == 0)
 		abort();
-	w = write(m->fd, buf, n);
+	w = write(m->conn->fd, buf, n);
 	if(w != n)
-		fshangup(m->fd, Eio);
+		fshangup(m->conn->fd, Eio);
 	free(m);
 }
 
@@ -401,33 +401,36 @@
 {
 	int i;
 	Fid *f;
+	Conn *c;
 
-	lock(&fs->fidtablk);
-	fprint(fd, "fids:---\n");
-	for(i = 0; i < Nfidtab; i++)
-		for(f = fs->fidtab[i]; f != nil; f = f->next){
-			rlock(f->dent);
-			fprint(fd, "\tfid[%d]: %d [refs=%ld, k=%K, qid=%Q]\n",
-				i, f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
-			runlock(f->dent);
-		}
-	unlock(&fs->fidtablk);
+	for(c = fs->conns; c != nil; c = c->next){
+		lock(&c->fidtablk);
+		fprint(fd, "fids:%d\n", c->fd);
+		for(i = 0; i < Nfidtab; i++)
+			for(f = c->fidtab[i]; f != nil; f = f->next){
+				rlock(f->dent);
+				fprint(fd, "\tfid[%d]: %d [refs=%ld, k=%K, qid=%Q]\n",
+					i, f->fid, f->dent->ref, &f->dent->Key, f->dent->qid);
+				runlock(f->dent);
+			}
+		unlock(&c->fidtablk);
+	}
 }
 
 static Fid*
-getfid(u32int fid)
+getfid(Conn *c, u32int fid)
 {
 	u32int h;
 	Fid *f;
 
 	h = ihash(fid) % Nfidtab;
-	lock(&fs->fidtablk);
-	for(f = fs->fidtab[h]; f != nil; f = f->next)
+	lock(&c->fidtablk);
+	for(f = c->fidtab[h]; f != nil; f = f->next)
 		if(f->fid == fid){
 			ainc(&f->ref);
 			break;
 		}
-	unlock(&fs->fidtablk);
+	unlock(&c->fidtablk);
 	return f;
 }
 
@@ -442,7 +445,7 @@
 }
 
 static Fid*
-dupfid(u32int new, Fid *f)
+dupfid(Conn *c, u32int new, Fid *f)
 {
 	Fid *n, *o;
 	u32int h;
@@ -459,16 +462,16 @@
 	if(n->mnt != nil)
 		ainc(&n->mnt->ref);
 
-	lock(&fs->fidtablk);
+	lock(&c->fidtablk);
 	ainc(&n->dent->ref);
-	for(o = fs->fidtab[h]; o != nil; o = o->next)
+	for(o = c->fidtab[h]; o != nil; o = o->next)
 		if(o->fid == new)
 			break;
 	if(o == nil){
-		n->next = fs->fidtab[h];
-		fs->fidtab[h] = n;
+		n->next = c->fidtab[h];
+		c->fidtab[h] = n;
 	}
-	unlock(&fs->fidtablk);
+	unlock(&c->fidtablk);
 
 	if(o != nil){
 		fprint(2, "fid in use: %d == %d\n", o->fid, new);
@@ -480,15 +483,15 @@
 }
 
 static void
-clunkfid(Fid *fid)
+clunkfid(Conn *c, Fid *fid)
 {
 	Fid *f, **pf;
 	u32int h;
 
-	lock(&fs->fidtablk);
+	lock(&c->fidtablk);
 	h = ihash(fid->fid) % Nfidtab;
-	pf = &fs->fidtab[h];
-	for(f = fs->fidtab[h]; f != nil; f = f->next){
+	pf = &c->fidtab[h];
+	for(f = c->fidtab[h]; f != nil; f = f->next){
 		if(f == fid){
 			assert(adec(&f->ref) != 0);
 			*pf = f->next;
@@ -497,37 +500,47 @@
 		pf = &f->next;
 	}
 	assert(f != nil);
-	unlock(&fs->fidtablk);
+	unlock(&c->fidtablk);
 }
 
-static Fmsg*
-readmsg(int fd, int max)
+static int
+readmsg(Conn *c, Fmsg **pm)
 {
 	char szbuf[4];
-	int sz;
+	int sz, n;
 	Fmsg *m;
 
-	if(readn(fd, szbuf, 4) != 4)
-		return nil;
+	n = readn(c->fd, szbuf, 4);
+	if(n <= 0){
+		*pm = nil;
+		return n;
+	}
+	if(n != 4){
+		werrstr("short read: %r");
+		return -1;
+	}
 	sz = GBIT32(szbuf);
-	if(sz > max)
-		return nil;
+	if(sz > c->iounit){
+		werrstr("message size too large");
+		return -1;
+	}
 	if((m = malloc(sizeof(Fmsg)+sz)) == nil)
-		return nil;
-	if(readn(fd, m->buf+4, sz-4) != sz-4){
+		return -1;
+	if(readn(c->fd, m->buf+4, sz-4) != sz-4){
 		werrstr("short read: %r");
 		free(m);
-		return nil;
+		return -1;
 	}
-	m->fd = fd;
+	m->conn = c;
 	m->sz = sz;
 	m->a = nil;
 	PBIT32(m->buf, sz);
-	return m;
+	*pm = m;
+	return 0;
 }
 
 static void
-fsversion(Fmsg *m, int *msz)
+fsversion(Fmsg *m)
 {
 	Fcall r;
 	char *p;
@@ -536,15 +549,17 @@
 	p = strchr(m->version, '.');
 	if(p != nil)
 		*p = '\0';
+	r.type = Rversion;
+	r.msize = Max9p;
 	if(strcmp(m->version, "9P2000") == 0){
-		if(m->msize < *msz)
-			*msz = m->msize;
-		r.type = Rversion;
-		r.msize = *msz;
+		if(m->msize < r.msize)
+			r.msize = m->msize;
 		r.version = "9P2000";
+		m->conn->versioned = 1;
+		m->conn->iounit = r.msize;
 	}else{
-		r.type = Rversion;
 		r.version = "unknown";
+		m->conn->versioned = 0;
 	}
 	respond(m, &r);
 }
@@ -584,7 +599,7 @@
 }
 
 static void
-fsauth(Fmsg *m, int iounit)
+fsauth(Fmsg *m)
 {
 	Dent *de;
 	Fcall r;
@@ -613,7 +628,7 @@
 	f.qpath = de->qid.path;
 	f.pqpath = de->qid.path;
 	f.mode = -1;
-	f.iounit = iounit;
+	f.iounit = m->conn->iounit;
 	f.dent = de;
 	f.uid = -1;
 	f.duid = -1;
@@ -620,7 +635,7 @@
 	f.dgid = -1;
 	f.dmode = 0600;
 	f.auth = authnew();
-	if(dupfid(m->afid, &f) == nil){
+	if(dupfid(m->conn, m->afid, &f) == nil){
 		rerror(m, Enomem);
 		return;
 	}
@@ -710,7 +725,7 @@
 }
 
 static void
-fsattach(Fmsg *m, int iounit)
+fsattach(Fmsg *m)
 {
 	char *e, *p, *n, dbuf[Kvmax], kvbuf[Kvmax];
 	Mount *mnt;
@@ -785,13 +800,13 @@
 	f.qpath = d.qid.path;
 	f.pqpath = d.qid.path;
 	f.mode = -1;
-	f.iounit = iounit;
+	f.iounit = m->conn->iounit;
 	f.dent = de;
 	f.uid = u->id;
 	f.duid = u->id;
 	f.dgid = d.gid;
 	f.dmode = d.mode;
-	if(dupfid(m->fid, &f) == nil){
+	if(dupfid(m->conn, m->fid, &f) == nil){
 		rerror(m, Enomem);
 		return;
 	}
@@ -801,7 +816,6 @@
 	r.type = Rattach;
 	r.qid = d.qid;
 	respond(m, &r);
-	return;
 }
 
 static char*
@@ -836,7 +850,7 @@
 	Key k;
 	int i;
 
-	if((o = getfid(m->fid)) == nil){
+	if((o = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -893,7 +907,7 @@
 	}
 	f = o;
 	if(m->fid != m->newfid && i == m->nwname){
-		if((f = dupfid(m->newfid, o)) == nil){
+		if((f = dupfid(m->conn, m->newfid, o)) == nil){
 			rerror(m, Enomem);
 			putfid(o);
 			return;
@@ -904,7 +918,7 @@
 		dent = getdent(up, &d);
 		if(dent == nil){
 			if(f != o)
-				clunkfid(f);
+				clunkfid(m->conn, f);
 			rerror(m, Enomem);
 			putfid(f);
 			return;
@@ -929,7 +943,7 @@
 	Kvp kv;
 	int n;
 
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -965,7 +979,7 @@
 	User *u;
 
 	rename = 0;
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1160,7 +1174,7 @@
 	Fcall r;
 	Fid *f;
 
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1173,7 +1187,7 @@
 	}
 	unlock(f);
 
-	clunkfid(f);
+	clunkfid(m->conn, f);
 	r.type = Rclunk;
 	respond(m, &r);
 	putfid(f);
@@ -1194,7 +1208,7 @@
 		rerror(m, Ename);
 		return;
 	}
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1266,7 +1280,7 @@
 	de = getdent(f->qpath, &d);
 	if(de == nil){
 		if(m->fid != m->newfid)
-			clunkfid(f);
+			clunkfid(m->conn, f);
 		rerror(m, Enomem);
 		putfid(f);
 		return;
@@ -1341,11 +1355,11 @@
 	Fid *f;
 	char *e;
 
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
-	clunkfid(f);
+	clunkfid(m->conn, f);
 
 	rlock(f->dent);
 	if((e = candelete(f)) != nil)
@@ -1390,7 +1404,7 @@
 	Msg mb;
 
 	mbits = mode2bits(m->mode);
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1596,7 +1610,7 @@
 	Fcall r;
 	Fid *f;
 
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1649,7 +1663,7 @@
 	Fcall r;
 	Fid *f;
 
-	if((f = getfid(m->fid)) == nil){
+	if((f = getfid(m->conn, m->fid)) == nil){
 		rerror(m, Efid);
 		return;
 	}
@@ -1730,38 +1744,46 @@
 }
 
 void
-runfs(int wid, void *pfd)
+runfs(int, void *pfd)
 {
-	int fd, msgmax, versioned;
+	Conn *c;
+	int fd;
 	char err[128];
 	Fcall r;
 	Fmsg *m;
 
 	fd = (uintptr)pfd;
-	msgmax = Max9p;
-	versioned = 0;
+	if((c = mallocz(sizeof(*c), 1)) == nil){
+		fshangup(fd, "malloc: %r");
+		return;
+	}
+	c->fd = fd;
+	c->iounit = Max9p;
+	lock(&fs->connlk);
+	c->next = fs->conns;
+	fs->conns = c;
+	unlock(&fs->connlk);
 	while(1){
-		if((m = readmsg(fd, msgmax)) == nil){
-			fshangup(fd, "truncated message: %r");
+		if(readmsg(c, &m) < 0){
+			fshangup(fd, "read message: %r");
 			return;
 		}
-		quiesce(wid);
+		if(m == nil)
+			break;
 		if(convM2S(m->buf, m->sz, m) == 0){
 			fshangup(fd, "invalid message: %r");
 			return;
 		}
-		if(m->type != Tversion && !versioned){
+		if(m->type != Tversion && !c->versioned){
 			fshangup(fd, "version required");
 			return;
 		}
-		versioned = 1;
 		dprint("← %F\n", &m->Fcall);
 		switch(m->type){
 		/* sync setup */
-		case Tversion:	fsversion(m, &msgmax);	break;
-		case Tauth:	fsauth(m, msgmax);	break;
+		case Tversion:	fsversion(m);	break;
+		case Tauth:	fsauth(m);	break;
 		case Tclunk:	fsclunk(m);		break;
-		case Tattach:	fsattach(m, msgmax);	break;
 
 		/* mutators */
 		case Tcreate:	chsend(fs->wrchan, m);	break;
@@ -1770,6 +1792,7 @@
 		case Tremove:	chsend(fs->wrchan, m);	break;
 
 		/* reads */
+		case Tattach:	chsend(fs->rdchan, m);	break;
 		case Tflush:	chsend(fs->rdchan, m);	break;
 		case Twalk:	chsend(fs->rdchan, m);	break;
 		case Tread:	chsend(fs->rdchan, m);	break;
@@ -1792,7 +1815,6 @@
 			respond(m, &r);
 			break;
 		}
-		quiesce(wid);
 	}
 }
 
@@ -1856,6 +1878,7 @@
 		quiesce(wid);
 		switch(m->type){
 		case Tflush:	rerror(m, Eimpl);	break;
+		case Tattach:	fsattach(m);	break;
 		case Twalk:	fswalk(m);	break;
 		case Tread:	fsread(m);	break;
 		case Tstat:	fsstat(m);	break;
--- a/main.c
+++ b/main.c
@@ -78,9 +78,34 @@
 }
 
 static void
+runannounce(int, void *arg)
+{
+	char *ann, adir[40], ldir[40];
+	int actl, lctl, fd;
+
+	ann = arg;
+	if((actl = announce(ann, adir)) < 0)
+		sysfatal("announce %s: %r", ann);
+	while(1){
+		if((lctl = listen(adir, ldir)) < 0){
+			fprint(2, "listen %s: %r", adir);
+			break;
+		}
+		fd = accept(lctl, ldir);
+		close(lctl);
+		if(fd < 0){
+			fprint(2, "accept %s: %r", ldir);
+			continue;
+		}
+		launch(runfs, -1, (void *)fd, "netio");
+	}
+	close(actl);
+}
+
+static void
 usage(void)
 {
-	fprint(2, "usage: %s [-rA] [-m mem] [-s srv] [-u usr] dev\n", argv0);
+	fprint(2, "usage: %s [-rA] [-m mem] [-s srv] [-u usr] [-a net]... dev\n", argv0);
 	exits("usage");
 }
 
@@ -87,10 +112,16 @@
 void
 main(int argc, char **argv)
 {
-	int i, srvfd, ctlfd;
-	char *s;
+	int i, srvfd, ctlfd, nann;
+	char *s, *ann[16];
 
+	nann = 0;
 	ARGBEGIN{
+	case 'a':
+		if(nann == nelem(ann))
+			sysfatal("too many announces");
+		ann[nann++] = EARGF(usage());
+		break;
 	case 'r':
 		ream = 1;
 		break;
@@ -166,7 +197,9 @@
 		launch(runread, fs->nquiesce++, nil, "readio");
 	for(i = 0; i < fs->nsyncers; i++)
 		launch(runsync, -1, fs->chsync[i], "syncio");
+	for(i = 0; i < nann; i++)
+		launch(runannounce, -1, ann[i], "announce");
 	if(srvfd != -1)
-		launch(runfs, fs->nquiesce++, (void*)srvfd, "srvio");
+		launch(runfs, -1, (void *)srvfd, "srvio");
 	exits(nil);
 }