Dev zeros the dir path before genning
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 Nov 2013 20:58:25 +0000 (12:58 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 29 Jan 2014 19:03:26 +0000 (11:03 -0800)
It's useful for devices to be able to get information about the last run
through their gen function when run in a tight loop.  There's no good
way to do pass an arbitrary value back, but we can use the dir to
communicate the result of the previous run.  So long as we handle the
initial case.

Gens communicate via the dir, and dir->qid.path is the last path used in
the previous run.  This works if we can bootstrap it, and passing in
gibberish (on the stack) or ancient versions of dir will mess things up.
So now any caller of a gen in a loop will make sure dir's path is 0.

Also, it's not sufficient to just check for {s,i} == 0 to detect the
"first run" of a gen.  Sometimes (devdirread()), a device will be asked
to gen starting at a higher value of its iterator.  By zeroing dir's
path, a gen can tell if it is in the middle or not of a series of runs.

kern/drivers/dev/dev.c

index 286080f..d3b6775 100644 (file)
@@ -171,6 +171,7 @@ devwalk(struct chan *c,
        }
        wq->clone = nc;
 
+       dir.qid.path = 0;
        for(j=0; j<nname; j++){
                if(!(nc->qid.type&QTDIR)){
                        if(j==0)
@@ -198,6 +199,7 @@ devwalk(struct chan *c,
                 */
                if(gen==devgen && nc->qid.path!=tab[0].qid.path)
                        goto Notfound;
+               dir.qid.path = 0;
                for(i=0;; i++) {
                        switch((*gen)(nc, n, tab, ntab, i, &dir)){
                        case -1:
@@ -248,6 +250,7 @@ devstat(struct chan *c, uint8_t *db, int n,
        struct dir dir;
        char *p, *elem;
 
+       dir.qid.path = 0;
        for(i=0;; i++)
                switch((*gen)(c, NULL, tab, ntab, i, &dir)){
                case -1:
@@ -298,6 +301,7 @@ devdirread(struct chan *c, char *d, long n,
         */
        struct dir dir[4];
 
+       dir[0].qid.path = 0;
        for(m=0; m<n; c->dri++) {
                switch((*gen)(c, NULL, tab, ntab, c->dri, &dir[0])){
                case -1:
@@ -353,6 +357,7 @@ devopen(struct chan *c, int omode, struct dirtab *tab, int ntab, Devgen *gen)
        int i;
        struct dir dir;
 
+       dir.qid.path = 0;
        for(i=0;; i++) {
                switch((*gen)(c, NULL, tab, ntab, i, &dir)){
                case -1: