Jump stacks before unlocking semaphores
[akaros.git] / kern / drivers / dev / srv.c
index de72388..ba4e144 100644 (file)
 #include <ip.h>
 #include <sys/queue.h>
 
+struct dev srvdevtab;
+
+static char *devname(void)
+{
+       return srvdevtab.name;
+}
+
 #define Qtopdir                        1
 #define Qsrvfile               2
 
@@ -93,7 +100,7 @@ static int srvgen(struct chan *c, char *name, struct dirtab *tab,
        if (s == DEVDOTDOT) {
                /* changing whatever c->aux was to be topdir */
                mkqid(&q, Qtopdir, 0, QTDIR);
-               devdir(c, q, "#s", 0, eve, 0555, dp);
+               devdir(c, q, devname(), 0, eve, 0555, dp);
                return 1;
        }
        spin_lock(&srvlock);
@@ -111,7 +118,7 @@ static int srvgen(struct chan *c, char *name, struct dirtab *tab,
        c->aux = next;  /* uncounted ref */
        mkqid(&q, Qsrvfile, 0, QTFILE);
        /* once we release the lock, next could disappear, including next->name */
-       strncpy(get_cur_genbuf(), next->name, GENBUF_SZ);
+       strlcpy(get_cur_genbuf(), next->name, GENBUF_SZ);
        devdir(c, q, get_cur_genbuf(), 1 /* length */ , next->user, next->perm, dp);
        spin_unlock(&srvlock);
        return 1;
@@ -119,7 +126,7 @@ static int srvgen(struct chan *c, char *name, struct dirtab *tab,
 
 static void __srvinit(void)
 {
-       top_dir = kzmalloc(sizeof(struct srvfile), KMALLOC_WAIT);
+       top_dir = kzmalloc(sizeof(struct srvfile), MEM_WAIT);
        /* kstrdup, just in case we free this later */
        kstrdup(&top_dir->name, "srv");
        kstrdup(&top_dir->user, current ? current->user : "eve");
@@ -138,7 +145,7 @@ static struct chan *srvattach(char *spec)
 {
        /* the inferno attach was pretty complicated, but
         * we're not sure that complexity is needed. */
-       struct chan *c = devattach('s', spec);
+       struct chan *c = devattach(devname(), spec);
        mkqid(&c->qid, Qtopdir, 0, QTDIR);
        /* c->aux is an uncounted ref */
        c->aux = top_dir;
@@ -182,8 +189,8 @@ static struct chan *srvopen(struct chan *c, int omode)
        struct srvfile *srv;
        openmode(omode);        /* used as an error checker in plan9, does little now */
        if (c->qid.type & QTDIR) {
-               if (!IS_RDONLY(omode))
-                       error(Eisdir);
+               if (omode & O_WRITE)
+                       error(EISDIR, ERROR_FIXME);
                c->mode = openmode(omode);
                c->flag |= COPEN;
                c->offset = 0;
@@ -191,7 +198,7 @@ static struct chan *srvopen(struct chan *c, int omode)
        }
        srv = c->aux;
        if (!grab_ref(srv))
-               error("Unable to open srv file, concurrent removal");
+               error(EFAIL, "Unable to open srv file, concurrent removal");
        if (waserror()) {
                kref_put(&srv->ref);
                nexterror();
@@ -201,16 +208,16 @@ static struct chan *srvopen(struct chan *c, int omode)
 #if 0
        if (omode & ORCLOSE) {
                if (strcmp(srv->user, up->env->user) != 0)
-                       error(Eperm);
+                       error(EPERM, ERROR_FIXME);
                else
                        srv->flags |= SORCLOSE;
        }
 #endif
        if ((srv->perm & DMEXCL) && atomic_read(&srv->opens))
-               error(Einuse);
+               error(EBUSY, ERROR_FIXME);
        /* srv->chan is write-once, so we don't need to sync. */
        if (!srv->chan)
-               error("srv file has no chan yet");
+               error(EFAIL, "srv file has no chan yet");
        /* this is more than just the ref - 1, since there will be refs in flight
         * as gens work their way through the list */
        atomic_inc(&srv->opens);
@@ -226,7 +233,7 @@ static struct chan *srvopen(struct chan *c, int omode)
 static void srvcreate(struct chan *c, char *name, int omode, uint32_t perm)
 {
        struct srvfile *srv;
-       srv = kzmalloc(sizeof(struct srvfile), KMALLOC_WAIT);
+       srv = kzmalloc(sizeof(struct srvfile), MEM_WAIT);
        kstrdup(&srv->name, name);
        kstrdup(&srv->user, current ? current->user : "eve");
        srv->perm = 0770;       /* TODO need some security thoughts */
@@ -244,7 +251,7 @@ static void srvcreate(struct chan *c, char *name, int omode, uint32_t perm)
 
 static int srvwstat(struct chan *c, uint8_t * dp, int n)
 {
-       error("srvwstat not supported yet");
+       error(ENOSYS, ERROR_FIXME);
        return -1;
 }
 
@@ -290,23 +297,22 @@ static long srvwrite(struct chan *c, void *va, long count, int64_t offset)
        int fd;
 
        if (c->qid.type & QTDIR)
-               error(Eperm);
+               error(EPERM, ERROR_FIXME);
        srv = c->aux;
        if (!grab_ref(srv))
-               error("Unable to write srv file, concurrent removal");
+               error(EFAIL, "Unable to write srv file, concurrent removal");
        if (waserror()) {
                kref_put(&srv->ref);
                nexterror();
        }
        if (srv->chan)
-               error("srv file already has a stored chan!");
+               error(EFAIL, "srv file already has a stored chan!");
        if (waserror()) {
                kfree(kbuf);
                nexterror();
        }
-       kbuf = kmalloc(count + 1, KMALLOC_WAIT);
-       strncpy(kbuf, va, count);
-       kbuf[count] = 0;
+       kbuf = kmalloc(count + 1, MEM_WAIT);
+       strlcpy(kbuf, va, count + 1);
        fd = strtoul(kbuf, 0, 10);
        /* the magic of srv: srv stores the chan corresponding to the fd.  -1 for
         * mode, so we just get the chan with no checks (RDWR would work too). */
@@ -314,7 +320,7 @@ static long srvwrite(struct chan *c, void *va, long count, int64_t offset)
        /* fdtochan already increffed for us */
        if (!__sync_bool_compare_and_swap(&srv->chan, 0, new_chan)) {
                cclose(new_chan);
-               error("srv file already has a stored chan!");
+               error(EFAIL, "srv file already has a stored chan!");
        }
        poperror();
        kfree(kbuf);
@@ -324,24 +330,23 @@ static long srvwrite(struct chan *c, void *va, long count, int64_t offset)
 }
 
 struct dev srvdevtab __devtab = {
-       's',
-       "srv",
+       .name = "srv",
 
-       devreset,
-       srvinit,
-       devshutdown,
-       srvattach,
-       srvwalk,
-       srvstat,
-       srvopen,
-       srvcreate,
-       srvclose,
-       srvread,
-       devbread,
-       srvwrite,
-       devbwrite,
-       srvremove,
-       srvwstat,
-       devpower,
-       devchaninfo,
+       .reset = devreset,
+       .init = srvinit,
+       .shutdown = devshutdown,
+       .attach = srvattach,
+       .walk = srvwalk,
+       .stat = srvstat,
+       .open = srvopen,
+       .create = srvcreate,
+       .close = srvclose,
+       .read = srvread,
+       .bread = devbread,
+       .write = srvwrite,
+       .bwrite = devbwrite,
+       .remove = srvremove,
+       .wstat = srvwstat,
+       .power = devpower,
+       .chaninfo = devchaninfo,
 };