rread: if you hit eof on a directory, mark the chan as being at eof
authorRonald G. Minnich <rminnich@google.com>
Tue, 8 Jul 2014 14:16:12 +0000 (07:16 -0700)
committerRonald G. Minnich <rminnich@google.com>
Tue, 8 Jul 2014 14:49:49 +0000 (07:49 -0700)
This saves a 0-byte read for each directory entry.
Sadly, it does not save the ensuing stat for each entry, which is very foolish.
Failure of Vision on the part of glibc.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/include/ns.h
kern/src/ns/chan.c
kern/src/ns/sysfile.c

index 36dec8f..fdfba12 100644 (file)
@@ -386,7 +386,8 @@ struct chan {
        struct chan *mchan;                     /* channel to mounted server */
        struct qid mqid;                        /* qid of root of mount point */
        struct cname *name;
-       /* hack for reads to try to get them right. */
+       /* hack for dir reads to try to get them right. */
+       int ateof;
        void *buf;
        int bufused;
 };
index 131ece5..d55919b 100644 (file)
@@ -263,6 +263,7 @@ void chanfree(struct chan *c)
                kfree(c->buf);
        c->buf = NULL;
        c->bufused = 0;
+       c->ateof = 0;
 
        spin_lock(&(&chanalloc)->lock);
        c->next = chanalloc.free;
index f28968f..fccae2d 100644 (file)
@@ -799,7 +799,13 @@ static long rread(int fd, void *va, long n, int64_t * offp)
                        }
                        unionrewind(c);
                }
-               n = devtab[c->type].read(c, va, n, off);
+               if (! c->ateof) {
+                       n = devtab[c->type].read(c, va, n, off);
+                       if (n == 0 && dir)
+                               c->ateof = 1;
+               } else {
+                       n = 0;
+               }
                spin_lock(&c->lock);
                c->offset += n;
                spin_unlock(&c->lock);