]> git.saurik.com Git - apple/xnu.git/blame - bsd/miscfs/fdesc/fdesc_vfsops.c
xnu-792.13.8.tar.gz
[apple/xnu.git] / bsd / miscfs / fdesc / fdesc_vfsops.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
8ad349bb 4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
1c79356b 5 *
8ad349bb
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
1c79356b
A
29 */
30/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
31/*
32 * Copyright (c) 1992, 1993, 1995
33 * The Regents of the University of California. All rights reserved.
34 *
35 * This code is derived from software donated to Berkeley by
36 * Jan-Simon Pendry.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * @(#)fdesc_vfsops.c 8.10 (Berkeley) 5/14/95
67 *
68 */
69
70/*
71 * /dev/fd Filesystem
72 */
73
74#include <sys/param.h>
75#include <sys/systm.h>
76#include <sys/time.h>
77#include <sys/types.h>
91447636 78#include <sys/proc_internal.h>
1c79356b
A
79#include <sys/resourcevar.h>
80#include <sys/filedesc.h>
81#include <sys/vnode.h>
91447636 82#include <sys/mount_internal.h>
1c79356b
A
83#include <sys/namei.h>
84#include <sys/malloc.h>
85#include <miscfs/fdesc/fdesc.h>
86
87/*
88 * Mount the per-process file descriptors (/dev/fd)
89 */
90int
91447636 91fdesc_mount(struct mount *mp, vnode_t devvp, __unused user_addr_t data, vfs_context_t context)
1c79356b
A
92{
93 int error = 0;
1c79356b
A
94 struct fdescmount *fmp;
95 struct vnode *rvp;
96
97 /*
98 * Update is a no-op
99 */
100 if (mp->mnt_flag & MNT_UPDATE)
91447636 101 return (ENOTSUP);
1c79356b 102
91447636 103 error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, VDIR);
1c79356b
A
104 if (error)
105 return (error);
106
107 MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount),
108 M_UFSMNT, M_WAITOK); /* XXX */
91447636
A
109
110 vnode_setnoflush(rvp);
111 vnode_ref(rvp);
112 vnode_put(rvp);
113
1c79356b
A
114 fmp->f_root = rvp;
115 /* XXX -- don't mark as local to work around fts() problems */
116 /*mp->mnt_flag |= MNT_LOCAL;*/
117 mp->mnt_data = (qaddr_t) fmp;
118 vfs_getnewfsid(mp);
119
91447636
A
120 bzero(mp->mnt_vfsstat.f_mntfromname, MAXPATHLEN);
121 bcopy("fdesc", mp->mnt_vfsstat.f_mntfromname, sizeof("fdesc"));
1c79356b
A
122 return (0);
123}
124
125int
91447636 126fdesc_start(mp, flags, context)
1c79356b
A
127 struct mount *mp;
128 int flags;
91447636 129 vfs_context_t context;
1c79356b
A
130{
131 return (0);
132}
133
134int
91447636 135fdesc_unmount(mp, mntflags, context)
1c79356b
A
136 struct mount *mp;
137 int mntflags;
91447636 138 vfs_context_t context;
1c79356b
A
139{
140 int error;
141 int flags = 0;
9bccf70c 142 int force = 0;
91447636 143 struct vnode *rvp = VFSTOFDESC(mp)->f_root;
1c79356b 144
9bccf70c 145 if (mntflags & MNT_FORCE) {
1c79356b 146 flags |= FORCECLOSE;
9bccf70c
A
147 force = 1;
148 }
1c79356b 149
91447636 150 if ( vnode_isinuse(rvp, 1) && !force )
1c79356b 151 return (EBUSY);
91447636 152 if ( (error = vflush(mp, rvp, flags|SKIPSYSTEM)) && !force )
1c79356b
A
153 return (error);
154
155 /*
91447636 156 * And mark for recycle after we drop its reference; it away for future re-use
1c79356b 157 */
91447636 158 vnode_recycle(rvp);
1c79356b 159 /*
91447636 160 * Release reference on underlying root vnode
1c79356b 161 */
91447636 162 vnode_rele(rvp);
1c79356b
A
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
172int
91447636 173fdesc_root(mp, vpp, context)
1c79356b
A
174 struct mount *mp;
175 struct vnode **vpp;
91447636 176 vfs_context_t context;
1c79356b 177{
1c79356b
A
178 struct vnode *vp;
179
180 /*
181 * Return locked reference to root.
182 */
183 vp = VFSTOFDESC(mp)->f_root;
91447636 184 vnode_get(vp);
1c79356b
A
185 *vpp = vp;
186 return (0);
187}
188
189int
91447636 190fdesc_statfs(mp, sbp, context)
1c79356b 191 struct mount *mp;
91447636
A
192 struct vfsstatfs *sbp;
193 vfs_context_t context;
1c79356b 194{
91447636 195 struct proc *p = vfs_context_proc(context);
1c79356b
A
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;
91447636 227 sbp->f_blocks = (uint64_t)2; /* 1K to keep df happy */
1c79356b
A
228 sbp->f_bfree = 0;
229 sbp->f_bavail = 0;
91447636
A
230 sbp->f_files = (uint64_t)((unsigned long)(lim + 1)); /* Allow for "." */
231 sbp->f_ffree = (uint64_t)((unsigned long)freefd); /* See comments above */
232
1c79356b
A
233 return (0);
234}
235
91447636
A
236static int
237fdesc_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t context)
238{
239 VFSATTR_RETURN(fsap, f_bsize, DEV_BSIZE);
240 VFSATTR_RETURN(fsap, f_iosize, DEV_BSIZE);
241 VFSATTR_RETURN(fsap, f_blocks, 2);
242 VFSATTR_RETURN(fsap, f_bfree, 0);
243 VFSATTR_RETURN(fsap, f_bavail, 0);
244 VFSATTR_RETURN(fsap, f_fssubtype, 0);
245
246 if (VFSATTR_IS_ACTIVE(fsap, f_objcount) ||
247 VFSATTR_IS_ACTIVE(fsap, f_maxobjcount) ||
248 VFSATTR_IS_ACTIVE(fsap, f_files) ||
249 VFSATTR_IS_ACTIVE(fsap, f_ffree))
250 {
251 struct proc *p = vfs_context_proc(context);
252 struct filedesc *fdp;
253 int lim;
254 int i;
255 int last;
256 int freefd;
257
258 /*
259 * Compute number of free file descriptors.
260 * [ Strange results will ensue if the open file
261 * limit is ever reduced below the current number
262 * of open files... ]
263 */
264 lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
265 fdp = p->p_fd;
266 last = min(fdp->fd_nfiles, lim);
267 freefd = 0;
268 for (i = fdp->fd_freefile; i < last; i++)
269 if (fdp->fd_ofiles[i] == NULL &&
270 !(fdp->fd_ofileflags[i] & UF_RESERVED))
271 freefd++;
272
273 /*
274 * Adjust for the fact that the fdesc array may not
275 * have been fully allocated yet.
276 */
277 if (fdp->fd_nfiles < lim)
278 freefd += (lim - fdp->fd_nfiles);
279
280 VFSATTR_RETURN(fsap, f_objcount, lim+1);
281 VFSATTR_RETURN(fsap, f_maxobjcount, lim+1);
282 VFSATTR_RETURN(fsap, f_files, lim+1);
283 VFSATTR_RETURN(fsap, f_ffree, freefd);
284 }
285
286 return 0;
287}
288
1c79356b 289int
91447636 290fdesc_sync(mp, waitfor, context)
1c79356b
A
291 struct mount *mp;
292 int waitfor;
91447636 293 vfs_context_t context;
1c79356b
A
294{
295
296 return (0);
297}
298
91447636
A
299#define fdesc_fhtovp (int (*) (mount_t, int, unsigned char *, vnode_t *, vfs_context_t))eopnotsupp
300#define fdesc_sysctl (int (*) (int *, u_int, user_addr_t, size_t *, user_addr_t, size_t, vfs_context_t))eopnotsupp
301#define fdesc_vget (int (*) (mount_t, ino64_t, vnode_t *, vfs_context_t))eopnotsupp
302#define fdesc_vptofh (int (*) (vnode_t, int *, unsigned char *, vfs_context_t))eopnotsupp
1c79356b
A
303
304struct vfsops fdesc_vfsops = {
305 fdesc_mount,
306 fdesc_start,
307 fdesc_unmount,
308 fdesc_root,
91447636
A
309 NULL, /* quotactl */
310 fdesc_vfs_getattr,
1c79356b
A
311 fdesc_sync,
312 fdesc_vget,
313 fdesc_fhtovp,
314 fdesc_vptofh,
315 fdesc_init,
91447636 316 fdesc_sysctl
1c79356b 317};