Encapsulate block metadata better
[akaros.git] / kern / src / ns / dev.c
index c651c1a..7012b5a 100644 (file)
 #include <cpio.h>
 #include <pmap.h>
 #include <smp.h>
-#include <ip.h>
+#include <net/ip.h>
 
 extern uint32_t kerndate;
-extern char *eve;
+extern struct username eve;
 
 void mkqid(struct qid *q, int64_t path, uint32_t vers, int type)
 {
@@ -80,7 +80,7 @@ devdir(struct chan *c, struct qid qid, char *n,
        db->mtime = kerndate;
        db->length = length;
        db->uid = user;
-       db->gid = eve;
+       db->gid = eve.name;
        db->muid = user;
 }
 
@@ -96,7 +96,15 @@ devdir(struct chan *c, struct qid qid, char *n,
  *
  * TODO(cross): Document devgen and clean this mess up. Devgen should probably
  * be removed and replaced with a smarter data structure.
- */
+ *
+ * Keep in mind that the expected behavior of gen functions that interoperate
+ * with dev functions (e.g. devdirread()) is that files are directly genned, but
+ * not directories.  Directories will fail to gen, and devstat() just makes
+ * something up.  See also:
+ * https://github.com/brho/plan9/blob/89d43d2262ad43eb4b26c2a8d6a27cfeddb33828/nix/sys/src/nix/port/dev.c#L74
+ *
+ * The comment about genning a file's siblings needs a grain of salt too.  Look
+ * through ipgen().  I think it's what I call "direct genning." */
 int
 devgen(struct chan *c, char *unused_name, struct dirtab *tab, int ntab,
        int i, struct dir *dp)
@@ -112,7 +120,7 @@ devgen(struct chan *c, char *unused_name, struct dirtab *tab, int ntab,
        }
        if (tab->qid.vers == -1)
                return 0;
-       devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
+       devdir(c, tab->qid, tab->name, tab->length, eve.name, tab->perm, dp);
        return 1;
 }
 
@@ -289,6 +297,18 @@ Done:
        return wq;
 }
 
+/* Helper, makes a stat in @dp, given @n bytes, from chan @c's contents in @dir.
+ * Throws on error, returns the size used on success. */
+size_t dev_make_stat(struct chan *c, struct dir *dir, uint8_t *dp, size_t n)
+{
+       if (c->flag & CMSG)
+               dir->mode |= DMMOUNT;
+       n = convD2M(dir, dp, n);
+       if (n == 0)
+               error(EINVAL, ERROR_FIXME);
+       return n;
+}
+
 int
 devstat(struct chan *c, uint8_t * db, int n,
                struct dirtab *tab, int ntab, Devgen * gen)
@@ -311,7 +331,7 @@ devstat(struct chan *c, uint8_t * db, int n,
                                                for (elem = p = c->name->s; *p; p++)
                                                        if (*p == '/')
                                                                elem = p + 1;
-                                       devdir(c, c->qid, elem, 0, eve, DMDIR | 0555, &dir);
+                                       devdir(c, c->qid, elem, 0, eve.name, DMDIR | 0555, &dir);
                                        n = convD2M(&dir, db, n);
                                        if (n == 0)
                                                error(EINVAL, ERROR_FIXME);
@@ -326,14 +346,8 @@ devstat(struct chan *c, uint8_t * db, int n,
                        case 1:
                                printd("DEVSTAT gen returns path %p name %s, want path %p\n",
                                           dir.qid.path, dir.name, c->qid.path);
-                               if (c->qid.path == dir.qid.path) {
-                                       if (c->flag & CMSG)
-                                               dir.mode |= DMMOUNT;
-                                       n = convD2M(&dir, db, n);
-                                       if (n == 0)
-                                               error(EINVAL, ERROR_FIXME);
-                                       return n;
-                               }
+                               if (c->qid.path == dir.qid.path)
+                                       return dev_make_stat(c, &dir, db, n);
                                break;
                }
 }
@@ -377,16 +391,18 @@ devdirread(struct chan *c, char *d, long n,
 }
 
 /*
- * error(EPERM, ERROR_FIXME) if open permission not granted for up->env->user.
+ * error(EPERM, ERROR_FIXME) if open permission not granted for
+ * current->user.name
  */
 void devpermcheck(char *fileuid, uint32_t perm, int omode)
 {
        int rwx;
+
        /* select user, group, or other from the traditional rwxrwxrwx, shifting
         * into the upper-most position */
-       if (strcmp(current->user, fileuid) == 0)
+       if (strcmp(current->user.name, fileuid) == 0)
                perm <<= 0;
-       else if (strcmp(current->user, eve) == 0)
+       else if (iseve())
                perm <<= 3;
        else
                perm <<= 6;