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