summaryrefslogtreecommitdiff
path: root/sys/src/9/port
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-11-05 18:26:12 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2016-11-05 18:26:12 +0100
commitfa5bd7121846bae31ede5d6851a5091e9c16683a (patch)
treeb3a22709d938925a71535c98374f2b7ff0a28e12 /sys/src/9/port
parent5c1feb0ef0b795e5de71e956f9ccddcd5c4b7f21 (diff)
devmnt: avoid memory copies of I/O rpc buffer by using bwrite()
given that devmnt will almost always write into a pipe or a network connection, which supports te bwrite routine, we can avoid the memory copy that would have been done by devbwrite(). this also means the i/o buffer for writes will get freed sooner without having to wait for the 9p rpc to get a response, saving memory. theres one case where we have to keep the rpc arround and that is when we write to a cached file, as we want to update the cache with the data that was written, but the user buffer cannot be trusted to stay the same during the rpc.
Diffstat (limited to 'sys/src/9/port')
-rw-r--r--sys/src/9/port/devmnt.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c
index 96b627eb6..4f88e3832 100644
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -26,8 +26,7 @@ struct Mntrpc
Fcall reply; /* Incoming reply */
Mnt* m; /* Mount device during rpc */
Rendez* z; /* Place to hang out */
- uchar* rpc; /* I/O Data buffer */
- uint rpclen; /* len of buffer */
+ Block* w; /* copy of write rpc for cache */
Block* b; /* reply blocks */
Mntrpc* flushed; /* message this one flushes */
char done; /* Rpc completed */
@@ -68,6 +67,8 @@ static void mountmux(Mnt*, Mntrpc*);
static void mountrpc(Mnt*, Mntrpc*);
static int rpcattn(void*);
+#define cachedchan(c) (((c)->flag & CCACHE) != 0 && (c)->mcp != nil)
+
char Esbadstat[] = "invalid directory entry received from server";
char Enoversion[] = "version not established for mount channel";
@@ -659,7 +660,7 @@ mntcache(Mntrpc *r)
Chan *c;
c = r->c;
- if((c->flag & CCACHE) == 0 || c->mcp == nil)
+ if(!cachedchan(c))
return;
off = r->request.offset;
switch(r->reply.type){
@@ -676,9 +677,13 @@ mntcache(Mntrpc *r)
}
break;
case Rwrite:
- if(convM2S(r->rpc, r->rpclen, &r->request) == 0)
+ b = r->w;
+ if(convM2S(b->rp, BLEN(b), &r->request) == 0)
panic("convM2S");
- cwrite(c, (uchar*)r->request.data, r->request.count, off);
+ m = r->reply.count;
+ if(m > r->request.count)
+ m = r->request.count;
+ cwrite(c, (uchar*)r->request.data, m, off);
break;
}
}
@@ -700,7 +705,7 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off)
if(nreq > c->iounit)
nreq = c->iounit;
- if(type == Tread && (c->flag&CCACHE) != 0) {
+ if(type == Tread && cachedchan(c)) {
nr = cread(c, (uchar*)uba, nreq, off);
if(nr > 0) {
nreq = nr;
@@ -992,6 +997,7 @@ mountrpc(Mnt *m, Mntrpc *r)
static void
mountio(Mnt *m, Mntrpc *r)
{
+ Block *b;
int n;
while(waserror()) {
@@ -1021,23 +1027,22 @@ mountio(Mnt *m, Mntrpc *r)
/* Transmit a file system rpc */
n = sizeS2M(&r->request);
- if(n > r->rpclen) {
- free(r->rpc);
- r->rpc = mallocz(((uint)n+127) & ~127, 0);
- if(r->rpc == nil) {
- r->rpclen = 0;
- exhausted("mount rpc buffer");
- }
- r->rpclen = msize(r->rpc);
+ b = allocb(n);
+ if(waserror()){
+ freeb(b);
+ nexterror();
}
- n = convS2M(&r->request, r->rpc, r->rpclen);
+ n = convS2M(&r->request, b->wp, n);
if(n <= 0 || n > m->msize) {
print("mountio: proc %s %lud: convS2M returned %d for tag %d fid %d T%d\n",
up->text, up->pid, n, r->request.tag, r->request.fid, r->request.type);
error(Emountrpc);
}
- if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n)
- error(Emountrpc);
+ b->wp += n;
+ if(r->request.type == Twrite && cachedchan(r->c))
+ r->w = copyblock(b, n);
+ poperror();
+ devtab[m->c->type]->bwrite(m->c, b, 0);
/* Gate readers onto the mount point one at a time */
for(;;) {
@@ -1288,8 +1293,6 @@ mntralloc(Chan *c)
new = malloc(sizeof(Mntrpc));
if(new == nil)
exhausted("mount rpc header");
- new->rpc = nil;
- new->rpclen = 0;
lock(&mntalloc);
new->request.tag = alloctag();
} else {
@@ -1308,12 +1311,14 @@ mntralloc(Chan *c)
new->done = 0;
new->flushed = nil;
new->b = nil;
+ new->w = nil;
return new;
}
static void
mntfree(Mntrpc *r)
{
+ freeb(r->w);
freeblist(r->b);
lock(&mntalloc);
mntalloc.nrpcused--;
@@ -1326,7 +1331,6 @@ mntfree(Mntrpc *r)
}
freetag(r->request.tag);
unlock(&mntalloc);
- free(r->rpc);
free(r);
}