summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/port/devmnt.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c
index 2b6610afc..91d6ad2f9 100644
--- a/sys/src/9/port/devmnt.c
+++ b/sys/src/9/port/devmnt.c
@@ -634,32 +634,11 @@ static long
mntread(Chan *c, void *buf, long n, vlong off)
{
uchar *p, *e;
- int nc, cache, isdir, dirlen;
-
- isdir = 0;
- cache = c->flag & CCACHE;
- if(c->qid.type & QTDIR) {
- cache = 0;
- isdir = 1;
- }
+ int dirlen;
p = buf;
- if(cache) {
- nc = cread(c, buf, n, off);
- if(nc > 0) {
- n -= nc;
- if(n == 0)
- return nc;
- p += nc;
- off += nc;
- }
- n = mntrdwr(Tread, c, p, n, off);
- cupdate(c, p, n, off);
- return n + nc;
- }
-
- n = mntrdwr(Tread, c, buf, n, off);
- if(isdir) {
+ n = mntrdwr(Tread, c, p, n, off);
+ if(c->qid.type & QTDIR) {
for(e = &p[n]; p+BIT16SZ < e; p += dirlen){
dirlen = BIT16SZ+GBIT16(p);
if(p+dirlen > e)
@@ -695,6 +674,14 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off)
if(c->qid.type & QTDIR)
cache = 0;
for(;;) {
+ if(cache && type == Tread) {
+ nr = cread(c, (uchar*)uba, n, off);
+ if(nr > 0) {
+ nreq = nr;
+ goto Next;
+ }
+ }
+
r = mntralloc(c, m->msize);
if(waserror()) {
mntfree(r);
@@ -714,13 +701,39 @@ mntrdwr(int type, Chan *c, void *buf, long n, vlong off)
if(nr > nreq)
nr = nreq;
+ if(cache) {
+ /*
+ * note that we cannot update the cache from uba as
+ * the user could change its contents from another
+ * process before the data gets copied to the cached.
+ */
+ if(type == Tread) {
+ ulong nc, nn;
+ Block *b;
+
+ nc = 0;
+ for(b = r->b; b != nil; b = b->next) {
+ nn = BLEN(b);
+ if(nc+nn > nr)
+ nn = nr - nc;
+ cupdate(c, b->rp, nn, off + nc);
+ nc += nn;
+ if(nc >= nr)
+ break;
+ }
+ } else {
+ if(convM2S(r->rpc, r->rpclen, &r->request) == 0)
+ panic("convM2S");
+ cwrite(c, (uchar*)r->request.data, nr, off);
+ }
+ }
+
if(type == Tread)
r->b = bl2mem((uchar*)uba, r->b, nr);
- else if(cache)
- cwrite(c, (uchar*)uba, nr, off);
-
- poperror();
mntfree(r);
+ poperror();
+
+ Next:
off += nr;
uba += nr;
cnt += nr;
@@ -807,7 +820,6 @@ mountio(Mnt *m, Mntrpc *r)
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);