xref: /netbsd-src/sys/miscfs/kernfs/kernfs_vfsops.c (revision d9158b13b5dfe46201430699a3f7a235ecf28df3)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software donated to Berkeley by
6  * Jan-Simon Pendry.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * 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 the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *	from: @(#)kernfs_vfsops.c	8.5 (Berkeley) 6/15/94
37  *	$Id: kernfs_vfsops.c,v 1.17 1994/06/15 22:54:40 mycroft Exp $
38  */
39 
40 /*
41  * Kernel params Filesystem
42  */
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/conf.h>
47 #include <sys/types.h>
48 #include <sys/proc.h>
49 #include <sys/vnode.h>
50 #include <sys/mount.h>
51 #include <sys/namei.h>
52 #include <sys/malloc.h>
53 
54 #include <miscfs/specfs/specdev.h>
55 #include <miscfs/kernfs/kernfs.h>
56 
57 dev_t rrootdev = NODEV;
58 
59 kernfs_init()
60 {
61 
62 }
63 
64 void
65 kernfs_get_rrootdev()
66 {
67 	static int tried = 0;
68 	int cmaj;
69 
70 	if (tried) {
71 		/* Already did it once. */
72 		return;
73 	}
74 	tried = 1;
75 
76 	if (rootdev == NODEV)
77 		return;
78 	for (cmaj = 0; cmaj < nchrdev; cmaj++) {
79 		rrootdev = makedev(cmaj, minor(rootdev));
80 		if (chrtoblk(rrootdev) == rootdev)
81 			return;
82 	}
83 	rrootdev = NODEV;
84 	printf("kernfs_get_rrootdev: no raw root device\n");
85 }
86 
87 /*
88  * Mount the Kernel params filesystem
89  */
90 kernfs_mount(mp, path, data, ndp, p)
91 	struct mount *mp;
92 	char *path;
93 	caddr_t data;
94 	struct nameidata *ndp;
95 	struct proc *p;
96 {
97 	int error = 0;
98 	u_int size;
99 	struct kernfs_mount *fmp;
100 	struct vnode *rvp;
101 
102 #ifdef KERNFS_DIAGNOSTIC
103 	printf("kernfs_mount(mp = %x)\n", mp);
104 #endif
105 
106 	/*
107 	 * Update is a no-op
108 	 */
109 	if (mp->mnt_flag & MNT_UPDATE)
110 		return (EOPNOTSUPP);
111 
112 	if (error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &rvp))
113 		return (error);
114 
115 	MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount),
116 	    M_MISCFSMNT, M_WAITOK);
117 	rvp->v_type = VDIR;
118 	rvp->v_flag |= VROOT;
119 #ifdef KERNFS_DIAGNOSTIC
120 	printf("kernfs_mount: root vp = %x\n", rvp);
121 #endif
122 	fmp->kf_root = rvp;
123 	mp->mnt_flag |= MNT_LOCAL;
124 	mp->mnt_data = (qaddr_t)fmp;
125 	getnewfsid(mp, makefstype(MOUNT_KERNFS));
126 
127 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
128 	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
129 	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
130 	bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
131 #ifdef KERNFS_DIAGNOSTIC
132 	printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
133 #endif
134 
135 	kernfs_get_rrootdev();
136 	return (0);
137 }
138 
139 kernfs_start(mp, flags, p)
140 	struct mount *mp;
141 	int flags;
142 	struct proc *p;
143 {
144 
145 	return (0);
146 }
147 
148 kernfs_unmount(mp, mntflags, p)
149 	struct mount *mp;
150 	int mntflags;
151 	struct proc *p;
152 {
153 	int error;
154 	int flags = 0;
155 	extern int doforce;
156 	struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
157 
158 #ifdef KERNFS_DIAGNOSTIC
159 	printf("kernfs_unmount(mp = %x)\n", mp);
160 #endif
161 
162 	if (mntflags & MNT_FORCE) {
163 		/* kernfs can never be rootfs so don't check for it */
164 		if (!doforce)
165 			return (EINVAL);
166 		flags |= FORCECLOSE;
167 	}
168 
169 	/*
170 	 * Clear out buffer cache.  I don't think we
171 	 * ever get anything cached at this level at the
172 	 * moment, but who knows...
173 	 */
174 	if (rootvp->v_usecount > 1)
175 		return (EBUSY);
176 #ifdef KERNFS_DIAGNOSTIC
177 	printf("kernfs_unmount: calling vflush\n");
178 #endif
179 	if (error = vflush(mp, rootvp, flags))
180 		return (error);
181 
182 #ifdef KERNFS_DIAGNOSTIC
183 	vprint("kernfs root", rootvp);
184 #endif
185 	/*
186 	 * Clean out the old root vnode for reuse.
187 	 */
188 	vrele(rootvp);
189 	vgone(rootvp);
190 	/*
191 	 * Finally, throw away the kernfs_mount structure
192 	 */
193 	free(mp->mnt_data, M_MISCFSMNT);
194 	mp->mnt_data = 0;
195 	return (0);
196 }
197 
198 kernfs_root(mp, vpp)
199 	struct mount *mp;
200 	struct vnode **vpp;
201 {
202 	struct vnode *vp;
203 
204 #ifdef KERNFS_DIAGNOSTIC
205 	printf("kernfs_root(mp = %x)\n", mp);
206 #endif
207 
208 	/*
209 	 * Return locked reference to root.
210 	 */
211 	vp = VFSTOKERNFS(mp)->kf_root;
212 	VREF(vp);
213 	VOP_LOCK(vp);
214 	*vpp = vp;
215 	return (0);
216 }
217 
218 kernfs_quotactl(mp, cmd, uid, arg, p)
219 	struct mount *mp;
220 	int cmd;
221 	uid_t uid;
222 	caddr_t arg;
223 	struct proc *p;
224 {
225 
226 	return (EOPNOTSUPP);
227 }
228 
229 kernfs_statfs(mp, sbp, p)
230 	struct mount *mp;
231 	struct statfs *sbp;
232 	struct proc *p;
233 {
234 
235 #ifdef KERNFS_DIAGNOSTIC
236 	printf("kernfs_statfs(mp = %x)\n", mp);
237 #endif
238 
239 #ifdef COMPAT_09
240 	sbp->f_type = 7;
241 #else
242 	sbp->f_type = 0;
243 #endif
244 	sbp->f_flags = 0;
245 	sbp->f_bsize = DEV_BSIZE;
246 	sbp->f_iosize = DEV_BSIZE;
247 	sbp->f_blocks = 2;		/* 1K to keep df happy */
248 	sbp->f_bfree = 0;
249 	sbp->f_bavail = 0;
250 	sbp->f_files = 0;
251 	sbp->f_ffree = 0;
252 	if (sbp != &mp->mnt_stat) {
253 		bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
254 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
255 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
256 	}
257 	strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN);
258 	sbp->f_fstypename[MFSNAMELEN] = '\0';
259 	return (0);
260 }
261 
262 kernfs_sync(mp, waitfor)
263 	struct mount *mp;
264 	int waitfor;
265 {
266 
267 	return (0);
268 }
269 
270 /*
271  * Kernfs flat namespace lookup.
272  * Currently unsupported.
273  */
274 kernfs_vget(mp, ino, vpp)
275 	struct mount *mp;
276 	ino_t ino;
277 	struct vnode **vpp;
278 {
279 
280 	return (EOPNOTSUPP);
281 }
282 
283 
284 kernfs_fhtovp(mp, fhp, setgen, vpp)
285 	struct mount *mp;
286 	struct fid *fhp;
287 	int setgen;
288 	struct vnode **vpp;
289 {
290 
291 	return (EOPNOTSUPP);
292 }
293 
294 kernfs_vptofh(vp, fhp)
295 	struct vnode *vp;
296 	struct fid *fhp;
297 {
298 
299 	return (EOPNOTSUPP);
300 }
301 
302 struct vfsops kernfs_vfsops = {
303 	MOUNT_KERNFS,
304 	kernfs_mount,
305 	kernfs_start,
306 	kernfs_unmount,
307 	kernfs_root,
308 	kernfs_quotactl,
309 	kernfs_statfs,
310 	kernfs_sync,
311 	kernfs_vget,
312 	kernfs_fhtovp,
313 	kernfs_vptofh,
314 	kernfs_init,
315 };
316