read_exactly_n()
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 7 Jan 2015 16:00:23 +0000 (11:00 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 7 Jan 2015 16:00:23 +0000 (11:00 -0500)
Yanked from nix.c.  We aren't using it yet, but looks useful in the future.
Note my comment about clobbering underlying errors with our Eshort.

kern/drivers/dev/nix.c
kern/include/ns.h
kern/src/ns/sysfile.c

index 0aa911c..a23758b 100644 (file)
@@ -84,26 +84,6 @@ static inline int QID(int index, int type)
        return ((index << INDEX_SHIFT) | type);
 }
 
-/* we'll need this somewhere more generic. */
-static void readn(struct chan *c, void *vp, long n)
-{
-       char *p;
-       long nn;
-       int total = 0, want = n;
-
-       p = vp;
-       while (n > 0) {
-               nn = devtab[c->type].read(c, p, n, c->offset);
-               printk("readn: Got %d@%lld\n", nn, c->offset);
-               if (nn == 0)
-                       error("%s: wanted %d, got %d", Eshort, want, total);
-               c->offset += nn;
-               p += nn;
-               n -= nn;
-               total += nn;
-       }
-}
-
 /* not called yet.  -- we have to unlink the nix */
 static void nix_release(struct kref *kref)
 {
index 6467ee5..17b7a49 100644 (file)
@@ -1001,6 +1001,7 @@ int sysmount(int fd, int afd, char *old, int flags, char *spec);
 int sysunmount(char *old, char *new);
 int sysopen(char *path, int mode);
 long unionread(struct chan *c, void *va, long n);
+void read_exactly_n(struct chan *c, void *vp, long n);
 long sysread(int fd, void *va, long n);
 long syspread(int fd, void *va, long n, int64_t off);
 int sysremove(char *path);
index 23209f0..74aa619 100644 (file)
@@ -891,6 +891,31 @@ out:
        return n;
 }
 
+/* Reads exactly n bytes from chan c, starting at its offset.  Can block, but if
+ * we get 0 back too soon (EOF or error), then we'll error out with Eshort.
+ * That might need a little work - if there was a previous error, then we
+ * clobbered it and only know Eshort but not why we completed early. */
+void read_exactly_n(struct chan *c, void *vp, long n)
+{
+       char *p;
+       long nn;
+       int total = 0, want = n;
+
+       p = vp;
+       while (n > 0) {
+               nn = devtab[c->type].read(c, p, n, c->offset);
+               printd("readn: Got %d@%lld\n", nn, c->offset);
+               if (nn == 0)
+                       error("%s: wanted %d, got %d", Eshort, want, total);
+               spin_lock(&c->lock);
+               c->offset += nn;
+               spin_unlock(&c->lock);
+               p += nn;
+               n -= nn;
+               total += nn;
+       }
+}
+
 long sysread(int fd, void *va, long n)
 {
        return rread(fd, va, n, NULL);