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