Fix devtab assumption with c->type
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 21 Jan 2014 00:24:23 +0000 (16:24 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 21 Jan 2014 00:33:33 +0000 (16:33 -0800)
Inferno assumed devroot was the first dev in devtab.  They needed
certain chans (ones not associated with a dev yet) to not execute a
dev's close method.  rootclose() was a noop, so they managed.

kern/drivers/dev/dev.c
kern/include/ns.h
kern/src/ns/chan.c

index e6d8273..07766ea 100644 (file)
@@ -164,7 +164,9 @@ devwalk(struct chan *c,
        }
        if(nc == NULL){
                nc = devclone(c);
-               nc->type = 0;   /* device doesn't know about this channel yet */
+               /* inferno was setting this to 0, assuming it was devroot.  lining up
+                * with chanrelease and newchan */
+               nc->type = -1;  /* device doesn't know about this channel yet */
                alloc = 1;
        }
        wq->clone = nc;
index fff144d..8b83f34 100644 (file)
@@ -354,7 +354,7 @@ struct chan
        struct chan*    next;                   /* allocation */
        struct chan*    link;
        int64_t offset;                 /* in file */
-       uint16_t        type;
+       int     type;
        uint32_t        dev;
        uint16_t        mode;                   /* read/write */
        uint16_t        flag;
index f7d28d2..aa1e4c7 100644 (file)
@@ -129,7 +129,10 @@ static void chan_release(struct kref *kref)
        /* this style discards the error from close().  picture it as
         * if (waserror()) { } else { close(); } chanfree_no_matter_what();  */
        if (!waserror()) {
-               devtab[c->type]->close(c);
+               printd("releasing chan %p, type %d\n", c, c->type);
+               /* -1 means there is no dev yet.  wants a noop for close() */
+               if (c->type != -1)
+                       devtab[c->type].close(c);
        }
        /* need to poperror regardless of whether we error'd or not */
        poperror();
@@ -159,9 +162,9 @@ newchan(void)
                qlock_init(&c->umqlock);
        }
 
-       /* if you get an error before associating with a dev,
-          close calls rootclose, a nop */
-       c->type = 0;
+       /* if you get an error before associating with a dev, cclose skips calling
+        * the dev's close */
+       c->type = -1;
        c->flag = 0;
        kref_init(&c->ref, chan_release, 1);
        c->dev = 0;