git: 9front

Download patch

ref: 882ec4ba3d42f15e630119e1f43e5400123539b5
parent: 2dd476e3176b0f9da75c1be5824bfb25e0965ab8
parent: 69481a8a50fc689c00b82fe96640856b6a83659b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 29 12:23:57 EST 2025

merge

--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -38,6 +38,9 @@
 	TAGSHIFT = 5,
 	TAGMASK = (1<<TAGSHIFT)-1,
 	NMASK = (64*1024)>>TAGSHIFT,
+
+	/* offset to data in Twrite request */
+	Twritehdr = BIT32SZ+BIT8SZ+BIT16SZ+BIT32SZ+BIT64SZ+BIT32SZ,
 };
 
 static struct Mntalloc
@@ -666,45 +669,105 @@
 mntcache(Mntrpc *r)
 {
 	ulong n, m;
-	vlong off;
+	vlong o;
 	Block *b;
-	Chan *c;
 
-	c = r->c;
-	if(!cachedchan(c))
-		return;
-	off = r->request.offset;
+	n = r->request.count;
+	o = r->request.offset;
+	if(r->reply.count < n)
+		n = r->reply.count;
 	switch(r->reply.type){
 	case Rread:
-		m = r->reply.count;
-		if(m > r->request.count)
-			m = r->request.count;
-		for(b = r->b; m > 0 && b != nil; m -= n, b = b->next) {
-			n = BLEN(b);
-			if(m < n)
-				n = m;
-			cupdate(c, b->rp, n, off);
-			off += n;
+		for(b = r->b; n > 0 && b != nil; n -= m, b = b->next) {
+			m = BLEN(b);
+			if(n < m)
+				m = n;
+			cupdate(r->c, b->rp, m, o);
+			o += m;
 		}
 		break;
 	case Rwrite:
-		b = r->w;
-		if(convM2S(b->rp, BLEN(b), &r->request) == 0)
-			panic("convM2S");
-		m = r->reply.count;
-		if(m > r->request.count)
-			m = r->request.count;
-		cwrite(c, (uchar*)r->request.data, m, off);
+		if((b = r->w) != nil)	/* saved Twrite request */
+			cwrite(r->c, b->rp + Twritehdr, n, o);
 		break;
 	}
 }
 
+static Block*
+mntbread(Chan *c, long n, ulong off)
+{
+	Mnt *m;
+ 	Mntrpc *r;
+	Block *b;
+
+	if(n > c->iounit || cachedchan(c))
+		return devbread(c, n, off);
+
+	m = mntchk(c);
+	r = mntralloc(c);
+	if(waserror()) {
+		mntfree(r);
+		nexterror();
+	}
+	r->request.type = Tread;
+	r->request.fid = c->fid;
+	r->request.offset = off;
+	r->request.count = n;
+	mountrpc(m, r);
+	b = concatblock(r->b);
+	r->b = nil;
+	if(r->reply.count < n)
+		n = r->reply.count;
+	if(BLEN(b) > n)
+		b->wp = b->rp + n;
+	mntfree(r);
+	poperror();
+
+	return b;
+}
+
 static long
+mntbwrite(Chan *c, Block *b, ulong off)
+{
+	Mnt *m;
+ 	Mntrpc *r;
+	long n;
+
+	n = BLEN(b);
+	if(n > c->iounit || cachedchan(c))
+		return devbwrite(c, b, off);
+
+	m = mntchk(c);
+	r = mntralloc(c);
+	if(waserror()) {
+		mntfree(r);
+		nexterror();
+	}
+	r->request.type = Twrite;
+	r->request.fid = c->fid;
+	r->request.offset = off;
+	r->request.count = n;
+	/* prepend Twrite header */
+	b = padblock(b, Twritehdr);
+	r->request.data = (char*)b->rp + Twritehdr;
+	r->w = b;
+	if(convS2M(&r->request, b->rp, BLEN(b)) <= 0)
+		error(Emsize);
+	mountrpc(m, r);
+	if(r->reply.count < n)
+		n = r->reply.count;
+	mntfree(r);
+	poperror();
+
+	return n;
+}
+
+static long
 mntrdwr(int type, Chan *c, void *buf, long n, vlong off)
 {
 	Mnt *m;
  	Mntrpc *r;
-	char *uba;
+	uchar *uba;
 	ulong cnt, nr, nreq;
 
 	m = mntchk(c);
@@ -717,7 +780,7 @@
 			nreq = c->iounit;
 
 		if(type == Tread && cachedchan(c)) {
-			nr = cread(c, (uchar*)uba, nreq, off);
+			nr = cread(c, uba, nreq, off);
 			if(nr > 0) {
 				nreq = nr;
 				goto Next;
@@ -732,15 +795,16 @@
 		r->request.type = type;
 		r->request.fid = c->fid;
 		r->request.offset = off;
-		r->request.data = uba;
+		r->request.data = (char*)uba;
 		r->request.count = nreq;
 		mountrpc(m, r);
-		mntcache(r);
+		if(cachedchan(c))
+			mntcache(r);
 		nr = r->reply.count;
 		if(nr > nreq)
 			nr = nreq;
 		if(type == Tread)
-			nr = readblist(r->b, (uchar*)uba, nr, 0);
+			nr = readblist(r->b, uba, nr, 0);
 		mntfree(r);
 		poperror();
 
@@ -1037,19 +1101,27 @@
 	unlock(m);
 
 	/* Transmit a file system rpc */
-	n = sizeS2M(&r->request);
-	b = allocb(n);
-	if(waserror()){
-		freeb(b);
-		nexterror();
+	if((b = r->w) != nil) {
+		/* Already converted by mntbwrite() */
+		r->w = nil;
+	} else {
+		n = sizeS2M(&r->request);
+		b = allocb(n);
+		if(waserror()){
+			freeb(b);
+			nexterror();
+		}
+		n = convS2M(&r->request, b->wp, n);
+		if(n <= 0 || n > m->msize)
+			error(Emsize);
+		b->wp += n;
+
+		/* Save request for mntcache() */
+		if(r->request.type == Twrite && cachedchan(r->c))
+			r->w = copyblock(b, n);
+
+		poperror();
 	}
-	n = convS2M(&r->request, b->wp, n);
-	if(n <= 0 || n > m->msize)
-		error(Emsize);
-	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 */
@@ -1417,9 +1489,9 @@
 	mntcreate,
 	mntclose,
 	mntread,
-	devbread,
+	mntbread,
 	mntwrite,
-	devbwrite,
+	mntbwrite,
 	mntremove,
 	mntwstat,
 };
--