read_exactly_n()
[akaros.git] / kern / drivers / dev / mnt.c
index 14bea93..4a92f03 100644 (file)
@@ -506,7 +506,7 @@ static int mntstat(struct chan *c, uint8_t * dp, int n)
        } else {
                n = r->reply.nstat;
                memmove(dp, r->reply.stat, n);
-               validstat(dp, n);
+               validstat(dp, n, 0);
                mntdirfix(dp, c);
        }
        poperror();
@@ -696,7 +696,7 @@ static long mntread(struct chan *c, void *buf, long n, int64_t off)
                        if (p + dirlen > e){
                                break;
                        }
-                       validstat(p, dirlen);
+                       validstat(p, dirlen, 0);
                        mntdirfix(p, c);
                        numdirent += dirlen;
                }
@@ -823,14 +823,13 @@ void mountio(struct mnt *m, struct mntrpc *r)
        while (waserror()) {
                if (m->rip == current)
                        mntgate(m);
-               if (!strcmp(current_errstr(), "syscall aborted")) {
-                       /* not sure what devmnt wants us to do here.  bail on aborted
-                        * syscall?  keep looping forever? (probably not) */
-                       printk("[kernel] mountio had aborted syscall");
-                       mntflushfree(m, r);
-                       nexterror();
-               }
-               if (strcmp(current_errstr(), Eintr) != 0) {
+               /* Syscall aborts are like Plan 9 Eintr.  For those, we need to change
+                * the old request to a flsh (mntflushalloc) and try again.  We'll
+                * always try to flush, and you can't get out until the flush either
+                * succeeds or errors out with a non-abort/Eintr error. */
+               if (strcmp(current_errstr(), "syscall aborted") &&
+                   strcmp(current_errstr(), Eintr)) {
+                       /* all other errors (not abort or Eintr) */
                        mntflushfree(m, r);
                        nexterror();
                }
@@ -944,6 +943,8 @@ int mntrpcread(struct mnt *m, struct mntrpc *r)
        *l = NULL;
        do {
                b = qremove(m->q);
+               /* TODO: have better block helpers for this and the memmove below */
+               b = linearizeblock(b);
                if (hlen > 0) {
                        b->rp += hlen;
                        len -= hlen;