xref: /netbsd-src/sys/miscfs/kernfs/kernfs_vfsops.c (revision cafd1f7e9fac539e60b5e1e3bbadb405586481a8)
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.4 (Berkeley) 1/21/94
37  *	$Id: kernfs_vfsops.c,v 1.15 1994/06/08 11:33:20 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 	int bmaj, cmaj;
68 
69 	if (rootdev == NODEV)
70 		return;
71 	if (rrootdev != NODEV) {
72 		/* Already did it once. */
73 		return;
74 	}
75 	bmaj = major(rootdev);
76 	for (cmaj = 0; cmaj < nchrdev; cmaj++) {
77 		if (chrtoblk(cmaj) == bmaj) {
78 			rrootdev = makedev(cmaj, minor(rootdev));
79 			return;
80 		}
81 	}
82 	printf("kernfs_get_rrootdev: no raw root device\n");
83 }
84 
85 /*
86  * Mount the Kernel params filesystem
87  */
88 kernfs_mount(mp, path, data, ndp, p)
89 	struct mount *mp;
90 	char *path;
91 	caddr_t data;
92 	struct nameidata *ndp;
93 	struct proc *p;
94 {
95 	int error = 0;
96 	u_int size;
97 	struct kernfs_mount *fmp;
98 	struct vnode *rvp;
99 
100 #ifdef KERNFS_DIAGNOSTIC
101 	printf("kernfs_mount(mp = %x)\n", mp);
102 #endif
103 
104 	/*
105 	 * Update is a no-op
106 	 */
107 	if (mp->mnt_flag & MNT_UPDATE)
108 		return (EOPNOTSUPP);
109 
110 	if (error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &rvp))
111 		return (error);
112 
113 	MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount),
114 	    M_MISCFSMNT, M_WAITOK);
115 	rvp->v_type = VDIR;
116 	rvp->v_flag |= VROOT;
117 #ifdef KERNFS_DIAGNOSTIC
118 	printf("kernfs_mount: root vp = %x\n", rvp);
119 #endif
120 	fmp->kf_root = rvp;
121 	mp->mnt_flag |= MNT_LOCAL;
122 	mp->mnt_data = (qaddr_t)fmp;
123 	getnewfsid(mp, makefstype(MOUNT_KERNFS));
124 
125 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
126 	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
127 	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
128 	bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
129 #ifdef KERNFS_DIAGNOSTIC
130 	printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
131 #endif
132 
133 	kernfs_get_rrootdev();
134 	return (0);
135 }
136 
137 kernfs_start(mp, flags, p)
138 	struct mount *mp;
139 	int flags;
140 	struct proc *p;
141 {
142 
143 	return (0);
144 }
145 
146 kernfs_unmount(mp, mntflags, p)
147 	struct mount *mp;
148 	int mntflags;
149 	struct proc *p;
150 {
151 	int error;
152 	int flags = 0;
153 	extern int doforce;
154 	struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
155 
156 #ifdef KERNFS_DIAGNOSTIC
157 	printf("kernfs_unmount(mp = %x)\n", mp);
158 #endif
159 
160 	if (mntflags & MNT_FORCE) {
161 		/* kernfs can never be rootfs so don't check for it */
162 		if (!doforce)
163 			return (EINVAL);
164 		flags |= FORCECLOSE;
165 	}
166 
167 	/*
168 	 * Clear out buffer cache.  I don't think we
169 	 * ever get anything cached at this level at the
170 	 * moment, but who knows...
171 	 */
172 	if (rootvp->v_usecount > 1)
173 		return (EBUSY);
174 #ifdef KERNFS_DIAGNOSTIC
175 	printf("kernfs_unmount: calling vflush\n");
176 #endif
177 	if (error = vflush(mp, rootvp, flags))
178 		return (error);
179 
180 #ifdef KERNFS_DIAGNOSTIC
181 	vprint("kernfs root", rootvp);
182 #endif
183 	/*
184 	 * Clean out the old root vnode for reuse.
185 	 */
186 	vrele(rootvp);
187 	vgone(rootvp);
188 	/*
189 	 * Finally, throw away the kernfs_mount structure
190 	 */
191 	free(mp->mnt_data, M_MISCFSMNT);
192 	mp->mnt_data = 0;
193 	return (0);
194 }
195 
196 kernfs_root(mp, vpp)
197 	struct mount *mp;
198 	struct vnode **vpp;
199 {
200 	struct vnode *vp;
201 
202 #ifdef KERNFS_DIAGNOSTIC
203 	printf("kernfs_root(mp = %x)\n", mp);
204 #endif
205 
206 	/*
207 	 * Return locked reference to root.
208 	 */
209 	vp = VFSTOKERNFS(mp)->kf_root;
210 	VREF(vp);
211 	VOP_LOCK(vp);
212 	*vpp = vp;
213 	return (0);
214 }
215 
216 kernfs_quotactl(mp, cmd, uid, arg, p)
217 	struct mount *mp;
218 	int cmd;
219 	uid_t uid;
220 	caddr_t arg;
221 	struct proc *p;
222 {
223 
224 	return (EOPNOTSUPP);
225 }
226 
227 kernfs_statfs(mp, sbp, p)
228 	struct mount *mp;
229 	struct statfs *sbp;
230 	struct proc *p;
231 {
232 
233 #ifdef KERNFS_DIAGNOSTIC
234 	printf("kernfs_statfs(mp = %x)\n", mp);
235 #endif
236 
237 #ifdef COMPAT_09
238 	sbp->f_type = 7;
239 #else
240 	sbp->f_type = 0;
241 #endif
242 	sbp->f_flags = 0;
243 	sbp->f_bsize = DEV_BSIZE;
244 	sbp->f_iosize = DEV_BSIZE;
245 	sbp->f_blocks = 2;		/* 1K to keep df happy */
246 	sbp->f_bfree = 0;
247 	sbp->f_bavail = 0;
248 	sbp->f_files = 0;
249 	sbp->f_ffree = 0;
250 	if (sbp != &mp->mnt_stat) {
251 		bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
252 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
253 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
254 	}
255 	strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN);
256 	sbp->f_fstypename[MFSNAMELEN] = '\0';
257 	return (0);
258 }
259 
260 kernfs_sync(mp, waitfor)
261 	struct mount *mp;
262 	int waitfor;
263 {
264 
265 	return (0);
266 }
267 
268 /*
269  * Kernfs flat namespace lookup.
270  * Currently unsupported.
271  */
272 kernfs_vget(mp, ino, vpp)
273 	struct mount *mp;
274 	ino_t ino;
275 	struct vnode **vpp;
276 {
277 
278 	return (EOPNOTSUPP);
279 }
280 
281 
282 kernfs_fhtovp(mp, fhp, setgen, vpp)
283 	struct mount *mp;
284 	struct fid *fhp;
285 	int setgen;
286 	struct vnode **vpp;
287 {
288 
289 	return (EOPNOTSUPP);
290 }
291 
292 kernfs_vptofh(vp, fhp)
293 	struct vnode *vp;
294 	struct fid *fhp;
295 {
296 
297 	return (EOPNOTSUPP);
298 }
299 
300 struct vfsops kernfs_vfsops = {
301 	MOUNT_KERNFS,
302 	kernfs_mount,
303 	kernfs_start,
304 	kernfs_unmount,
305 	kernfs_root,
306 	kernfs_quotactl,
307 	kernfs_statfs,
308 	kernfs_sync,
309 	kernfs_vget,
310 	kernfs_fhtovp,
311 	kernfs_vptofh,
312 	kernfs_init,
313 };
314