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