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