Module Name: src
Committed By: pooka
Date: Wed Jun 10 12:12:23 UTC 2009
Modified Files:
src/sys/rump/librump/rumpvfs: rumpfs.c
Log Message:
Support VOP_MKNOD. This is so that components which need device
nodes (e.g. raidframe) can create them.
To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/rump/librump/rumpvfs/rumpfs.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/rump/librump/rumpvfs/rumpfs.c
diff -u src/sys/rump/librump/rumpvfs/rumpfs.c:1.18 src/sys/rump/librump/rumpvfs/rumpfs.c:1.19
--- src/sys/rump/librump/rumpvfs/rumpfs.c:1.18 Tue Jun 9 14:20:42 2009
+++ src/sys/rump/librump/rumpvfs/rumpfs.c Wed Jun 10 12:12:23 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpfs.c,v 1.18 2009/06/09 14:20:42 pooka Exp $ */
+/* $NetBSD: rumpfs.c,v 1.19 2009/06/10 12:12:23 pooka Exp $ */
/*
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.18 2009/06/09 14:20:42 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpfs.c,v 1.19 2009/06/10 12:12:23 pooka Exp $");
#include <sys/param.h>
#include <sys/mount.h>
@@ -56,9 +56,11 @@
static int rump_vop_lookup(void *);
static int rump_vop_getattr(void *);
static int rump_vop_mkdir(void *);
+static int rump_vop_mknod(void *);
static int rump_vop_inactive(void *);
static int rump_vop_reclaim(void *);
static int rump_vop_success(void *);
+static int rump_vop_spec(void *);
int (**fifo_vnodeop_p)(void *);
const struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
@@ -74,6 +76,8 @@
{ &vop_lookup_desc, rump_vop_lookup },
{ &vop_getattr_desc, rump_vop_getattr },
{ &vop_mkdir_desc, rump_vop_mkdir },
+ { &vop_mknod_desc, rump_vop_mknod },
+ { &vop_access_desc, rump_vop_success },
{ &vop_putpages_desc, genfs_null_putpages },
{ &vop_fsync_desc, rump_vop_success },
{ &vop_lock_desc, genfs_lock },
@@ -84,8 +88,18 @@
};
const struct vnodeopv_desc rump_vnodeop_opv_desc =
{ &rump_vnodeop_p, rump_vnodeop_entries };
+
+int (**rump_specop_p)(void *);
+const struct vnodeopv_entry_desc rump_specop_entries[] = {
+ { &vop_default_desc, rump_vop_spec },
+ { NULL, NULL }
+};
+const struct vnodeopv_desc rump_specop_opv_desc =
+ { &rump_specop_p, rump_specop_entries };
+
const struct vnodeopv_desc * const rump_opv_descs[] = {
&rump_vnodeop_opv_desc,
+ &rump_specop_opv_desc,
NULL
};
@@ -109,7 +123,7 @@
};
static struct rumpfs_node *
-makeprivate(enum vtype vt)
+makeprivate(enum vtype vt, dev_t rdev, voff_t size)
{
struct rumpfs_node *rn;
struct vattr *va;
@@ -130,7 +144,7 @@
va->va_gid = 0;
va->va_fsid =
va->va_fileid = atomic_inc_uint_nv(&lastino);
- va->va_size = 512;
+ va->va_size = size;
va->va_blocksize = 512;
va->va_atime = ts;
va->va_mtime = ts;
@@ -138,7 +152,7 @@
va->va_birthtime = ts;
va->va_gen = 0;
va->va_flags = 0;
- va->va_rdev = -1;
+ va->va_rdev = rdev;
va->va_bytes = 512;
va->va_filerev = 0;
va->va_vaflags = 0;
@@ -147,7 +161,8 @@
}
static int
-rump_makevnode(const char *path, size_t size, enum vtype vt, struct vnode **vpp)
+rump_makevnode(const char *path, voff_t size, enum vtype vt, dev_t rdev,
+ struct vnode **vpp, bool regrumpblk)
{
struct vnode *vp;
struct rumpfs_node *rn;
@@ -156,7 +171,7 @@
if (vt == VREG || vt == VCHR || vt == VBLK) {
vt = VBLK;
- vpops = spec_vnodeop_p;
+ vpops = rump_specop_p;
} else {
vpops = rump_vnodeop_p;
}
@@ -171,16 +186,19 @@
vp->v_type = vt;
if (vp->v_type == VBLK) {
- rv = rumpblk_register(path);
- if (rv == -1)
- panic("rump_makevnode: lazy bum");
- spec_node_init(vp, makedev(RUMPBLK, rv));
- }
- if (vt != VBLK) {
- rn = makeprivate(vp->v_type);
- rn->rn_vp = vp;
- vp->v_data = rn;
+ if (regrumpblk) {
+ rv = rumpblk_register(path);
+ if (rv == -1)
+ panic("rump_makevnode: lazy bum");
+ rdev = makedev(RUMPBLK, rv);
+ spec_node_init(vp, rdev);
+ } else {
+ spec_node_init(vp, rdev);
+ }
}
+ rn = makeprivate(vp->v_type, rdev, size);
+ rn->rn_vp = vp;
+ vp->v_data = rn;
vn_lock(vp, LK_RETRY | LK_EXCLUSIVE);
*vpp = vp;
@@ -241,7 +259,8 @@
vt = VBAD;
break;
}
- error = rump_makevnode(cnp->cn_pnbuf, fsize, vt, vpp);
+ error = rump_makevnode(cnp->cn_pnbuf, fsize, vt, -1,
+ vpp, true);
if (error)
return error;
cnp->cn_consume = strlen(cnp->cn_nameptr
@@ -266,7 +285,6 @@
return EJUSTRETURN;
}
KASSERT(rd);
- KASSERT(rd->rd_node->rn_va.va_type == VDIR);
retry:
mutex_enter(&reclock);
@@ -277,7 +295,8 @@
goto retry;
*vpp = vp;
} else {
- rv = rump_makevnode(cnp->cn_nameptr, DEV_BSIZE, VDIR, vpp);
+ rv = rump_makevnode(cnp->cn_nameptr, DEV_BSIZE, VDIR, -1,
+ vpp, false);
if (rv)
return rv;
}
@@ -315,7 +334,8 @@
struct rumpfs_dent *rdent;
int rv = 0;
- if ((rv = rump_makevnode(cnp->cn_nameptr, DEV_BSIZE, VDIR, vpp)) != 0)
+ if ((rv = rump_makevnode(cnp->cn_nameptr, DEV_BSIZE, VDIR, -1,
+ vpp, false)) != 0)
goto out;
rdent = kmem_alloc(sizeof(*rdent), KM_SLEEP);
@@ -331,6 +351,40 @@
}
static int
+rump_vop_mknod(void *v)
+{
+ struct vop_mknod_args /* {
+ struct vnode *a_dvp;
+ struct vnode **a_vpp;
+ struct componentname *a_cnp;
+ struct vattr *a_vap;
+ }; */ *ap = v;
+ struct vnode *dvp = ap->a_dvp;
+ struct vnode **vpp = ap->a_vpp;
+ struct componentname *cnp = ap->a_cnp;
+ struct vattr *va = ap->a_vap;
+ struct rumpfs_node *rnd = dvp->v_data;
+ struct rumpfs_dent *rdent;
+ int rv;
+
+ if ((rv = rump_makevnode(cnp->cn_nameptr, DEV_BSIZE, va->va_type,
+ va->va_rdev, vpp, false)) != 0)
+ goto out;
+
+ rdent = kmem_alloc(sizeof(*rdent), KM_SLEEP);
+ rdent->rd_name = kmem_alloc(cnp->cn_namelen+1, KM_SLEEP);
+ rdent->rd_node = (*vpp)->v_data;
+ rdent->rd_node->rn_va.va_rdev = va->va_rdev;
+ strlcpy(rdent->rd_name, cnp->cn_nameptr, cnp->cn_namelen+1);
+
+ LIST_INSERT_HEAD(&rnd->rn_dir, rdent, rd_entries);
+
+ out:
+ vput(dvp);
+ return rv;
+}
+
+static int
rump_vop_success(void *v)
{
@@ -363,6 +417,25 @@
return 0;
}
+static int
+rump_vop_spec(void *v)
+{
+ struct vop_generic_args *ap = v;
+ int (**opvec)(void *);
+
+ switch (ap->a_desc->vdesc_offset) {
+ case VOP_ACCESS_DESCOFFSET:
+ case VOP_GETATTR_DESCOFFSET:
+ opvec = rump_vnodeop_p;
+ break;
+ default:
+ opvec = spec_vnodeop_p;
+ break;
+ }
+
+ return VOCALL(opvec, ap->a_desc->vdesc_offset, v);
+}
+
void
rumpfs_init(void)
{
@@ -377,7 +450,7 @@
TAILQ_INIT(&rump_mnt.mnt_vnodelist);
vfs_opv_init(rump_opv_descs);
- rv = rump_makevnode("/", 0, VDIR, &rootvnode);
+ rv = rump_makevnode("/", 0, VDIR, -1, &rootvnode, false);
if (rv)
panic("could not create root vnode: %d", rv);
rootvnode->v_vflag |= VV_ROOT;