procfs_vfsops.c revision 1.45 1 /* $NetBSD: procfs_vfsops.c,v 1.45 2003/04/16 21:44:24 christos Exp $ */
2
3 /*
4 * Copyright (c) 1993 Jan-Simon Pendry
5 * Copyright (c) 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95
40 */
41
42 /*
43 * procfs VFS interface
44 */
45
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.45 2003/04/16 21:44:24 christos Exp $");
48
49 #if defined(_KERNEL_OPT)
50 #include "opt_compat_netbsd.h"
51 #endif
52
53 #include <sys/param.h>
54 #include <sys/time.h>
55 #include <sys/kernel.h>
56 #include <sys/systm.h>
57 #include <sys/proc.h>
58 #include <sys/buf.h>
59 #include <sys/syslog.h>
60 #include <sys/mount.h>
61 #include <sys/signalvar.h>
62 #include <sys/vnode.h>
63 #include <sys/malloc.h>
64
65 #include <miscfs/procfs/procfs.h>
66
67 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */
68
69 void procfs_init __P((void));
70 void procfs_reinit __P((void));
71 void procfs_done __P((void));
72 int procfs_mount __P((struct mount *, const char *, void *,
73 struct nameidata *, struct proc *));
74 int procfs_start __P((struct mount *, int, struct proc *));
75 int procfs_unmount __P((struct mount *, int, struct proc *));
76 int procfs_quotactl __P((struct mount *, int, uid_t, caddr_t,
77 struct proc *));
78 int procfs_statfs __P((struct mount *, struct statfs *, struct proc *));
79 int procfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
80 int procfs_vget __P((struct mount *, ino_t, struct vnode **));
81 int procfs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
82 int procfs_checkexp __P((struct mount *, struct mbuf *, int *,
83 struct ucred **));
84 int procfs_vptofh __P((struct vnode *, struct fid *));
85 int procfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
86 struct proc *));
87 /*
88 * VFS Operations.
89 *
90 * mount system call
91 */
92 /* ARGSUSED */
93 int
94 procfs_mount(mp, path, data, ndp, p)
95 struct mount *mp;
96 const char *path;
97 void *data;
98 struct nameidata *ndp;
99 struct proc *p;
100 {
101 struct procfsmount *pmnt;
102 struct procfs_args args;
103 int error;
104
105 if (UIO_MX & (UIO_MX-1)) {
106 log(LOG_ERR, "procfs: invalid directory entry size");
107 return (EINVAL);
108 }
109
110 if (mp->mnt_flag & MNT_GETARGS) {
111 pmnt = VFSTOPROC(mp);
112 if (pmnt == NULL)
113 return EIO;
114 args.version = PROCFS_ARGSVERSION;
115 args.flags = pmnt->pmnt_flags;
116 return copyout(&args, data, sizeof(args));
117 }
118
119 if (mp->mnt_flag & MNT_UPDATE)
120 return (EOPNOTSUPP);
121
122 if (data != NULL) {
123 error = copyin(data, &args, sizeof args);
124 if (error != 0)
125 return error;
126
127 if (args.version != PROCFS_ARGSVERSION)
128 return EINVAL;
129 } else
130 args.flags = 0;
131
132 mp->mnt_flag |= MNT_LOCAL;
133 pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount),
134 M_UFSMNT, M_WAITOK); /* XXX need new malloc type */
135
136 mp->mnt_data = pmnt;
137 vfs_getnewfsid(mp);
138
139 error = set_statfs_info(path, UIO_USERSPACE, "procfs", UIO_SYSSPACE,
140 mp, p);
141 pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp);
142 pmnt->pmnt_flags = args.flags;
143
144 return error;
145 }
146
147 /*
148 * unmount system call
149 */
150 int
151 procfs_unmount(mp, mntflags, p)
152 struct mount *mp;
153 int mntflags;
154 struct proc *p;
155 {
156 int error;
157 int flags = 0;
158
159 if (mntflags & MNT_FORCE)
160 flags |= FORCECLOSE;
161
162 if ((error = vflush(mp, 0, flags)) != 0)
163 return (error);
164
165 exechook_disestablish(VFSTOPROC(mp)->pmnt_exechook);
166
167 free(mp->mnt_data, M_UFSMNT);
168 mp->mnt_data = 0;
169
170 return (0);
171 }
172
173 int
174 procfs_root(mp, vpp)
175 struct mount *mp;
176 struct vnode **vpp;
177 {
178
179 return (procfs_allocvp(mp, vpp, 0, Proot, -1));
180 }
181
182 /* ARGSUSED */
183 int
184 procfs_start(mp, flags, p)
185 struct mount *mp;
186 int flags;
187 struct proc *p;
188 {
189
190 return (0);
191 }
192
193 /*
194 * Get file system statistics.
195 */
196 int
197 procfs_statfs(mp, sbp, p)
198 struct mount *mp;
199 struct statfs *sbp;
200 struct proc *p;
201 {
202
203 sbp->f_bsize = PAGE_SIZE;
204 sbp->f_iosize = PAGE_SIZE;
205 sbp->f_blocks = 1; /* avoid divide by zero in some df's */
206 sbp->f_bfree = 0;
207 sbp->f_bavail = 0;
208 sbp->f_files = maxproc; /* approx */
209 sbp->f_ffree = maxproc - nprocs; /* approx */
210 #ifdef COMPAT_09
211 sbp->f_type = 10;
212 #else
213 sbp->f_type = 0;
214 #endif
215 copy_statfs_info(sbp, mp);
216 return (0);
217 }
218
219 /*ARGSUSED*/
220 int
221 procfs_quotactl(mp, cmds, uid, arg, p)
222 struct mount *mp;
223 int cmds;
224 uid_t uid;
225 caddr_t arg;
226 struct proc *p;
227 {
228
229 return (EOPNOTSUPP);
230 }
231
232 /*ARGSUSED*/
233 int
234 procfs_sync(mp, waitfor, uc, p)
235 struct mount *mp;
236 int waitfor;
237 struct ucred *uc;
238 struct proc *p;
239 {
240
241 return (0);
242 }
243
244 /*ARGSUSED*/
245 int
246 procfs_vget(mp, ino, vpp)
247 struct mount *mp;
248 ino_t ino;
249 struct vnode **vpp;
250 {
251 return (EOPNOTSUPP);
252 }
253
254 /*ARGSUSED*/
255 int
256 procfs_fhtovp(mp, fhp, vpp)
257 struct mount *mp;
258 struct fid *fhp;
259 struct vnode **vpp;
260 {
261
262 return (EINVAL);
263 }
264
265 /*ARGSUSED*/
266 int
267 procfs_checkexp(mp, mb, what, anon)
268 struct mount *mp;
269 struct mbuf *mb;
270 int *what;
271 struct ucred **anon;
272 {
273
274 return (EINVAL);
275 }
276
277 /*ARGSUSED*/
278 int
279 procfs_vptofh(vp, fhp)
280 struct vnode *vp;
281 struct fid *fhp;
282 {
283
284 return (EINVAL);
285 }
286
287 void
288 procfs_init()
289 {
290 procfs_hashinit();
291 }
292
293 void
294 procfs_reinit()
295 {
296 procfs_hashreinit();
297 }
298
299 void
300 procfs_done()
301 {
302 procfs_hashdone();
303 }
304
305 int
306 procfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
307 int *name;
308 u_int namelen;
309 void *oldp;
310 size_t *oldlenp;
311 void *newp;
312 size_t newlen;
313 struct proc *p;
314 {
315 return (EOPNOTSUPP);
316 }
317
318 extern const struct vnodeopv_desc procfs_vnodeop_opv_desc;
319
320 const struct vnodeopv_desc * const procfs_vnodeopv_descs[] = {
321 &procfs_vnodeop_opv_desc,
322 NULL,
323 };
324
325 struct vfsops procfs_vfsops = {
326 MOUNT_PROCFS,
327 procfs_mount,
328 procfs_start,
329 procfs_unmount,
330 procfs_root,
331 procfs_quotactl,
332 procfs_statfs,
333 procfs_sync,
334 procfs_vget,
335 procfs_fhtovp,
336 procfs_vptofh,
337 procfs_init,
338 procfs_reinit,
339 procfs_done,
340 procfs_sysctl,
341 NULL, /* vfs_mountroot */
342 procfs_checkexp,
343 procfs_vnodeopv_descs,
344 };
345