xref: /freebsd/sys/fs/pseudofs/pseudofs.c (revision 1a2cdef4962b47be5057809ce730a733b7f3c27c)
1 /*-
2  * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *	$FreeBSD$
29  */
30 
31 #include <sys/param.h>
32 #include <sys/kernel.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/mount.h>
37 #include <sys/proc.h>
38 #include <sys/sbuf.h>
39 #include <sys/sysctl.h>
40 #include <sys/vnode.h>
41 
42 #include <fs/pseudofs/pseudofs.h>
43 #include <fs/pseudofs/pseudofs_internal.h>
44 
45 SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0,
46     "pseudofs");
47 
48 /*
49  * Mount a pseudofs instance
50  */
51 int
52 pfs_mount(struct pfs_info *pi, struct mount *mp, char *path, caddr_t data,
53 	  struct nameidata *ndp, struct proc *p)
54 {
55 	struct statfs *sbp;
56 
57 	if (mp->mnt_flag & MNT_UPDATE)
58 		return (EOPNOTSUPP);
59 
60 	mp->mnt_flag |= MNT_LOCAL;
61 	mp->mnt_data = (qaddr_t)pi;
62 	vfs_getnewfsid(mp);
63 
64 	sbp = &mp->mnt_stat;
65 	bcopy(pi->pi_name, sbp->f_mntfromname, sizeof pi->pi_name);
66 	sbp->f_bsize = PAGE_SIZE;
67 	sbp->f_iosize = PAGE_SIZE;
68 	sbp->f_blocks = 1;
69 	sbp->f_bfree = 0;
70 	sbp->f_bavail = 0;
71 	sbp->f_files = 1;
72 	sbp->f_ffree = 0;
73 
74 	return (0);
75 }
76 
77 /*
78  * Unmount a pseudofs instance
79  */
80 int
81 pfs_unmount(struct mount *mp, int mntflags, struct proc *p)
82 {
83 	struct pfs_info *pi;
84 	int error;
85 
86 	pi = (struct pfs_info *)mp->mnt_data;
87 
88 	/* XXX do stuff with pi... */
89 
90 	error = vflush(mp, 0, (mntflags & MNT_FORCE) ?  FORCECLOSE : 0);
91 	return (error);
92 }
93 
94 /*
95  * Return a root vnode
96  */
97 int
98 pfs_root(struct mount *mp, struct vnode **vpp)
99 {
100 	struct pfs_info *pi;
101 
102 	pi = (struct pfs_info *)mp->mnt_data;
103 	return pfs_vncache_alloc(mp, vpp, pi->pi_root);
104 }
105 
106 /*
107  * Return filesystem stats
108  */
109 int
110 pfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
111 {
112 	bcopy(&mp->mnt_stat, sbp, sizeof *sbp);
113 	return (0);
114 }
115 
116 /*
117  * Initialize a pseudofs instance
118  */
119 int
120 pfs_init(struct pfs_info *pi, struct vfsconf *vfc)
121 {
122 	mtx_init(&pi->pi_mutex, "pseudofs", MTX_DEF);
123 	pfs_fileno_init(pi);
124 	printf("%s registered\n", pi->pi_name);
125 	return (0);
126 }
127 
128 /*
129  * Destroy a pseudofs instance
130  */
131 int
132 pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc)
133 {
134 	pfs_fileno_uninit(pi);
135 	mtx_destroy(&pi->pi_mutex);
136 	printf("%s unregistered\n", pi->pi_name);
137 	return (0);
138 }
139 
140 /*
141  * Handle load / unload events
142  */
143 static int
144 pfs_modevent(module_t mod, int evt, void *arg)
145 {
146 	switch (evt) {
147 	case MOD_LOAD:
148 		pfs_fileno_load();
149 		pfs_vncache_load();
150 		break;
151 	case MOD_UNLOAD:
152 	case MOD_SHUTDOWN:
153 		pfs_vncache_unload();
154 		pfs_fileno_unload();
155 		break;
156 	default:
157 		printf("pseudofs: unexpected event type %d\n", evt);
158 		break;
159 	}
160 	return 0;
161 }
162 
163 /*
164  * Module declaration
165  */
166 static moduledata_t pseudofs_data = {
167 	"pseudofs",
168 	pfs_modevent,
169 	NULL
170 };
171 DECLARE_MODULE(pseudofs, pseudofs_data, SI_SUB_EXEC, SI_ORDER_FIRST);
172 MODULE_VERSION(pseudofs, 1);
173