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;