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