summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/9p.h1
-rw-r--r--sys/src/lib9p/srv.c46
2 files changed, 39 insertions, 8 deletions
diff --git a/sys/include/9p.h b/sys/include/9p.h
index a8fb1fdc1..27bec9b9a 100644
--- a/sys/include/9p.h
+++ b/sys/include/9p.h
@@ -234,6 +234,7 @@ struct Srv {
QLock slock;
Ref sref;
+ Ref rref;
};
void srv(Srv*);
diff --git a/sys/src/lib9p/srv.c b/sys/src/lib9p/srv.c
index 33791cb18..12b1d7fe5 100644
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -163,23 +163,34 @@ walkandclone(Req *r, char *(*walk1)(Fid*, char*, void*), char *(*clone)(Fid*, Fi
}
static void
-sversion(Srv*, Req *r)
+sversion(Srv *srv, Req *r)
{
+ if(srv->rref.ref != 2){
+ respond(r, Ebotch);
+ return;
+ }
if(strncmp(r->ifcall.version, "9P", 2) != 0){
r->ofcall.version = "unknown";
respond(r, nil);
return;
}
-
r->ofcall.version = "9P2000";
- r->ofcall.msize = r->ifcall.msize;
+ if(r->ifcall.msize < 256){
+ respond(r, "version: message size too small");
+ return;
+ }
+ if(r->ifcall.msize < 1024*1024)
+ r->ofcall.msize = r->ifcall.msize;
+ else
+ r->ofcall.msize = 1024*1024;
respond(r, nil);
}
+
static void
rversion(Req *r, char *error)
{
- assert(error == nil);
- changemsize(r->srv, r->ofcall.msize);
+ if(error == nil)
+ changemsize(r->srv, r->ofcall.msize);
}
static void
@@ -682,14 +693,18 @@ rwstat(Req*, char*)
{
}
+static void srvclose(Srv *);
+
static void
srvwork(void *v)
{
Srv *srv = v;
Req *r;
+ incref(&srv->rref);
incref(&srv->sref);
while(r = getreq(srv)){
+ incref(&srv->rref);
if(r->error){
respond(r, r->error);
continue;
@@ -715,9 +730,19 @@ srvwork(void *v)
}
qunlock(&srv->slock);
}
- if(decref(&srv->sref))
+ decref(&srv->sref);
+ srvclose(srv);
+}
+
+static void
+srvclose(Srv *srv)
+{
+ if(decref(&srv->rref))
return;
+ if(chatty9p)
+ fprint(2, "srvclose\n");
+
free(srv->rbuf);
srv->rbuf = nil;
free(srv->wbuf);
@@ -753,6 +778,9 @@ srv(Srv *srv)
fmtinstall('D', dirfmt);
fmtinstall('F', fcallfmt);
+ srv->sref.ref = 0;
+ srv->rref.ref = 0;
+
if(srv->fpool == nil)
srv->fpool = allocfidpool(srv->destroyfid);
if(srv->rpool == nil)
@@ -819,7 +847,7 @@ if(chatty9p)
qlock(&srv->wlock);
n = convS2M(&r->ofcall, srv->wbuf, srv->msize);
if(n <= 0){
- fprint(2, "n = %d %F\n", n, &r->ofcall);
+ fprint(2, "msize = %d n = %d %F\n", srv->msize, n, &r->ofcall);
abort();
}
assert(n > 2);
@@ -827,7 +855,7 @@ if(chatty9p)
closereq(removereq(r->pool, r->ifcall.tag));
m = write(srv->outfd, srv->wbuf, n);
if(m != n)
- sysfatal("lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd);
+ fprint(2, "lib9p srv: write %d returned %d on fd %d: %r", n, m, srv->outfd);
qunlock(&srv->wlock);
qlock(&r->lk); /* no one will add flushes now */
@@ -844,6 +872,8 @@ if(chatty9p)
closereq(r);
else
free(r);
+
+ srvclose(srv);
}
void