kernfs_vfsops.c revision 1.10 1 /*
2 * Copyright (c) 1990, 1992 Jan-Simon Pendry
3 * All rights reserved.
4 *
5 * This code is derived from software contributed 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 * $Id: kernfs_vfsops.c,v 1.10 1993/12/20 12:39:10 cgd Exp $
37 */
38
39 /*
40 * Kernel params Filesystem
41 */
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/time.h>
46 #include <sys/types.h>
47 #include <sys/proc.h>
48 #include <sys/vnode.h>
49 #include <sys/mount.h>
50 #include <sys/namei.h>
51 #include <sys/malloc.h>
52 #include <sys/conf.h>
53
54 #include <miscfs/kernfs/kernfs.h>
55
56 /* bring in the spec vnodeops for cdevvp */
57 extern struct vnodeops spec_vnodeops;
58
59 struct vnode *rrootdevvp;
60
61 kernfs_init()
62 {
63 #ifdef KERNFS_DIAGNOSTIC
64 printf("kernfs_init\n"); /* printed during system boot */
65 #endif
66
67 /* DO NOTHING */
68 }
69
70 kernfs_rrootdevvp_init()
71 {
72 int error, bmaj, cmaj;
73
74 if (rrootdevvp != NULL) /* then we've already done this */
75 return;
76
77 error = ENXIO;
78 bmaj = major(rootdev);
79
80 /* hunt for the raw root device by looking in cdevsw for a matching
81 * open routine...
82 */
83 for (cmaj = 0; cmaj < nchrdev; cmaj++) {
84 if (cdevsw[cmaj].d_open == bdevsw[bmaj].d_open) {
85 dev_t cdev = makedev(cmaj, minor(rootdev));
86 error = cdevvp(cdev, &rrootdevvp);
87 if (!error)
88 return;
89 }
90 }
91
92 /* this isn't fatal... */
93 if (error) {
94 printf("kernfs: no raw root device\n");
95 rrootdevvp = NULL;
96 }
97 }
98
99 /*
100 * Mount the kernel parameter filesystem
101 */
102 kernfs_mount(mp, path, data, ndp, p)
103 struct mount *mp;
104 char *path;
105 caddr_t data;
106 struct nameidata *ndp;
107 struct proc *p;
108 {
109 int error = 0;
110 u_int size;
111 struct kernfs_mount *fmp;
112 struct vnode *rvp;
113
114 #ifdef KERNFS_DIAGNOSTIC
115 printf("kernfs_mount(mp = %x)\n", mp);
116 #endif
117
118 /*
119 * Update is a no-op
120 */
121 if (mp->mnt_flag & MNT_UPDATE)
122 return (EOPNOTSUPP);
123
124 error = getnewvnode(VT_KERNFS, mp, &kernfs_vnodeops, &rvp);
125 if (error)
126 return (error);
127
128 fmp = (struct kernfs_mount *) malloc(sizeof(struct kernfs_mount),
129 M_MISCFSMNT, M_WAITOK);
130 rvp->v_type = VDIR;
131 rvp->v_flag |= VROOT;
132 VTOKERN(rvp)->kf_kt = &kernfs_targets[KERNFS_TARGET_ROOT];
133 #ifdef KERNFS_DIAGNOSTIC
134 printf("kernfs_mount: root vp = %x\n", rvp);
135 #endif
136 fmp->kf_root = rvp;
137 mp->mnt_flag |= MNT_LOCAL;
138 mp->mnt_data = (qaddr_t) fmp;
139 getnewfsid(mp, MOUNT_KERNFS);
140
141 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
142 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
143 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
144 bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
145 #ifdef KERNFS_DIAGNOSTIC
146 printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
147 #endif
148
149 kernfs_rrootdevvp_init();
150
151 return (0);
152 }
153
154 kernfs_start(mp, flags, p)
155 struct mount *mp;
156 int flags;
157 struct proc *p;
158 {
159 return (0);
160 }
161
162 kernfs_unmount(mp, mntflags, p)
163 struct mount *mp;
164 int mntflags;
165 struct proc *p;
166 {
167 int error;
168 int flags = 0;
169 extern int doforce;
170 struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
171
172 #ifdef KERNFS_DIAGNOSTIC
173 printf("kernfs_unmount(mp = %x)\n", mp);
174 #endif
175
176 if (mntflags & MNT_FORCE) {
177 /* kernfs can never be rootfs so don't check for it */
178 if (!doforce)
179 return (EINVAL);
180 flags |= FORCECLOSE;
181 }
182
183 /*
184 * Clear out buffer cache. I don't think we
185 * ever get anything cached at this level at the
186 * moment, but who knows...
187 */
188 #ifdef KERNFS_DIAGNOSTIC
189 printf("kernfs_unmount: calling mntflushbuf\n");
190 #endif
191 mntflushbuf(mp, 0);
192 #ifdef KERNFS_DIAGNOSTIC
193 printf("kernfs_unmount: calling mntinvalbuf\n");
194 #endif
195 if (mntinvalbuf(mp, 1))
196 return (EBUSY);
197 if (rootvp->v_usecount > 1)
198 return (EBUSY);
199 #ifdef KERNFS_DIAGNOSTIC
200 printf("kernfs_unmount: calling vflush\n");
201 #endif
202 if (error = vflush(mp, rootvp, flags))
203 return (error);
204
205 #ifdef KERNFS_DIAGNOSTIC
206 vprint("kernfs root", rootvp);
207 #endif
208 /*
209 * Release reference on underlying root vnode
210 */
211 vrele(rootvp);
212 /*
213 * And blow it away for future re-use
214 */
215 vgone(rootvp);
216 /*
217 * Finally, throw away the kernfs_mount structure
218 */
219 free(mp->mnt_data, M_MISCFSMNT);
220 mp->mnt_data = 0;
221 return 0;
222 }
223
224 kernfs_root(mp, vpp)
225 struct mount *mp;
226 struct vnode **vpp;
227 {
228 struct vnode *vp;
229 int error;
230
231 #ifdef KERNFS_DIAGNOSTIC
232 printf("kernfs_root(mp = %x)\n", mp);
233 #endif
234
235 /*
236 * Return locked reference to root.
237 */
238 vp = VFSTOKERNFS(mp)->kf_root;
239 VREF(vp);
240 VOP_LOCK(vp);
241 *vpp = vp;
242 return (0);
243 }
244
245 kernfs_quotactl(mp, cmd, uid, arg, p)
246 struct mount *mp;
247 int cmd;
248 uid_t uid;
249 caddr_t arg;
250 struct proc *p;
251 {
252 return (EOPNOTSUPP);
253 }
254
255 kernfs_statfs(mp, sbp, p)
256 struct mount *mp;
257 struct statfs *sbp;
258 struct proc *p;
259 {
260 struct filedesc *fdp;
261 int lim;
262 int i;
263 int last;
264 int freefd;
265
266 #ifdef KERNFS_DIAGNOSTIC
267 printf("kernfs_statfs(mp = %x)\n", mp);
268 #endif
269
270 sbp->f_type = MOUNT_KERNFS;
271 sbp->f_flags = 0;
272 sbp->f_fsize = DEV_BSIZE;
273 sbp->f_bsize = DEV_BSIZE;
274 sbp->f_blocks = 2; /* 1K to keep df happy */
275 sbp->f_bfree = 0;
276 sbp->f_bavail = 0;
277 sbp->f_files = 0; /* Allow for "." */
278 sbp->f_ffree = 0; /* See comments above */
279 if (sbp != &mp->mnt_stat) {
280 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
281 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
282 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
283 }
284 return (0);
285 }
286
287 kernfs_sync(mp, waitfor)
288 struct mount *mp;
289 int waitfor;
290 {
291 return (0);
292 }
293
294 kernfs_fhtovp(mp, fhp, vpp)
295 struct mount *mp;
296 struct fid *fhp;
297 struct vnode **vpp;
298 {
299 return (EOPNOTSUPP);
300 }
301
302 kernfs_vptofh(vp, fhp)
303 struct vnode *vp;
304 struct fid *fhp;
305 {
306 return (EOPNOTSUPP);
307 }
308
309 struct vfsops kernfs_vfsops = {
310 kernfs_mount,
311 kernfs_start,
312 kernfs_unmount,
313 kernfs_root,
314 kernfs_quotactl,
315 kernfs_statfs,
316 kernfs_sync,
317 kernfs_fhtovp,
318 kernfs_vptofh,
319 kernfs_init,
320 };
321