Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / sys / kern / vfs_synth.c
blobe9c92867693cae1c981944dcb7b9d24379438f10
1 /*
2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sys/kern/vfs_synth.c,v 1.1 2007/07/30 08:02:38 dillon Exp $
38 * Synthesize vnodes for devices. Devices have certain requirements and
39 * limitations with regards to opening and closing, and physical I/O
40 * limits. This module allows you to synthesize a specfs-backed vnode
41 * for a device.
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/vnode.h>
48 #include <sys/lock.h>
49 #include <sys/disk.h>
50 #include <sys/mount.h>
52 #include <sys/thread2.h>
54 static struct mount *synth_mount;
57 * getsynthvnode() - return a vnode representing a device.
59 * The caller must VOP_OPEN() the vnode as appropriate before using it for
60 * I/O, and VOP_CLOSE() it when finished.
62 * The returned vnode will be referenced and locked. The caller must
63 * vrele() the vnode when finished with it.
65 struct vnode *
66 getsynthvnode(const char *devname)
68 struct vnode *vp;
69 int error;
70 cdev_t dev;
72 dev = disk_locate(devname);
73 if (dev == NULL)
74 return(NULL);
76 error = getnewvnode(VT_SYNTH, synth_mount, &vp, 0, 0);
77 if (error)
78 panic("getsynthvnode: unable to get new vnode");
79 vp->v_type = VCHR;
80 addaliasu(vp, dev->si_umajor, dev->si_uminor);
81 return(vp);
85 * VOP support - use specfs and dummy up the mount.
88 static int synth_inactive(struct vop_inactive_args *ap);
89 static int synth_reclaim(struct vop_reclaim_args *ap);
91 struct vop_ops synth_vnode_vops = {
92 .vop_default = spec_vnoperate,
93 .vop_inactive = synth_inactive,
94 .vop_reclaim = synth_reclaim
97 VNODEOP_SET(synth_vnode_vops);
99 static
101 synth_inactive(struct vop_inactive_args *ap)
103 vrecycle(ap->a_vp);
104 return (0);
107 static
109 synth_reclaim(struct vop_reclaim_args *ap)
111 ap->a_vp->v_data = NULL;
112 return(0);
116 * Create a dummy mount structure and VFS. This VFS is not currently
117 * mountable.
119 static int synth_vfs_mount(struct mount *, char *, caddr_t, struct ucred *);
120 static int synth_vfs_unmount(struct mount *, int mntflags);
121 static int synth_vfs_root(struct mount *mp, struct vnode **vpp);
123 static struct vfsops synth_vfsops = {
124 .vfs_mount = synth_vfs_mount,
125 .vfs_root = synth_vfs_root,
126 .vfs_unmount = synth_vfs_unmount
129 static struct vfsconf synth_vfsconf = {
130 .vfc_vfsops = &synth_vfsops,
131 .vfc_name = { "synth" },
132 .vfc_typenum = VT_SYNTH
135 static
137 synth_vfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
139 return (EINVAL);
142 static
144 synth_vfs_unmount(struct mount *mp, int mntflags)
146 return (0);
149 static
151 synth_vfs_root(struct mount *mp, struct vnode **vpp)
153 *vpp = NULL;
154 return (EINVAL);
158 * We have to register our VFS and create our dummy mount structure before
159 * devices configure or vinum will not be able to configure at boot. The
160 * standard usage via VFS_SET() is registered too late.
162 static
163 void
164 synthinit(void *arg __unused)
166 int error;
168 error = vfs_register(&synth_vfsconf);
169 KKASSERT(error == 0);
170 error = vfs_rootmountalloc("synth", "dummy", &synth_mount);
171 KKASSERT(error == 0);
172 synth_mount->mnt_vn_use_ops = &synth_vnode_vops;
175 SYSINIT(synthinit, SI_SUB_CREATE_INIT, SI_ORDER_ANY, synthinit, NULL)