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*69335Smckusick * @(#)fdesc_vfsops.c 8.8 (Berkeley) 05/10/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 struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 9353838Spendry 94*69335Smckusick if (mntflags & MNT_FORCE) 9553838Spendry flags |= FORCECLOSE; 9653838Spendry 9753838Spendry /* 9853838Spendry * Clear out buffer cache. I don't think we 9953838Spendry * ever get anything cached at this level at the 10053838Spendry * moment, but who knows... 10153838Spendry */ 10253838Spendry if (rootvp->v_usecount > 1) 10353838Spendry return (EBUSY); 10453838Spendry if (error = vflush(mp, rootvp, flags)) 10553838Spendry return (error); 10653838Spendry 10753838Spendry /* 10853838Spendry * Release reference on underlying root vnode 10953838Spendry */ 11053838Spendry vrele(rootvp); 11153838Spendry /* 11253838Spendry * And blow it away for future re-use 11353838Spendry */ 11468425Smckusick VOP_REVOKE(rootvp, 0); 11553838Spendry /* 11653838Spendry * Finally, throw away the fdescmount structure 11753838Spendry */ 11853838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 11953838Spendry mp->mnt_data = 0; 12065513Spendry 12165513Spendry return (0); 12253838Spendry } 12353838Spendry 12465513Spendry int 12553838Spendry fdesc_root(mp, vpp) 12653838Spendry struct mount *mp; 12753838Spendry struct vnode **vpp; 12853838Spendry { 12953838Spendry struct vnode *vp; 13053838Spendry 13153838Spendry /* 13253838Spendry * Return locked reference to root. 13353838Spendry */ 13453838Spendry vp = VFSTOFDESC(mp)->f_root; 13553838Spendry VREF(vp); 13653838Spendry VOP_LOCK(vp); 13753838Spendry *vpp = vp; 13853838Spendry return (0); 13953838Spendry } 14053838Spendry 14165513Spendry int 14253838Spendry fdesc_statfs(mp, sbp, p) 14353838Spendry struct mount *mp; 14453838Spendry struct statfs *sbp; 14553838Spendry struct proc *p; 14653838Spendry { 14753838Spendry struct filedesc *fdp; 14853838Spendry int lim; 14953838Spendry int i; 15053838Spendry int last; 15153838Spendry int freefd; 15253838Spendry 15353838Spendry /* 15453838Spendry * Compute number of free file descriptors. 15553838Spendry * [ Strange results will ensue if the open file 15653838Spendry * limit is ever reduced below the current number 15753838Spendry * of open files... ] 15853838Spendry */ 15956938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 16053838Spendry fdp = p->p_fd; 16153838Spendry last = min(fdp->fd_nfiles, lim); 16253838Spendry freefd = 0; 16353838Spendry for (i = fdp->fd_freefile; i < last; i++) 16453838Spendry if (fdp->fd_ofiles[i] == NULL) 16553838Spendry freefd++; 16653838Spendry 16753838Spendry /* 16853838Spendry * Adjust for the fact that the fdesc array may not 16953838Spendry * have been fully allocated yet. 17053838Spendry */ 17153838Spendry if (fdp->fd_nfiles < lim) 17253838Spendry freefd += (lim - fdp->fd_nfiles); 17353838Spendry 17453838Spendry sbp->f_flags = 0; 17553838Spendry sbp->f_bsize = DEV_BSIZE; 17653838Spendry sbp->f_iosize = DEV_BSIZE; 17753838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 17853838Spendry sbp->f_bfree = 0; 17953838Spendry sbp->f_bavail = 0; 18053838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 18153838Spendry sbp->f_ffree = freefd; /* See comments above */ 18253838Spendry if (sbp != &mp->mnt_stat) { 18368616Smckusick sbp->f_type = mp->mnt_vfc->vfc_typenum; 18453838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 18553838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 18653838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 18753838Spendry } 18853838Spendry return (0); 18953838Spendry } 19053838Spendry 19165513Spendry int 19253838Spendry fdesc_sync(mp, waitfor) 19353838Spendry struct mount *mp; 19453838Spendry int waitfor; 19553838Spendry { 19665513Spendry 19753838Spendry return (0); 19853838Spendry } 19953838Spendry 20068728Smckusick #define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 20168728Smckusick struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 20268728Smckusick #define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 20368728Smckusick struct proc *)))eopnotsupp) 20468728Smckusick #define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 20568728Smckusick size_t, struct proc *)))eopnotsupp) 20668728Smckusick #define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 20768728Smckusick eopnotsupp) 20868728Smckusick #define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 20968728Smckusick 21053838Spendry struct vfsops fdesc_vfsops = { 21153838Spendry fdesc_mount, 21253838Spendry fdesc_start, 21353838Spendry fdesc_unmount, 21453838Spendry fdesc_root, 21553838Spendry fdesc_quotactl, 21653838Spendry fdesc_statfs, 21753838Spendry fdesc_sync, 21854980Spendry fdesc_vget, 21953838Spendry fdesc_fhtovp, 22053838Spendry fdesc_vptofh, 22153838Spendry fdesc_init, 22268616Smckusick fdesc_sysctl, 22353838Spendry }; 224