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