fdesc_vfsops.c revision 1.26 1 /* $NetBSD: fdesc_vfsops.c,v 1.26 1998/08/09 20:51:08 perry Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software donated to Berkeley by
8 * Jan-Simon Pendry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)fdesc_vfsops.c 8.10 (Berkeley) 5/14/95
39 *
40 * #Id: fdesc_vfsops.c,v 1.9 1993/04/06 15:28:33 jsp Exp #
41 */
42
43 /*
44 * /dev/fd Filesystem
45 */
46
47 #if defined(_KERNEL) && !defined(_LKM)
48 #include "opt_compat_netbsd.h"
49 #endif
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/time.h>
54 #include <sys/types.h>
55 #include <sys/proc.h>
56 #include <sys/resourcevar.h>
57 #include <sys/filedesc.h>
58 #include <sys/vnode.h>
59 #include <sys/mount.h>
60 #include <sys/namei.h>
61 #include <sys/malloc.h>
62 #include <miscfs/fdesc/fdesc.h>
63
64 int fdesc_mount __P((struct mount *, const char *, void *,
65 struct nameidata *, struct proc *));
66 int fdesc_start __P((struct mount *, int, struct proc *));
67 int fdesc_unmount __P((struct mount *, int, struct proc *));
68 int fdesc_root __P((struct mount *, struct vnode **));
69 int fdesc_quotactl __P((struct mount *, int, uid_t, caddr_t,
70 struct proc *));
71 int fdesc_statfs __P((struct mount *, struct statfs *, struct proc *));
72 int fdesc_sync __P((struct mount *, int, struct ucred *, struct proc *));
73 int fdesc_vget __P((struct mount *, ino_t, struct vnode **));
74 int fdesc_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
75 struct vnode **, int *, struct ucred **));
76 int fdesc_vptofh __P((struct vnode *, struct fid *));
77 int fdesc_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
78 struct proc *));
79
80 /*
81 * Mount the per-process file descriptors (/dev/fd)
82 */
83 int
84 fdesc_mount(mp, path, data, ndp, p)
85 struct mount *mp;
86 const char *path;
87 void *data;
88 struct nameidata *ndp;
89 struct proc *p;
90 {
91 int error = 0;
92 size_t size;
93 struct fdescmount *fmp;
94 struct vnode *rvp;
95
96 /*
97 * Update is a no-op
98 */
99 if (mp->mnt_flag & MNT_UPDATE)
100 return (EOPNOTSUPP);
101
102 error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp);
103 if (error)
104 return (error);
105
106 MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount),
107 M_UFSMNT, M_WAITOK); /* XXX */
108 rvp->v_type = VDIR;
109 rvp->v_flag |= VROOT;
110 fmp->f_root = rvp;
111 mp->mnt_flag |= MNT_LOCAL;
112 mp->mnt_data = (qaddr_t)fmp;
113 vfs_getnewfsid(mp, MOUNT_FDESC);
114
115 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
116 memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
117 memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
118 memcpy(mp->mnt_stat.f_mntfromname, "fdesc", sizeof("fdesc"));
119 return (0);
120 }
121
122 int
123 fdesc_start(mp, flags, p)
124 struct mount *mp;
125 int flags;
126 struct proc *p;
127 {
128 return (0);
129 }
130
131 int
132 fdesc_unmount(mp, mntflags, p)
133 struct mount *mp;
134 int mntflags;
135 struct proc *p;
136 {
137 int error;
138 int flags = 0;
139 struct vnode *rootvp = VFSTOFDESC(mp)->f_root;
140
141 if (mntflags & MNT_FORCE)
142 flags |= FORCECLOSE;
143
144 /*
145 * Clear out buffer cache. I don't think we
146 * ever get anything cached at this level at the
147 * moment, but who knows...
148 */
149 if (rootvp->v_usecount > 1)
150 return (EBUSY);
151 if ((error = vflush(mp, rootvp, flags)) != 0)
152 return (error);
153
154 /*
155 * Release reference on underlying root vnode
156 */
157 vrele(rootvp);
158 /*
159 * And blow it away for future re-use
160 */
161 vgone(rootvp);
162 /*
163 * Finally, throw away the fdescmount structure
164 */
165 free(mp->mnt_data, M_UFSMNT); /* XXX */
166 mp->mnt_data = 0;
167
168 return (0);
169 }
170
171 int
172 fdesc_root(mp, vpp)
173 struct mount *mp;
174 struct vnode **vpp;
175 {
176 struct vnode *vp;
177
178 /*
179 * Return locked reference to root.
180 */
181 vp = VFSTOFDESC(mp)->f_root;
182 VREF(vp);
183 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
184 *vpp = vp;
185 return (0);
186 }
187
188 int
189 fdesc_quotactl(mp, cmd, uid, arg, p)
190 struct mount *mp;
191 int cmd;
192 uid_t uid;
193 caddr_t arg;
194 struct proc *p;
195 {
196
197 return (EOPNOTSUPP);
198 }
199
200 int
201 fdesc_statfs(mp, sbp, p)
202 struct mount *mp;
203 struct statfs *sbp;
204 struct proc *p;
205 {
206 struct filedesc *fdp;
207 int lim;
208 int i;
209 int last;
210 int freefd;
211
212 /*
213 * Compute number of free file descriptors.
214 * [ Strange results will ensue if the open file
215 * limit is ever reduced below the current number
216 * of open files... ]
217 */
218 lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
219 fdp = p->p_fd;
220 last = min(fdp->fd_nfiles, lim);
221 freefd = 0;
222 for (i = fdp->fd_freefile; i < last; i++)
223 if (fdp->fd_ofiles[i] == NULL)
224 freefd++;
225
226 /*
227 * Adjust for the fact that the fdesc array may not
228 * have been fully allocated yet.
229 */
230 if (fdp->fd_nfiles < lim)
231 freefd += (lim - fdp->fd_nfiles);
232
233 sbp->f_bsize = DEV_BSIZE;
234 sbp->f_iosize = DEV_BSIZE;
235 sbp->f_blocks = 2; /* 1K to keep df happy */
236 sbp->f_bfree = 0;
237 sbp->f_bavail = 0;
238 sbp->f_files = lim + 1; /* Allow for "." */
239 sbp->f_ffree = freefd; /* See comments above */
240 #ifdef COMPAT_09
241 sbp->f_type = 6;
242 #else
243 sbp->f_type = 0;
244 #endif
245 if (sbp != &mp->mnt_stat) {
246 memcpy(&sbp->f_fsid, &mp->mnt_stat.f_fsid, sizeof(sbp->f_fsid));
247 memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN);
248 memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN);
249 }
250 strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
251 return (0);
252 }
253
254 /*ARGSUSED*/
255 int
256 fdesc_sync(mp, waitfor, uc, p)
257 struct mount *mp;
258 int waitfor;
259 struct ucred *uc;
260 struct proc *p;
261 {
262
263 return (0);
264 }
265
266 /*
267 * Fdesc flat namespace lookup.
268 * Currently unsupported.
269 */
270 int
271 fdesc_vget(mp, ino, vpp)
272 struct mount *mp;
273 ino_t ino;
274 struct vnode **vpp;
275 {
276
277 return (EOPNOTSUPP);
278 }
279
280
281 /*ARGSUSED*/
282 int
283 fdesc_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
284 struct mount *mp;
285 struct fid *fhp;
286 struct mbuf *nam;
287 struct vnode **vpp;
288 int *exflagsp;
289 struct ucred **credanonp;
290 {
291
292 return (EOPNOTSUPP);
293 }
294
295 /*ARGSUSED*/
296 int
297 fdesc_vptofh(vp, fhp)
298 struct vnode *vp;
299 struct fid *fhp;
300 {
301 return (EOPNOTSUPP);
302 }
303
304 int
305 fdesc_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
306 int *name;
307 u_int namelen;
308 void *oldp;
309 size_t *oldlenp;
310 void *newp;
311 size_t newlen;
312 struct proc *p;
313 {
314 return (EOPNOTSUPP);
315 }
316
317 extern struct vnodeopv_desc fdesc_vnodeop_opv_desc;
318
319 struct vnodeopv_desc *fdesc_vnodeopv_descs[] = {
320 &fdesc_vnodeop_opv_desc,
321 NULL,
322 };
323
324 struct vfsops fdesc_vfsops = {
325 MOUNT_FDESC,
326 fdesc_mount,
327 fdesc_start,
328 fdesc_unmount,
329 fdesc_root,
330 fdesc_quotactl,
331 fdesc_statfs,
332 fdesc_sync,
333 fdesc_vget,
334 fdesc_fhtovp,
335 fdesc_vptofh,
336 fdesc_init,
337 fdesc_sysctl,
338 NULL, /* vfs_mountroot */
339 fdesc_vnodeopv_descs,
340 };
341