153838Spendry /* 253838Spendry * Copyright (c) 1992 The Regents of the University of California 353838Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 453838Spendry * All rights reserved. 553838Spendry * 653838Spendry * This code is derived from software donated to Berkeley by 753838Spendry * Jan-Simon Pendry. 853838Spendry * 953838Spendry * %sccs.include.redist.c% 1053838Spendry * 11*56938Smckusick * @(#)fdesc_vfsops.c 7.2 (Berkeley) 12/01/92 1253838Spendry * 1353838Spendry * $Id: fdesc_vfsops.c,v 1.6 1992/05/30 10:25:59 jsp Exp jsp $ 1453838Spendry */ 1553838Spendry 1653838Spendry /* 1753838Spendry * /dev/fd Filesystem 1853838Spendry */ 1953838Spendry 2053838Spendry #include <sys/param.h> 2153838Spendry #include <sys/systm.h> 2253838Spendry #include <sys/time.h> 2353838Spendry #include <sys/types.h> 2453838Spendry #include <sys/proc.h> 2553838Spendry #include <sys/resourcevar.h> 2653838Spendry #include <sys/filedesc.h> 2753838Spendry #include <sys/vnode.h> 2853838Spendry #include <sys/mount.h> 2953838Spendry #include <sys/namei.h> 3053838Spendry #include <sys/malloc.h> 3155016Smckusick #include <miscfs/fdesc/fdesc.h> 3253838Spendry 3353838Spendry static u_short fdesc_mntid; 3453838Spendry 3553838Spendry fdesc_init() 3653838Spendry { 3753838Spendry #ifdef FDESC_DIAGNOSTIC 3853838Spendry printf("fdesc_init\n"); /* printed during system boot */ 3953838Spendry #endif 4053838Spendry } 4153838Spendry 4253838Spendry /* 4353838Spendry * Mount the per-process file descriptors (/dev/fd) 4453838Spendry */ 4553838Spendry fdesc_mount(mp, path, data, ndp, p) 4653838Spendry struct mount *mp; 4753838Spendry char *path; 4853838Spendry caddr_t data; 4953838Spendry struct nameidata *ndp; 5053838Spendry struct proc *p; 5153838Spendry { 5253838Spendry int error = 0; 5353838Spendry u_int size; 5453838Spendry struct fdescmount *fmp; 5553838Spendry struct vnode *rvp; 5653838Spendry 5753838Spendry #ifdef FDESC_DIAGNOSTIC 5853838Spendry printf("fdesc_mount(mp = %x)\n", mp); 5953838Spendry #endif 6053838Spendry 6153838Spendry /* 6253838Spendry * Update is a no-op 6353838Spendry */ 6453838Spendry if (mp->mnt_flag & MNT_UPDATE) 6553838Spendry return (EOPNOTSUPP); 6653838Spendry 6753838Spendry error = getnewvnode(VT_UFS, mp, fdesc_vnodeop_p, &rvp); /* XXX */ 6853838Spendry if (error) 6953838Spendry return (error); 7053838Spendry 7153838Spendry MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 7253838Spendry M_UFSMNT, M_WAITOK); /* XXX */ 7353838Spendry rvp->v_type = VDIR; 7453838Spendry rvp->v_flag |= VROOT; 7553838Spendry #ifdef FDESC_DIAGNOSTIC 7653838Spendry printf("fdesc_mount: root vp = %x\n", rvp); 7753838Spendry #endif 7853838Spendry fmp->f_root = rvp; 7953838Spendry mp->mnt_flag |= MNT_LOCAL; 8053838Spendry mp->mnt_data = (qaddr_t) fmp; 8153838Spendry getnewfsid(mp, MOUNT_FDESC); 8253838Spendry 8353838Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 8453838Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 8553838Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 8653838Spendry bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 8753838Spendry #ifdef FDESC_DIAGNOSTIC 8853838Spendry printf("fdesc_mount: at %s\n", mp->mnt_stat.f_mntonname); 8953838Spendry #endif 9053838Spendry return (0); 9153838Spendry } 9253838Spendry 9353838Spendry fdesc_start(mp, flags, p) 9453838Spendry struct mount *mp; 9553838Spendry int flags; 9653838Spendry struct proc *p; 9753838Spendry { 9853838Spendry return (0); 9953838Spendry } 10053838Spendry 10153838Spendry fdesc_unmount(mp, mntflags, p) 10253838Spendry struct mount *mp; 10353838Spendry int mntflags; 10453838Spendry struct proc *p; 10553838Spendry { 10653838Spendry int error; 10753838Spendry int flags = 0; 10853838Spendry extern int doforce; 10953838Spendry struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 11053838Spendry 11153838Spendry #ifdef FDESC_DIAGNOSTIC 11253838Spendry printf("fdesc_unmount(mp = %x)\n", mp); 11353838Spendry #endif 11453838Spendry 11553838Spendry if (mntflags & MNT_FORCE) { 11653838Spendry /* fdesc can never be rootfs so don't check for it */ 11753838Spendry if (!doforce) 11853838Spendry return (EINVAL); 11953838Spendry flags |= FORCECLOSE; 12053838Spendry } 12153838Spendry 12253838Spendry /* 12353838Spendry * Clear out buffer cache. I don't think we 12453838Spendry * ever get anything cached at this level at the 12553838Spendry * moment, but who knows... 12653838Spendry */ 12754980Spendry #if 0 12853838Spendry #ifdef FDESC_DIAGNOSTIC 12953838Spendry printf("fdesc_unmount: calling mntflushbuf\n"); 13053838Spendry #endif 13153838Spendry mntflushbuf(mp, 0); 13253838Spendry #ifdef FDESC_DIAGNOSTIC 13353838Spendry printf("fdesc_unmount: calling mntinvalbuf\n"); 13453838Spendry #endif 13553838Spendry if (mntinvalbuf(mp, 1)) 13653838Spendry return (EBUSY); 13754980Spendry #endif 13853838Spendry if (rootvp->v_usecount > 1) 13953838Spendry return (EBUSY); 14053838Spendry #ifdef FDESC_DIAGNOSTIC 14153838Spendry printf("fdesc_unmount: calling vflush\n"); 14253838Spendry #endif 14353838Spendry if (error = vflush(mp, rootvp, flags)) 14453838Spendry return (error); 14553838Spendry 14653838Spendry #ifdef FDESC_DIAGNOSTIC 14753838Spendry vprint("fdesc root", rootvp); 14853838Spendry #endif 14953838Spendry /* 15053838Spendry * Release reference on underlying root vnode 15153838Spendry */ 15253838Spendry vrele(rootvp); 15353838Spendry /* 15453838Spendry * And blow it away for future re-use 15553838Spendry */ 15653838Spendry vgone(rootvp); 15753838Spendry /* 15853838Spendry * Finally, throw away the fdescmount structure 15953838Spendry */ 16053838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 16153838Spendry mp->mnt_data = 0; 16253838Spendry return 0; 16353838Spendry } 16453838Spendry 16553838Spendry fdesc_root(mp, vpp) 16653838Spendry struct mount *mp; 16753838Spendry struct vnode **vpp; 16853838Spendry { 16953838Spendry struct vnode *vp; 17053838Spendry int error; 17153838Spendry 17253838Spendry #ifdef FDESC_DIAGNOSTIC 17353838Spendry printf("fdesc_root(mp = %x)\n", mp); 17453838Spendry #endif 17553838Spendry 17653838Spendry /* 17753838Spendry * Return locked reference to root. 17853838Spendry */ 17953838Spendry vp = VFSTOFDESC(mp)->f_root; 18053838Spendry VREF(vp); 18153838Spendry VOP_LOCK(vp); 18253838Spendry *vpp = vp; 18353838Spendry return (0); 18453838Spendry } 18553838Spendry 18653838Spendry fdesc_quotactl(mp, cmd, uid, arg, p) 18753838Spendry struct mount *mp; 18853838Spendry int cmd; 18953838Spendry uid_t uid; 19053838Spendry caddr_t arg; 19153838Spendry struct proc *p; 19253838Spendry { 19353838Spendry return (EOPNOTSUPP); 19453838Spendry } 19553838Spendry 19653838Spendry fdesc_statfs(mp, sbp, p) 19753838Spendry struct mount *mp; 19853838Spendry struct statfs *sbp; 19953838Spendry struct proc *p; 20053838Spendry { 20153838Spendry struct filedesc *fdp; 20253838Spendry int lim; 20353838Spendry int i; 20453838Spendry int last; 20553838Spendry int freefd; 20653838Spendry 20753838Spendry #ifdef FDESC_DIAGNOSTIC 20853838Spendry printf("fdesc_statfs(mp = %x)\n", mp); 20953838Spendry #endif 21053838Spendry 21153838Spendry /* 21253838Spendry * Compute number of free file descriptors. 21353838Spendry * [ Strange results will ensue if the open file 21453838Spendry * limit is ever reduced below the current number 21553838Spendry * of open files... ] 21653838Spendry */ 217*56938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 21853838Spendry fdp = p->p_fd; 21953838Spendry last = min(fdp->fd_nfiles, lim); 22053838Spendry freefd = 0; 22153838Spendry for (i = fdp->fd_freefile; i < last; i++) 22253838Spendry if (fdp->fd_ofiles[i] == NULL) 22353838Spendry freefd++; 22453838Spendry 22553838Spendry /* 22653838Spendry * Adjust for the fact that the fdesc array may not 22753838Spendry * have been fully allocated yet. 22853838Spendry */ 22953838Spendry if (fdp->fd_nfiles < lim) 23053838Spendry freefd += (lim - fdp->fd_nfiles); 23153838Spendry 23253838Spendry sbp->f_type = MOUNT_FDESC; 23353838Spendry sbp->f_flags = 0; 23453838Spendry sbp->f_bsize = DEV_BSIZE; 23553838Spendry sbp->f_iosize = DEV_BSIZE; 23653838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 23753838Spendry sbp->f_bfree = 0; 23853838Spendry sbp->f_bavail = 0; 23953838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 24053838Spendry sbp->f_ffree = freefd; /* See comments above */ 24153838Spendry if (sbp != &mp->mnt_stat) { 24253838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 24353838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 24453838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 24553838Spendry } 24653838Spendry return (0); 24753838Spendry } 24853838Spendry 24953838Spendry fdesc_sync(mp, waitfor) 25053838Spendry struct mount *mp; 25153838Spendry int waitfor; 25253838Spendry { 25353838Spendry return (0); 25453838Spendry } 25553838Spendry 25654980Spendry /* 25754980Spendry * Fdesc flat namespace lookup. 25854980Spendry * Currently unsupported. 25954980Spendry */ 26054980Spendry fdesc_vget(mp, ino, vpp) 26154980Spendry struct mount *mp; 26254980Spendry ino_t ino; 26354980Spendry struct vnode **vpp; 26454980Spendry { 26554980Spendry 26654980Spendry return (EOPNOTSUPP); 26754980Spendry } 26854980Spendry 26954980Spendry 27053838Spendry fdesc_fhtovp(mp, fhp, setgen, vpp) 27153838Spendry struct mount *mp; 27253838Spendry struct fid *fhp; 27353838Spendry int setgen; 27453838Spendry struct vnode **vpp; 27553838Spendry { 27653838Spendry return (EOPNOTSUPP); 27753838Spendry } 27853838Spendry 27953838Spendry fdesc_vptofh(vp, fhp) 28053838Spendry struct vnode *vp; 28153838Spendry struct fid *fhp; 28253838Spendry { 28353838Spendry return (EOPNOTSUPP); 28453838Spendry } 28553838Spendry 28653838Spendry struct vfsops fdesc_vfsops = { 28753838Spendry fdesc_mount, 28853838Spendry fdesc_start, 28953838Spendry fdesc_unmount, 29053838Spendry fdesc_root, 29153838Spendry fdesc_quotactl, 29253838Spendry fdesc_statfs, 29353838Spendry fdesc_sync, 29454980Spendry fdesc_vget, 29553838Spendry fdesc_fhtovp, 29653838Spendry fdesc_vptofh, 29753838Spendry fdesc_init, 29853838Spendry }; 299