9ns: Add 'extensions' to dev.create
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 22 Feb 2018 21:47:30 +0000 (16:47 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 6 Apr 2018 19:23:01 +0000 (15:23 -0400)
This is based on Eric VH's 9p2000 RFC:

http://ericvh.github.io/9p-rfc/rfc9p2000.u.html

The extension string's meaning will depend on the mode/perm bits (not
omode, which is open mode).

The main user will be symlinks.  The ext string will be the path.  By
adding the path to the create message, we can atomically create a symlink
file and have its path set.  That might make namec easier.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/mnt.c
kern/drivers/dev/root.c
kern/drivers/dev/srv.c
kern/drivers/dev/vars.c
kern/include/ns.h
kern/src/ns/chan.c
kern/src/ns/dev.c

index e2de883..12e19fe 100644 (file)
@@ -588,8 +588,12 @@ static struct chan *mntopen(struct chan *c, int omode)
        return mntopencreate(Topen, c, NULL, omode, 0);
 }
 
-static void mntcreate(struct chan *c, char *name, int omode, uint32_t perm)
+static void mntcreate(struct chan *c, char *name, int omode, uint32_t perm,
+                      char *ext)
 {
+       /* TODO: support extensions for e.g. symlinks */
+       if (perm & DMSYMLINK)
+               error(EINVAL, "#%s doesn't support symlinks", devname());
        mntopencreate(Tcreate, c, name, omode, perm);
 }
 
index 3cbbbc2..45ebc7f 100644 (file)
@@ -340,10 +340,14 @@ static struct chan *rootopen(struct chan *c, int omode)
        return devopen(c, omode, NULL, 0, rootgen);
 }
 
-static void rootcreate(struct chan *c, char *name, int omode, uint32_t perm)
+static void rootcreate(struct chan *c, char *name, int omode, uint32_t perm,
+                       char *ext)
 {
        struct dirtab *r = &roottab[c->qid.path], *newr;
        struct rootdata *rd = &rootdata[c->qid.path];
+
+       if (perm & DMSYMLINK)
+               error(EINVAL, "#%s doesn't support symlinks", devname());
        /* need to filter openmode so that it gets only the access-type bits */
        omode = openmode(omode);
        c->mode = openmode(omode);
index 2a5cc26..1db03fd 100644 (file)
@@ -221,9 +221,13 @@ static struct chan *srvopen(struct chan *c, int omode)
        return c;
 }
 
-static void srvcreate(struct chan *c, char *name, int omode, uint32_t perm)
+static void srvcreate(struct chan *c, char *name, int omode, uint32_t perm,
+                      char *ext)
 {
        struct srvfile *srv;
+
+       if (perm & DMSYMLINK)
+               error(EINVAL, "#%s doesn't support symlinks", devname());
        srv = kzmalloc(sizeof(struct srvfile), MEM_WAIT);
        kstrdup(&srv->name, name);
        kstrdup(&srv->user, current ? current->user.name : "eve");
index f056f2b..3de2549 100644 (file)
@@ -166,13 +166,16 @@ static struct dirtab *find_free_var(void)
 }
 
 /* We ignore the perm - they are all hard-coded in the dirtab */
-static void vars_create(struct chan *c, char *name, int omode, uint32_t perm)
+static void vars_create(struct chan *c, char *name, int omode, uint32_t perm,
+                        char *ext)
 {
        struct dirtab *new_slot;
        uintptr_t addr;
        char *bang;
        size_t size;
 
+       if (perm & DMSYMLINK)
+               error(EINVAL, "#%s doesn't support symlinks", devname());
        /* TODO: check that the user is privileged */
        bang = strchr(name, '!');
        if (!bang)
index 1e31279..6d0a8df 100644 (file)
@@ -457,7 +457,7 @@ struct dev {
        struct walkqid *(*walk) (struct chan *, struct chan *, char **name, int);
        int (*stat) (struct chan *, uint8_t *, int);
        struct chan *(*open) (struct chan *, int);
-       void (*create) (struct chan *, char *, int, uint32_t);
+       void (*create)(struct chan *, char *, int, uint32_t, char *);
        void (*close) (struct chan *);
        long (*read) (struct chan *, void *, long, int64_t);
        struct block *(*bread) (struct chan *, long, uint32_t);
@@ -707,7 +707,7 @@ struct chan *devattach(const char *name, char *spec);
 struct block *devbread(struct chan *, long, uint32_t);
 long devbwrite(struct chan *, struct block *, uint32_t);
 struct chan *devclone(struct chan *);
-void devcreate(struct chan *, char *name, int mode, uint32_t perm);
+void devcreate(struct chan *, char *name, int mode, uint32_t perm, char *ext);
 void devdir(struct chan *, struct qid, char *, int64_t, char *, long,
                        struct dir *);
 long devdirread(struct chan *, char *, long, struct dirtab *, int, Devgen *);
index 06e4920..b09cbac 100644 (file)
@@ -1253,7 +1253,7 @@ Open:
                                cnew->flag |= omode & CEXTERNAL_FLAGS;
                                devtab[cnew->type].create(cnew, e.elems[e.ARRAY_SIZEs - 1],
                                                                                  omode & ~(O_EXCL | O_CLOEXEC),
-                                                                                 perm);
+                                                                                 perm, NULL);
                                poperror();
 
                                if (m)
index bc8db6e..a849bc3 100644 (file)
@@ -430,8 +430,8 @@ Return:
        return c;
 }
 
-void
-devcreate(struct chan *c, char *unused_char_p_t, int unused_int, uint32_t u)
+void devcreate(struct chan *c, char *unused_char_p_t, int unused_int,
+               uint32_t u, char *ext)
 {
        error(EPERM, ERROR_FIXME);
 }