Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/librump/rumpvfs Implement RUMP_ETFS_REG. Usable e....



details:   https://anonhg.NetBSD.org/src/rev/018547cc8eac
branches:  trunk
changeset: 747880:018547cc8eac
user:      pooka <pooka%NetBSD.org@localhost>
date:      Sun Oct 04 16:31:08 2009 +0000

description:
Implement RUMP_ETFS_REG.  Usable e.g. by firmload(9).
(well, it should probably be RUMP_ETFS_PATH, but simple things first)

diffstat:

 sys/rump/librump/rumpvfs/rumpfs.c |  199 ++++++++++++++++++++++++++++++++-----
 1 files changed, 168 insertions(+), 31 deletions(-)

diffs (truncated from 345 to 300 lines):

diff -r ff089f8449c6 -r 018547cc8eac sys/rump/librump/rumpvfs/rumpfs.c
--- a/sys/rump/librump/rumpvfs/rumpfs.c Sun Oct 04 15:12:41 2009 +0000
+++ b/sys/rump/librump/rumpvfs/rumpfs.c Sun Oct 04 16:31:08 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpfs.c,v 1.23 2009/09/05 11:02:49 pooka Exp $        */
+/*     $NetBSD: rumpfs.c,v 1.24 2009/10/04 16:31:08 pooka Exp $        */
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -28,21 +28,23 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.23 2009/09/05 11:02:49 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.24 2009/10/04 16:31:08 pooka Exp $");
 
 #include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/filedesc.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/kauth.h>
+#include <sys/malloc.h>
 #include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/errno.h>
-#include <sys/kauth.h>
+#include <sys/namei.h>
 #include <sys/lock.h>
 #include <sys/lockf.h>
+#include <sys/queue.h>
 #include <sys/stat.h>
-#include <sys/namei.h>
-#include <sys/queue.h>
-#include <sys/filedesc.h>
 #include <sys/syscallargs.h>
-#include <sys/atomic.h>
+#include <sys/vnode.h>
 
 #include <miscfs/fifofs/fifo.h>
 #include <miscfs/specfs/specdev.h>
@@ -61,6 +63,9 @@
 static int rump_vop_reclaim(void *);
 static int rump_vop_success(void *);
 static int rump_vop_spec(void *);
+static int rump_vop_read(void *);
+static int rump_vop_write(void *);
+static int rump_vop_open(void *);
 
 int (**fifo_vnodeop_p)(void *);
 const struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
@@ -78,6 +83,9 @@
        { &vop_mkdir_desc, rump_vop_mkdir },
        { &vop_mknod_desc, rump_vop_mknod },
        { &vop_access_desc, rump_vop_success },
+       { &vop_read_desc, rump_vop_read },
+       { &vop_write_desc, rump_vop_write },
+       { &vop_open_desc, rump_vop_open },
        { &vop_putpages_desc, genfs_null_putpages },
        { &vop_fsync_desc, rump_vop_success },
        { &vop_lock_desc, genfs_lock },
@@ -114,11 +122,21 @@
        struct vattr rn_va;
        struct vnode *rn_vp;
 
-       /* only for VDIR */
-       LIST_HEAD(, rumpfs_dent) rn_dir;
+       union {
+               struct {
+                       char *hostpath;         /* VREG */
+                       int readfd;
+                       int writefd;
+               } reg;
+               LIST_HEAD(, rumpfs_dent) dir;   /* VDIR */
+       } rn_u;
 };
+#define rn_hostpath    rn_u.reg.hostpath
+#define rn_readfd      rn_u.reg.readfd
+#define rn_writefd     rn_u.reg.writefd
+#define rn_dir         rn_u.dir
 
-static struct rumpfs_node *makeprivate(enum vtype, dev_t, off_t);
+static struct rumpfs_node *makeprivate(enum vtype, dev_t, off_t, const char *);
 
 /*
  * Extra Terrestrial stuff.  We map a given key (pathname) to a file on
@@ -130,6 +148,8 @@
 
 struct etfs {
        char et_key[MAXPATHLEN];
+       size_t et_keylen;
+
        LIST_ENTRY(etfs) et_entries;
 
        struct rumpfs_node *et_rn;
@@ -163,12 +183,13 @@
 etfs_find(const char *key, struct rumpfs_node **rnp)
 {
        struct etfs *et;
+       size_t keylen = strlen(key);
        bool rv = false;
 
        KASSERT(mutex_owned(&etfs_lock));
 
        LIST_FOREACH(et, &etfs_list, et_entries) {
-               if (strcmp(key, et->et_key) == 0) {
+               if (keylen == et->et_keylen && strcmp(key, et->et_key) == 0) {
                        *rnp = et->et_rn;
                        rv = true;
                        break;
@@ -185,26 +206,25 @@
        struct etfs *et;
        struct rumpfs_node *rn_dummy;
        uint64_t fsize;
-       dev_t rdev;
+       dev_t rdev = NODEV;
        devminor_t dmin;
        int hft, error;
 
-       /* not supported for now, need r/w VOPs ... */
-       if (ftype == RUMP_ETFS_REG)
-               return EOPNOTSUPP;
-
        if (rumpuser_getfileinfo(hostpath, &fsize, &hft, &error))
                return error;
 
