153838Spendry /* 263231Sbostic * Copyright (c) 1992, 1993 363231Sbostic * The Regents of the University of California. All rights reserved. 453838Spendry * 553838Spendry * This code is derived from software donated to Berkeley by 653838Spendry * Jan-Simon Pendry. 753838Spendry * 853838Spendry * %sccs.include.redist.c% 953838Spendry * 10*68728Smckusick * @(#)fdesc_vfsops.c 8.7 (Berkeley) 04/03/95 1153838Spendry * 1259255Spendry * $Id: fdesc_vfsops.c,v 1.9 1993/04/06 15:28:33 jsp Exp $ 1353838Spendry */ 1453838Spendry 1553838Spendry /* 1653838Spendry * /dev/fd Filesystem 1753838Spendry */ 1853838Spendry 1953838Spendry #include <sys/param.h> 2053838Spendry #include <sys/systm.h> 2153838Spendry #include <sys/time.h> 2253838Spendry #include <sys/types.h> 2353838Spendry #include <sys/proc.h> 2453838Spendry #include <sys/resourcevar.h> 2553838Spendry #include <sys/filedesc.h> 2653838Spendry #include <sys/vnode.h> 2753838Spendry #include <sys/mount.h> 2853838Spendry #include <sys/namei.h> 2953838Spendry #include <sys/malloc.h> 3055016Smckusick #include <miscfs/fdesc/fdesc.h> 3153838Spendry 3253838Spendry /* 3353838Spendry * Mount the per-process file descriptors (/dev/fd) 3453838Spendry */ 3565513Spendry int 3653838Spendry fdesc_mount(mp, path, data, ndp, p) 3753838Spendry struct mount *mp; 3853838Spendry char *path; 3953838Spendry caddr_t data; 4053838Spendry struct nameidata *ndp; 4153838Spendry struct proc *p; 4253838Spendry { 4353838Spendry int error = 0; 4453838Spendry u_int size; 4553838Spendry struct fdescmount *fmp; 4653838Spendry struct vnode *rvp; 4753838Spendry 4853838Spendry /* 4953838Spendry * Update is a no-op 5053838Spendry */ 5153838Spendry if (mp->mnt_flag & MNT_UPDATE) 5253838Spendry return (EOPNOTSUPP); 5353838Spendry 5459255Spendry error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 5553838Spendry if (error) 5653838Spendry return (error); 5753838Spendry 5853838Spendry MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 5953838Spendry M_UFSMNT, M_WAITOK); /* XXX */ 6053838Spendry rvp->v_type = VDIR; 6153838Spendry rvp->v_flag |= VROOT; 6253838Spendry fmp->f_root = rvp; 6359557Spendry /* XXX -- don't mark as local to work around fts() problems */ 6459557Spendry /*mp->mnt_flag |= MNT_LOCAL;*/ 6553838Spendry mp->mnt_data = (qaddr_t) fmp; 6668616Smckusick vfs_getnewfsid(mp); 6753838Spendry 6853838Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 6953838Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 7053838Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 7153838Spendry bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 7253838Spendry return (0); 7353838Spendry } 7453838Spendry 7565513Spendry int 7653838Spendry fdesc_start(mp, flags, p) 7753838Spendry struct mount *mp; 7853838Spendry int flags; 7953838Spendry struct proc *p; 8053838Spendry { 8153838Spendry return (0); 8253838Spendry } 8353838Spendry 8465513Spendry int 8553838Spendry fdesc_unmount(mp, mntflags, p) 8653838Spendry struct mount *mp; 8753838Spendry int mntflags; 8853838Spendry struct proc *p; 8953838Spendry { 9053838Spendry int error; 9153838Spendry int flags = 0; 9253838Spendry extern int doforce; 9353838Spendry struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 9453838Spendry 9553838Spendry if (mntflags & MNT_FORCE) { 9653838Spendry /* fdesc can never be rootfs so don't check for it */ 9753838Spendry if (!doforce) 9853838Spendry return (EINVAL); 9953838Spendry flags |= FORCECLOSE; 10053838Spendry } 10153838Spendry 10253838Spendry /* 10353838Spendry * Clear out buffer cache. I don't think we 10453838Spendry * ever get anything cached at this level at the 10553838Spendry * moment, but who knows... 10653838Spendry */ 10753838Spendry if (rootvp->v_usecount > 1) 10853838Spendry return (EBUSY); 10953838Spendry if (error = vflush(mp, rootvp, flags)) 11053838Spendry return (error); 11153838Spendry 11253838Spendry /* 11353838Spendry * Release reference on underlying root vnode 11453838Spendry */ 11553838Spendry vrele(rootvp); 11653838Spendry /* 11753838Spendry * And blow it away for future re-use 11853838Spendry */ 11968425Smckusick VOP_REVOKE(rootvp, 0); 12053838Spendry /* 12153838Spendry * Finally, throw away the fdescmount structure 12253838Spendry */ 12353838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 12453838Spendry mp->mnt_data = 0; 12565513Spendry 12665513Spendry return (0); 12753838Spendry } 12853838Spendry 12965513Spendry int 13053838Spendry fdesc_root(mp, vpp) 13153838Spendry struct mount *mp; 13253838Spendry struct vnode **vpp; 13353838Spendry { 13453838Spendry struct vnode *vp; 13553838Spendry 13653838Spendry /* 13753838Spendry * Return locked reference to root. 13853838Spendry */ 13953838Spendry vp = VFSTOFDESC(mp)->f_root; 14053838Spendry VREF(vp); 14153838Spendry VOP_LOCK(vp); 14253838Spendry *vpp = vp; 14353838Spendry return (0); 14453838Spendry } 14553838Spendry 14665513Spendry int 14753838Spendry fdesc_statfs(mp, sbp, p) 14853838Spendry struct mount *mp; 14953838Spendry struct statfs *sbp; 15053838Spendry struct proc *p; 15153838Spendry { 15253838Spendry struct filedesc *fdp; 15353838Spendry int lim; 15453838Spendry int i; 15553838Spendry int last; 15653838Spendry int freefd; 15753838Spendry 15853838Spendry /* 15953838Spendry * Compute number of free file descriptors. 16053838Spendry * [ Strange results will ensue if the open file 16153838Spendry * limit is ever reduced below the current number 16253838Spendry * of open files... ] 16353838Spendry */ 16456938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 16553838Spendry fdp = p->p_fd; 16653838Spendry last = min(fdp->fd_nfiles, lim); 16753838Spendry freefd = 0; 16853838Spendry for (i = fdp->fd_freefile; i < last; i++) 16953838Spendry if (fdp->fd_ofiles[i] == NULL) 17053838Spendry freefd++; 17153838Spendry 17253838Spendry /* 17353838Spendry * Adjust for the fact that the fdesc array may not 17453838Spendry * have been fully allocated yet. 17553838Spendry */ 17653838Spendry if (fdp->fd_nfiles < lim) 17753838Spendry freefd += (lim - fdp->fd_nfiles); 17853838Spendry 17953838Spendry sbp->f_flags = 0; 18053838Spendry sbp->f_bsize = DEV_BSIZE; 18153838Spendry sbp->f_iosize = DEV_BSIZE; 18253838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 18353838Spendry sbp->f_bfree = 0; 18453838Spendry sbp->f_bavail = 0; 18553838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 18653838Spendry sbp->f_ffree = freefd; /* See comments above */ 18753838Spendry if (sbp != &mp->mnt_stat) { 18868616Smckusick sbp->f_type = mp->mnt_vfc->vfc_typenum; 18953838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 19053838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 19153838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 19253838Spendry } 19353838Spendry return (0); 19453838Spendry } 19553838Spendry 19665513Spendry int 19753838Spendry fdesc_sync(mp, waitfor) 19853838Spendry struct mount *mp; 19953838Spendry int waitfor; 20053838Spendry { 20165513Spendry 20253838Spendry return (0); 20353838Spendry } 20453838Spendry 205*68728Smckusick #define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 206*68728Smckusick struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 207*68728Smckusick #define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 208*68728Smckusick struct proc *)))eopnotsupp) 209*68728Smckusick #define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 210*68728Smckusick size_t, struct proc *)))eopnotsupp) 211*68728Smckusick #define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 212*68728Smckusick eopnotsupp) 213*68728Smckusick #define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 214*68728Smckusick 21553838Spendry struct vfsops fdesc_vfsops = { 21653838Spendry fdesc_mount, 21753838Spendry fdesc_start, 21853838Spendry fdesc_unmount, 21953838Spendry fdesc_root, 22053838Spendry fdesc_quotactl, 22153838Spendry fdesc_statfs, 22253838Spendry fdesc_sync, 22354980Spendry fdesc_vget, 22453838Spendry fdesc_fhtovp, 22553838Spendry fdesc_vptofh, 22653838Spendry fdesc_init, 22768616Smckusick fdesc_sysctl, 22853838Spendry }; 229