X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..2d21ac55c334faf3a56e5634905ed6987fc787d4:/bsd/miscfs/fdesc/fdesc_vfsops.c diff --git a/bsd/miscfs/fdesc/fdesc_vfsops.c b/bsd/miscfs/fdesc/fdesc_vfsops.c index 47e969141..9d419783c 100644 --- a/bsd/miscfs/fdesc/fdesc_vfsops.c +++ b/bsd/miscfs/fdesc/fdesc_vfsops.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ /* @@ -61,20 +64,19 @@ * @(#)fdesc_vfsops.c 8.10 (Berkeley) 5/14/95 * */ - /* - * /dev/fd Filesystem +* /dev/fd Filesystem */ #include #include #include #include -#include +#include #include #include #include -#include +#include #include #include #include @@ -82,16 +84,10 @@ /* * Mount the per-process file descriptors (/dev/fd) */ -int -fdesc_mount(mp, path, data, ndp, p) - struct mount *mp; - char *path; - caddr_t data; - struct nameidata *ndp; - struct proc *p; +static int +fdesc_mount(struct mount *mp, __unused vnode_t devvp, __unused user_addr_t data, __unused vfs_context_t context) { int error = 0; - size_t size; struct fdescmount *fmp; struct vnode *rvp; @@ -99,100 +95,93 @@ fdesc_mount(mp, path, data, ndp, p) * Update is a no-op */ if (mp->mnt_flag & MNT_UPDATE) - return (EOPNOTSUPP); + return (ENOTSUP); - error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); + error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, VDIR); if (error) return (error); MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), M_UFSMNT, M_WAITOK); /* XXX */ - rvp->v_type = VDIR; - rvp->v_flag |= VROOT; + + vnode_setnoflush(rvp); + vnode_ref(rvp); + vnode_put(rvp); + fmp->f_root = rvp; /* XXX -- don't mark as local to work around fts() problems */ /*mp->mnt_flag |= MNT_LOCAL;*/ mp->mnt_data = (qaddr_t) fmp; vfs_getnewfsid(mp); - (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); - bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); - bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); - bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); + bzero(mp->mnt_vfsstat.f_mntfromname, MAXPATHLEN); + bcopy("fdesc", mp->mnt_vfsstat.f_mntfromname, sizeof("fdesc")); return (0); } -int -fdesc_start(mp, flags, p) - struct mount *mp; - int flags; - struct proc *p; +static int +fdesc_start(__unused struct mount *mp, __unused int flags, __unused vfs_context_t context) { return (0); } -int -fdesc_unmount(mp, mntflags, p) - struct mount *mp; - int mntflags; - struct proc *p; +static int +fdesc_unmount(struct mount *mp, int mntflags, __unused vfs_context_t context) { int error; int flags = 0; int force = 0; - struct vnode *rootvp = VFSTOFDESC(mp)->f_root; + struct vnode *rvp = VFSTOFDESC(mp)->f_root; if (mntflags & MNT_FORCE) { flags |= FORCECLOSE; force = 1; } - if ( (rootvp->v_usecount > 1) && !force ) + if ( vnode_isinuse(rvp, 1) && !force ) return (EBUSY); - if ( (error = vflush(mp, rootvp, flags)) && !force ) + if ( (error = vflush(mp, rvp, flags|SKIPSYSTEM)) && !force ) return (error); /* - * Release reference on underlying root vnode + * And mark for recycle after we drop its reference; it away for future re-use */ - vrele(rootvp); + vnode_recycle(rvp); /* - * And blow it away for future re-use + * Release reference on underlying root vnode */ - vgone(rootvp); + vnode_rele(rvp); /* * Finally, throw away the fdescmount structure */ _FREE(mp->mnt_data, M_UFSMNT); /* XXX */ - mp->mnt_data = 0; + mp->mnt_data = NULL; return (0); } int -fdesc_root(mp, vpp) - struct mount *mp; - struct vnode **vpp; +fdesc_root(struct mount *mp, struct vnode **vpp, __unused vfs_context_t context) { - struct proc *p = current_proc(); /* XXX */ struct vnode *vp; /* * Return locked reference to root. */ vp = VFSTOFDESC(mp)->f_root; - VREF(vp); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + vnode_get(vp); *vpp = vp; return (0); } +#if 0 +/* + * XXX commented out in mount.h + */ int -fdesc_statfs(mp, sbp, p) - struct mount *mp; - struct statfs *sbp; - struct proc *p; +fdesc_statfs(__unused struct mount *mp, struct vfsstatfs *sbp, vfs_context_t context) { + proc_t p = vfs_context_proc(context); struct filedesc *fdp; int lim; int i; @@ -224,50 +213,95 @@ fdesc_statfs(mp, sbp, p) sbp->f_flags = 0; sbp->f_bsize = DEV_BSIZE; sbp->f_iosize = DEV_BSIZE; - sbp->f_blocks = 2; /* 1K to keep df happy */ + sbp->f_blocks = (uint64_t)2; /* 1K to keep df happy */ sbp->f_bfree = 0; sbp->f_bavail = 0; - sbp->f_files = lim + 1; /* Allow for "." */ - sbp->f_ffree = freefd; /* See comments above */ - if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; - bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - } + sbp->f_files = (uint64_t)((unsigned long)(lim + 1)); /* Allow for "." */ + sbp->f_ffree = (uint64_t)((unsigned long)freefd); /* See comments above */ + return (0); } +#endif /* 0 */ -int -fdesc_sync(mp, waitfor) - struct mount *mp; - int waitfor; +static int +fdesc_vfs_getattr(__unused mount_t mp, struct vfs_attr *fsap, vfs_context_t context) +{ + VFSATTR_RETURN(fsap, f_bsize, DEV_BSIZE); + VFSATTR_RETURN(fsap, f_iosize, DEV_BSIZE); + VFSATTR_RETURN(fsap, f_blocks, 2); + VFSATTR_RETURN(fsap, f_bfree, 0); + VFSATTR_RETURN(fsap, f_bavail, 0); + VFSATTR_RETURN(fsap, f_fssubtype, 0); + + if (VFSATTR_IS_ACTIVE(fsap, f_objcount) || + VFSATTR_IS_ACTIVE(fsap, f_maxobjcount) || + VFSATTR_IS_ACTIVE(fsap, f_files) || + VFSATTR_IS_ACTIVE(fsap, f_ffree)) + { + proc_t p = vfs_context_proc(context); + struct filedesc *fdp; + int lim; + int i; + int last; + int freefd; + + /* + * Compute number of free file descriptors. + * [ Strange results will ensue if the open file + * limit is ever reduced below the current number + * of open files... ] + */ + lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; + fdp = p->p_fd; + last = min(fdp->fd_nfiles, lim); + freefd = 0; + for (i = fdp->fd_freefile; i < last; i++) + if (fdp->fd_ofiles[i] == NULL && + !(fdp->fd_ofileflags[i] & UF_RESERVED)) + freefd++; + + /* + * Adjust for the fact that the fdesc array may not + * have been fully allocated yet. + */ + if (fdp->fd_nfiles < lim) + freefd += (lim - fdp->fd_nfiles); + + VFSATTR_RETURN(fsap, f_objcount, lim+1); + VFSATTR_RETURN(fsap, f_maxobjcount, lim+1); + VFSATTR_RETURN(fsap, f_files, lim+1); + VFSATTR_RETURN(fsap, f_ffree, freefd); + } + + return 0; +} + +static int +fdesc_sync(__unused struct mount *mp, __unused int waitfor, __unused vfs_context_t context) { return (0); } -#define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \ - struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) -#define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ - struct proc *)))eopnotsupp) -#define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ - size_t, struct proc *)))eopnotsupp) -#define fdesc_vget ((int (*) __P((struct mount *, void *, struct vnode **))) \ - eopnotsupp) -#define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) +#define fdesc_fhtovp (int (*) (mount_t, int, unsigned char *, vnode_t *, vfs_context_t))eopnotsupp +#define fdesc_sysctl (int (*) (int *, u_int, user_addr_t, size_t *, user_addr_t, size_t, vfs_context_t))eopnotsupp +#define fdesc_vget (int (*) (mount_t, ino64_t, vnode_t *, vfs_context_t))eopnotsupp +#define fdesc_vptofh (int (*) (vnode_t, int *, unsigned char *, vfs_context_t))eopnotsupp struct vfsops fdesc_vfsops = { fdesc_mount, fdesc_start, fdesc_unmount, fdesc_root, - fdesc_quotactl, - fdesc_statfs, + NULL, /* quotactl */ + fdesc_vfs_getattr, +/* fdesc_statfs, XXX commented out in mount.h */ fdesc_sync, fdesc_vget, fdesc_fhtovp, fdesc_vptofh, fdesc_init, fdesc_sysctl, + NULL, + {NULL} };