-       error = rumpblk_register(hostpath, &dmin);
-       if (error != 0) {
-               return error;
+       if (ftype == RUMP_ETFS_BLK || ftype == RUMP_ETFS_CHR) {
+               error = rumpblk_register(hostpath, &dmin);
+               if (error != 0) {
+                       return error;
+               }
+               rdev = makedev(RUMPBLK, dmin);
        }
-       rdev = makedev(RUMPBLK, dmin);
 
        et = kmem_alloc(sizeof(*et), KM_SLEEP);
        strcpy(et->et_key, key);
-       et->et_rn = makeprivate(ettype_to_vtype(ftype), rdev, fsize);
+       et->et_keylen = strlen(et->et_key);
+       et->et_rn = makeprivate(ettype_to_vtype(ftype), rdev, fsize, hostpath);
 
        mutex_enter(&etfs_lock);
        if (etfs_find(key, &rn_dummy)) {
@@ -223,10 +243,11 @@
 rump_etfs_remove(const char *key)
 {
        struct etfs *et;
+       size_t keylen = strlen(key);
 
        mutex_enter(&etfs_lock);
        LIST_FOREACH(et, &etfs_list, et_entries) {
-               if (strcmp(et->et_key, key) == 0) {
+               if (keylen == et->et_keylen && strcmp(et->et_key, key) == 0) {
                        LIST_REMOVE(et, et_entries);
                        kmem_free(et, sizeof(*et));
                        break;
@@ -248,14 +269,28 @@
 static kmutex_t reclock;
 
 static struct rumpfs_node *
-makeprivate(enum vtype vt, dev_t rdev, off_t size)
+makeprivate(enum vtype vt, dev_t rdev, off_t size, const char *hostpath)
 {
        struct rumpfs_node *rn;
        struct vattr *va;
        struct timespec ts;
 
        rn = kmem_zalloc(sizeof(*rn), KM_SLEEP);
-       LIST_INIT(&rn->rn_dir);
+
+       switch (vt) {
+       case VDIR:
+               LIST_INIT(&rn->rn_dir);
+               break;
+       case VREG:
+               rn->rn_readfd = -1;
+               rn->rn_writefd = -1;
+               rn->rn_hostpath = malloc(strlen(hostpath)+1, M_TEMP, M_WAITOK);
+               strcpy(rn->rn_hostpath, hostpath);
+               break;
+       default:
+               break;
+       }
+
        nanotime(&ts);
 
        va = &rn->rn_va;
@@ -300,7 +335,8 @@
        } else {
                vpops = rump_vnodeop_p;
        }
-       if (vpops != rump_specop_p && va->va_type != VDIR)
+       if (vpops != rump_specop_p && va->va_type != VDIR
+           && !(va->va_type == VREG && rn->rn_hostpath != NULL))
                return EOPNOTSUPP;
 
        rv = getnewvnode(VT_RUMP, &rump_mnt, vpops, &vp);
@@ -435,7 +471,7 @@
        struct rumpfs_dent *rdent;
        int rv = 0;
 
-       rn = makeprivate(VDIR, NODEV, DEV_BSIZE);
+       rn = makeprivate(VDIR, NODEV, DEV_BSIZE, NULL);
        mutex_enter(&reclock);
        rv = makevnode(rn, vpp);
        mutex_exit(&reclock);
@@ -471,7 +507,7 @@
        struct rumpfs_dent *rdent;
        int rv;
 
-       rn = makeprivate(va->va_type, va->va_rdev, DEV_BSIZE);
+       rn = makeprivate(va->va_type, va->va_rdev, DEV_BSIZE, NULL);
        mutex_enter(&reclock);
        rv = makevnode(rn, vpp);
        mutex_exit(&reclock);
@@ -492,6 +528,93 @@
 }
 
 static int
+rump_vop_open(void *v)
+{
+       struct vop_open_args /* {
+               struct vnode *a_vp;
+               int a_mode;
+               kauth_cred_t a_cred;
+       } */ *ap = v;
+       struct vnode *vp = ap->a_vp;
+       struct rumpfs_node *rn = vp->v_data;
+       int mode = ap->a_mode;
+       int error = EINVAL;
+
+       if (vp->v_type != VREG)
+               return 0;
+
+       if (mode & FREAD) {
+               if (rn->rn_readfd != -1)
+                       return 0;
+               rn->rn_readfd = rumpuser_open(rn->rn_hostpath,
+                   O_RDONLY, &error);
+       } else if (mode & FWRITE) {
+               if (rn->rn_writefd != -1)
+                       return 0;
+               rn->rn_writefd = rumpuser_open(rn->rn_hostpath,
+                   O_WRONLY, &error);
+       }
+
+       return error;
+}
+
+static int
+rump_vop_read(void *v)
+{
+       struct vop_read_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int ioflags a_ioflag;
+               kauth_cred_t a_cred;
+       }; */ *ap = v;
+       struct vnode *vp = ap->a_vp;
+       struct rumpfs_node *rn = vp->v_data;
+       struct uio *uio = ap->a_uio;
+       uint8_t *buf;
+       size_t bufsize;
+       int error = 0;
+
+       bufsize = uio->uio_resid;
+       buf = kmem_alloc(bufsize, KM_SLEEP);
+       if (rumpuser_read(rn->rn_readfd, buf, bufsize, &error) == -1)
+               goto out;
+       error = uiomove(buf, bufsize, uio);
+
+ out:
+       kmem_free(buf, bufsize);
+       return error;
+}
+
+static int
+rump_vop_write(void *v)
+{
+       struct vop_read_args /* {
+               struct vnode *a_vp;
+               struct uio *a_uio;
+               int ioflags a_ioflag;
+               kauth_cred_t a_cred;
+       }; */ *ap = v;
+       struct vnode *vp = ap->a_vp;
+       struct rumpfs_node *rn = vp->v_data;
+       struct uio *uio = ap->a_uio;
+       uint8_t *buf;
+       size_t bufsize;
+       int error = 0;
+
+       bufsize = uio->uio_resid;
+       buf = kmem_alloc(bufsize, KM_SLEEP);
+       error = uiomove(buf, bufsize, uio);
+       if (error)
+               goto out;



Home | Main Index | Thread Index | Old Index