1 /* 2 * Copyright (c) 1990, 1992 Jan-Simon Pendry 3 * All rights reserved. 4 * 5 * This code is derived from software contributed 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 * $Id: fdesc_vfsops.c,v 1.4 1993/06/07 05:25:20 cgd Exp $ 37 */ 38 39 /* 40 * /dev/fd Filesystem 41 */ 42 43 #include "param.h" 44 #include "systm.h" 45 #include "time.h" 46 #include "types.h" 47 #include "proc.h" 48 #include "resourcevar.h" 49 #include "filedesc.h" 50 #include "vnode.h" 51 #include "mount.h" 52 #include "namei.h" 53 #include "malloc.h" 54 #include "miscfs/fdesc/fdesc.h" 55 56 static u_short fdesc_mntid; 57 58 fdesc_init() 59 { 60 #ifdef FDESC_DIAGNOSTIC 61 printf("fdesc_init\n"); /* printed during system boot */ 62 #endif 63 } 64 65 /* 66 * Mount the per-process file descriptors (/dev/fd) 67 */ 68 fdesc_mount(mp, path, data, ndp, p) 69 struct mount *mp; 70 char *path; 71 caddr_t data; 72 struct nameidata *ndp; 73 struct proc *p; 74 { 75 int error = 0; 76 u_int size; 77 struct fdescmount *fmp; 78 struct vnode *rvp; 79 80 #ifdef FDESC_DIAGNOSTIC 81 printf("fdesc_mount(mp = %x)\n", mp); 82 #endif 83 84 /* 85 * Update is a no-op 86 */ 87 if (mp->mnt_flag & MNT_UPDATE) 88 return (EOPNOTSUPP); 89 90 error = getnewvnode(VT_FDESC, mp, &fdesc_vnodeops, &rvp); 91 if (error) 92 return (error); 93 94 fmp = (struct fdescmount *) malloc(sizeof(struct fdescmount), 95 M_MISCFSMNT, M_WAITOK); 96 rvp->v_type = VDIR; 97 rvp->v_flag |= VROOT; 98 /*VTOFDESC(rvp)->f_isroot = 1;*/ 99 #ifdef FDESC_DIAGNOSTIC 100 printf("fdesc_mount: root vp = %x\n", rvp); 101 #endif 102 fmp->f_root = rvp; 103 mp->mnt_flag |= MNT_LOCAL; 104 mp->mnt_data = (qaddr_t) fmp; 105 getnewfsid(mp, MOUNT_FDESC); 106 107 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 108 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 109 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 110 bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 111 #ifdef FDESC_DIAGNOSTIC 112 printf("fdesc_mount: at %s\n", mp->mnt_stat.f_mntonname); 113 #endif 114 return (0); 115 } 116 117 fdesc_start(mp, flags, p) 118 struct mount *mp; 119 int flags; 120 struct proc *p; 121 { 122 return (0); 123 } 124 125 fdesc_unmount(mp, mntflags, p) 126 struct mount *mp; 127 int mntflags; 128 struct proc *p; 129 { 130 int error; 131 int flags = 0; 132 extern int doforce; 133 struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 134 135 #ifdef FDESC_DIAGNOSTIC 136 printf("fdesc_unmount(mp = %x)\n", mp); 137 #endif 138 139 if (mntflags & MNT_FORCE) { 140 /* fdesc can never be rootfs so don't check for it */ 141 if (!doforce) 142 return (EINVAL); 143 flags |= FORCECLOSE; 144 } 145 146 /* 147 * Clear out buffer cache. I don't think we 148 * ever get anything cached at this level at the 149 * moment, but who knows... 150 */ 151 #ifdef FDESC_DIAGNOSTIC 152 printf("fdesc_unmount: calling mntflushbuf\n"); 153 #endif 154 mntflushbuf(mp, 0); 155 #ifdef FDESC_DIAGNOSTIC 156 printf("fdesc_unmount: calling mntinvalbuf\n"); 157 #endif 158 if (mntinvalbuf(mp, 1)) 159 return (EBUSY); 160 if (rootvp->v_usecount > 1) 161 return (EBUSY); 162 #ifdef FDESC_DIAGNOSTIC 163 printf("fdesc_unmount: calling vflush\n"); 164 #endif 165 if (error = vflush(mp, rootvp, flags)) 166 return (error); 167 168 #ifdef FDESC_DIAGNOSTIC 169 vprint("fdesc root", rootvp); 170 #endif 171 /* 172 * Release reference on underlying root vnode 173 */ 174 vrele(rootvp); 175 /* 176 * And blow it away for future re-use 177 */ 178 vgone(rootvp); 179 /* 180 * Finally, throw away the fdescmount structure 181 */ 182 free(mp->mnt_data, M_MISCFSMNT); 183 mp->mnt_data = 0; 184 return 0; 185 } 186 187 fdesc_root(mp, vpp) 188 struct mount *mp; 189 struct vnode **vpp; 190 { 191 struct vnode *vp; 192 int error; 193 194 #ifdef FDESC_DIAGNOSTIC 195 printf("fdesc_root(mp = %x)\n", mp); 196 #endif 197 198 /* 199 * Return locked reference to root. 200 */ 201 vp = VFSTOFDESC(mp)->f_root; 202 VREF(vp); 203 VOP_LOCK(vp); 204 *vpp = vp; 205 return (0); 206 } 207 208 fdesc_quotactl(mp, cmd, uid, arg, p) 209 struct mount *mp; 210 int cmd; 211 uid_t uid; 212 caddr_t arg; 213 struct proc *p; 214 { 215 return (EOPNOTSUPP); 216 } 217 218 fdesc_statfs(mp, sbp, p) 219 struct mount *mp; 220 struct statfs *sbp; 221 struct proc *p; 222 { 223 struct filedesc *fdp; 224 int lim; 225 int i; 226 int last; 227 int freefd; 228 229 #ifdef FDESC_DIAGNOSTIC 230 printf("fdesc_statfs(mp = %x)\n", mp); 231 #endif 232 233 /* 234 * Compute number of free file descriptors. 235 * [ Strange results will ensue if the open file 236 * limit is ever reduced below the current number 237 * of open files... ] 238 */ 239 lim = p->p_rlimit[RLIMIT_OFILE].rlim_cur; 240 fdp = p->p_fd; 241 last = min(fdp->fd_nfiles, lim); 242 freefd = 0; 243 for (i = fdp->fd_freefile; i < last; i++) 244 if (fdp->fd_ofiles[i] == NULL) 245 freefd++; 246 247 /* 248 * Adjust for the fact that the fdesc array may not 249 * have been fully allocated yet. 250 */ 251 if (fdp->fd_nfiles < lim) 252 freefd += (lim - fdp->fd_nfiles); 253 254 sbp->f_type = MOUNT_FDESC; 255 sbp->f_flags = 0; 256 sbp->f_fsize = DEV_BSIZE; 257 sbp->f_bsize = DEV_BSIZE; 258 sbp->f_blocks = 2; /* 1K to keep df happy */ 259 sbp->f_bfree = 0; 260 sbp->f_bavail = 0; 261 sbp->f_files = lim + 1; /* Allow for "." */ 262 sbp->f_ffree = freefd; /* See comments above */ 263 if (sbp != &mp->mnt_stat) { 264 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 265 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 266 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 267 } 268 return (0); 269 } 270 271 fdesc_sync(mp, waitfor) 272 struct mount *mp; 273 int waitfor; 274 { 275 return (0); 276 } 277 278 fdesc_fhtovp(mp, fhp, vpp) 279 struct mount *mp; 280 struct fid *fhp; 281 struct vnode **vpp; 282 { 283 return (EOPNOTSUPP); 284 } 285 286 fdesc_vptofh(vp, fhp) 287 struct vnode *vp; 288 struct fid *fhp; 289 { 290 return (EOPNOTSUPP); 291 } 292 293 struct vfsops fdesc_vfsops = { 294 fdesc_mount, 295 fdesc_start, 296 fdesc_unmount, 297 fdesc_root, 298 fdesc_quotactl, 299 fdesc_statfs, 300 fdesc_sync, 301 fdesc_fhtovp, 302 fdesc_vptofh, 303 fdesc_init, 304 }; 305