]> git.saurik.com Git - apple/xnu.git/blob - bsd/miscfs/fdesc/fdesc_vfsops.c
1d26b20e9735fc618d8539bb47719e4975617576
[apple/xnu.git] / bsd / miscfs / fdesc / fdesc_vfsops.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26 /*
27 * Copyright (c) 1992, 1993, 1995
28 * The Regents of the University of California. All rights reserved.
29 *
30 * This code is derived from software donated to Berkeley by
31 * Jan-Simon Pendry.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)fdesc_vfsops.c 8.10 (Berkeley) 5/14/95
62 *
63 */
64
65 /*
66 * /dev/fd Filesystem
67 */
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/time.h>
72 #include <sys/types.h>
73 #include <sys/proc.h>
74 #include <sys/resourcevar.h>
75 #include <sys/filedesc.h>
76 #include <sys/vnode.h>
77 #include <sys/mount.h>
78 #include <sys/namei.h>
79 #include <sys/malloc.h>
80 #include <miscfs/fdesc/fdesc.h>
81
82 /*
83 * Mount the per-process file descriptors (/dev/fd)
84 */
85 int
86 fdesc_mount(mp, path, data, ndp, p)
87 struct mount *mp;
88 char *path;
89 caddr_t data;
90 struct nameidata *ndp;
91 struct proc *p;
92 {
93 int error = 0;
94 u_int size;
95 struct fdescmount *fmp;
96 struct vnode *rvp;
97
98 /*
99 * Update is a no-op
100 */
101 if (mp->mnt_flag & MNT_UPDATE)
102 return (EOPNOTSUPP);
103
104 error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp);
105 if (error)
106 return (error);
107
108 MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount),
109 M_UFSMNT, M_WAITOK); /* XXX */
110 rvp->v_type = VDIR;
111 rvp->v_flag |= VROOT;
112 fmp->f_root = rvp;
113 /* XXX -- don't mark as local to work around fts() problems */
114 /*mp->mnt_flag |= MNT_LOCAL;*/
115 mp->mnt_data = (qaddr_t) fmp;
116 vfs_getnewfsid(mp);
117
118 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
119 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
120 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
121 bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc"));
122 return (0);
123 }
124
125 int
126 fdesc_start(mp, flags, p)
127 struct mount *mp;
128 int flags;
129 struct proc *p;
130 {
131 return (0);
132 }
133
134 int
135 fdesc_unmount(mp, mntflags, p)
136 struct mount *mp;
137 int mntflags;
138 struct proc *p;
139 {
140 int error;
141 int flags = 0;
142 int force = 0;
143 struct vnode *rootvp = VFSTOFDESC(mp)->f_root;
144
145 if (mntflags & MNT_FORCE) {
146 flags |= FORCECLOSE;
147 force = 1;
148 }
149
150 if ( (rootvp->v_usecount > 1) && !force )
151 return (EBUSY);
152 if ( (error = vflush(mp, rootvp, flags)) && !force )
153 return (error);
154
155 /*
156 * Release reference on underlying root vnode
157 */
158 vrele(rootvp);
159 /*
160 * And blow it away for future re-use
161 */
162 vgone(rootvp);
163 /*
164 * Finally, throw away the fdescmount structure
165 */
166 _FREE(mp->mnt_data, M_UFSMNT); /* XXX */
167 mp->mnt_data = 0;
168
169 return (0);
170 }
171
172 int
173 fdesc_root(mp, vpp)
174 struct mount *mp;
175 struct vnode **vpp;
176 {
177 struct proc *p = current_proc(); /* XXX */
178 struct vnode *vp;
179
180 /*
181 * Return locked reference to root.
182 */
183 vp = VFSTOFDESC(mp)->f_root;
184 VREF(vp);
185 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
186 *vpp = vp;
187 return (0);
188 }
189
190 int
191 fdesc_statfs(mp, sbp, p)
192 struct mount *mp;
193 struct statfs *sbp;
194 struct proc *p;
195 {
196 struct filedesc *fdp;
197 int lim;
198 int i;
199 int last;
200 int freefd;
201
202 /*
203 * Compute number of free file descriptors.
204 * [ Strange results will ensue if the open file
205 * limit is ever reduced below the current number
206 * of open files... ]
207 */
208 lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
209 fdp = p->p_fd;
210 last = min(fdp->fd_nfiles, lim);
211 freefd = 0;
212 for (i = fdp->fd_freefile; i < last; i++)
213 if (fdp->fd_ofiles[i] == NULL &&
214 !(fdp->fd_ofileflags[i] & UF_RESERVED))
215 freefd++;
216
217 /*
218 * Adjust for the fact that the fdesc array may not
219 * have been fully allocated yet.
220 */
221 if (fdp->fd_nfiles < lim)
222 freefd += (lim - fdp->fd_nfiles);
223
224 sbp->f_flags = 0;
225 sbp->f_bsize = DEV_BSIZE;
226 sbp->f_iosize = DEV_BSIZE;
227 sbp->f_blocks = 2; /* 1K to keep df happy */
228 sbp->f_bfree = 0;
229 sbp->f_bavail = 0;
230 sbp->f_files = lim + 1; /* Allow for "." */
231 sbp->f_ffree = freefd; /* See comments above */
232 if (sbp != &mp->mnt_stat) {
233 sbp->f_type = mp->mnt_vfc->vfc_typenum;
234 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
235 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
236 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
237 }
238 return (0);
239 }
240
241 int
242 fdesc_sync(mp, waitfor)
243 struct mount *mp;
244 int waitfor;
245 {
246
247 return (0);
248 }
249
250 #define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \
251 struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp)
252 #define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
253 struct proc *)))eopnotsupp)
254 #define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
255 size_t, struct proc *)))eopnotsupp)
256 #define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
257 eopnotsupp)
258 #define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp)
259
260 struct vfsops fdesc_vfsops = {
261 fdesc_mount,
262 fdesc_start,
263 fdesc_unmount,
264 fdesc_root,
265 fdesc_quotactl,
266 fdesc_statfs,
267 fdesc_sync,
268 fdesc_vget,
269 fdesc_fhtovp,
270 fdesc_vptofh,
271 fdesc_init,
272 fdesc_sysctl,
273 };