153838Spendry /* 263231Sbostic * Copyright (c) 1992, 1993 363231Sbostic * The Regents of the University of California. All rights reserved. 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*65513Spendry * @(#)fdesc_vfsops.c 8.3 (Berkeley) 01/05/94 1253838Spendry * 1359255Spendry * $Id: fdesc_vfsops.c,v 1.9 1993/04/06 15:28:33 jsp Exp $ 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 /* 3453838Spendry * Mount the per-process file descriptors (/dev/fd) 3553838Spendry */ 36*65513Spendry int 3753838Spendry fdesc_mount(mp, path, data, ndp, p) 3853838Spendry struct mount *mp; 3953838Spendry char *path; 4053838Spendry caddr_t data; 4153838Spendry struct nameidata *ndp; 4253838Spendry struct proc *p; 4353838Spendry { 4453838Spendry int error = 0; 4553838Spendry u_int size; 4653838Spendry struct fdescmount *fmp; 4753838Spendry struct vnode *rvp; 4853838Spendry 4953838Spendry /* 5053838Spendry * Update is a no-op 5153838Spendry */ 5253838Spendry if (mp->mnt_flag & MNT_UPDATE) 5353838Spendry return (EOPNOTSUPP); 5453838Spendry 5559255Spendry error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 5653838Spendry if (error) 5753838Spendry return (error); 5853838Spendry 5953838Spendry MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 6053838Spendry M_UFSMNT, M_WAITOK); /* XXX */ 6153838Spendry rvp->v_type = VDIR; 6253838Spendry rvp->v_flag |= VROOT; 6353838Spendry fmp->f_root = rvp; 6459557Spendry /* XXX -- don't mark as local to work around fts() problems */ 6559557Spendry /*mp->mnt_flag |= MNT_LOCAL;*/ 6653838Spendry mp->mnt_data = (qaddr_t) fmp; 6753838Spendry getnewfsid(mp, MOUNT_FDESC); 6853838Spendry 6953838Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 7053838Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 7153838Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 7253838Spendry bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 7353838Spendry return (0); 7453838Spendry } 7553838Spendry 76*65513Spendry int 7753838Spendry fdesc_start(mp, flags, p) 7853838Spendry struct mount *mp; 7953838Spendry int flags; 8053838Spendry struct proc *p; 8153838Spendry { 8253838Spendry return (0); 8353838Spendry } 8453838Spendry 85*65513Spendry int 8653838Spendry fdesc_unmount(mp, mntflags, p) 8753838Spendry struct mount *mp; 8853838Spendry int mntflags; 8953838Spendry struct proc *p; 9053838Spendry { 9153838Spendry int error; 9253838Spendry int flags = 0; 9353838Spendry extern int doforce; 9453838Spendry struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 9553838Spendry 9653838Spendry if (mntflags & MNT_FORCE) { 9753838Spendry /* fdesc can never be rootfs so don't check for it */ 9853838Spendry if (!doforce) 9953838Spendry return (EINVAL); 10053838Spendry flags |= FORCECLOSE; 10153838Spendry } 10253838Spendry 10353838Spendry /* 10453838Spendry * Clear out buffer cache. I don't think we 10553838Spendry * ever get anything cached at this level at the 10653838Spendry * moment, but who knows... 10753838Spendry */ 10853838Spendry if (rootvp->v_usecount > 1) 10953838Spendry return (EBUSY); 11053838Spendry if (error = vflush(mp, rootvp, flags)) 11153838Spendry return (error); 11253838Spendry 11353838Spendry /* 11453838Spendry * Release reference on underlying root vnode 11553838Spendry */ 11653838Spendry vrele(rootvp); 11753838Spendry /* 11853838Spendry * And blow it away for future re-use 11953838Spendry */ 12053838Spendry vgone(rootvp); 12153838Spendry /* 12253838Spendry * Finally, throw away the fdescmount structure 12353838Spendry */ 12453838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 12553838Spendry mp->mnt_data = 0; 126*65513Spendry 127*65513Spendry return (0); 12853838Spendry } 12953838Spendry 130*65513Spendry int 13153838Spendry fdesc_root(mp, vpp) 13253838Spendry struct mount *mp; 13353838Spendry struct vnode **vpp; 13453838Spendry { 13553838Spendry struct vnode *vp; 13653838Spendry 13753838Spendry /* 13853838Spendry * Return locked reference to root. 13953838Spendry */ 14053838Spendry vp = VFSTOFDESC(mp)->f_root; 14153838Spendry VREF(vp); 14253838Spendry VOP_LOCK(vp); 14353838Spendry *vpp = vp; 14453838Spendry return (0); 14553838Spendry } 14653838Spendry 147*65513Spendry int 14853838Spendry fdesc_quotactl(mp, cmd, uid, arg, p) 14953838Spendry struct mount *mp; 15053838Spendry int cmd; 15153838Spendry uid_t uid; 15253838Spendry caddr_t arg; 15353838Spendry struct proc *p; 15453838Spendry { 155*65513Spendry 15653838Spendry return (EOPNOTSUPP); 15753838Spendry } 15853838Spendry 159*65513Spendry int 16053838Spendry fdesc_statfs(mp, sbp, p) 16153838Spendry struct mount *mp; 16253838Spendry struct statfs *sbp; 16353838Spendry struct proc *p; 16453838Spendry { 16553838Spendry struct filedesc *fdp; 16653838Spendry int lim; 16753838Spendry int i; 16853838Spendry int last; 16953838Spendry int freefd; 17053838Spendry 17153838Spendry /* 17253838Spendry * Compute number of free file descriptors. 17353838Spendry * [ Strange results will ensue if the open file 17453838Spendry * limit is ever reduced below the current number 17553838Spendry * of open files... ] 17653838Spendry */ 17756938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 17853838Spendry fdp = p->p_fd; 17953838Spendry last = min(fdp->fd_nfiles, lim); 18053838Spendry freefd = 0; 18153838Spendry for (i = fdp->fd_freefile; i < last; i++) 18253838Spendry if (fdp->fd_ofiles[i] == NULL) 18353838Spendry freefd++; 18453838Spendry 18553838Spendry /* 18653838Spendry * Adjust for the fact that the fdesc array may not 18753838Spendry * have been fully allocated yet. 18853838Spendry */ 18953838Spendry if (fdp->fd_nfiles < lim) 19053838Spendry freefd += (lim - fdp->fd_nfiles); 19153838Spendry 19253838Spendry sbp->f_type = MOUNT_FDESC; 19353838Spendry sbp->f_flags = 0; 19453838Spendry sbp->f_bsize = DEV_BSIZE; 19553838Spendry sbp->f_iosize = DEV_BSIZE; 19653838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 19753838Spendry sbp->f_bfree = 0; 19853838Spendry sbp->f_bavail = 0; 19953838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 20053838Spendry sbp->f_ffree = freefd; /* See comments above */ 20153838Spendry if (sbp != &mp->mnt_stat) { 20253838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 20353838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 20453838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 20553838Spendry } 20653838Spendry return (0); 20753838Spendry } 20853838Spendry 209*65513Spendry int 21053838Spendry fdesc_sync(mp, waitfor) 21153838Spendry struct mount *mp; 21253838Spendry int waitfor; 21353838Spendry { 214*65513Spendry 21553838Spendry return (0); 21653838Spendry } 21753838Spendry 21854980Spendry /* 21954980Spendry * Fdesc flat namespace lookup. 22054980Spendry * Currently unsupported. 22154980Spendry */ 222*65513Spendry int 22354980Spendry fdesc_vget(mp, ino, vpp) 22454980Spendry struct mount *mp; 22554980Spendry ino_t ino; 22654980Spendry struct vnode **vpp; 22754980Spendry { 22854980Spendry 22954980Spendry return (EOPNOTSUPP); 23054980Spendry } 23154980Spendry 232*65513Spendry int 23353838Spendry fdesc_fhtovp(mp, fhp, setgen, vpp) 23453838Spendry struct mount *mp; 23553838Spendry struct fid *fhp; 23653838Spendry int setgen; 23753838Spendry struct vnode **vpp; 23853838Spendry { 23953838Spendry return (EOPNOTSUPP); 24053838Spendry } 24153838Spendry 242*65513Spendry int 24353838Spendry fdesc_vptofh(vp, fhp) 24453838Spendry struct vnode *vp; 24553838Spendry struct fid *fhp; 24653838Spendry { 247*65513Spendry 24853838Spendry return (EOPNOTSUPP); 24953838Spendry } 25053838Spendry 25153838Spendry struct vfsops fdesc_vfsops = { 25253838Spendry fdesc_mount, 25353838Spendry fdesc_start, 25453838Spendry fdesc_unmount, 25553838Spendry fdesc_root, 25653838Spendry fdesc_quotactl, 25753838Spendry fdesc_statfs, 25853838Spendry fdesc_sync, 25954980Spendry fdesc_vget, 26053838Spendry fdesc_fhtovp, 26153838Spendry fdesc_vptofh, 26253838Spendry fdesc_init, 26353838Spendry }; 264