fdesc_vfsops.c revision 2946
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1992, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * This code is derived from software donated to Berkeley by 61541Srgrimes * Jan-Simon Pendry. 71541Srgrimes * 81541Srgrimes * Redistribution and use in source and binary forms, with or without 91541Srgrimes * modification, are permitted provided that the following conditions 101541Srgrimes * are met: 111541Srgrimes * 1. Redistributions of source code must retain the above copyright 121541Srgrimes * notice, this list of conditions and the following disclaimer. 131541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer in the 151541Srgrimes * documentation and/or other materials provided with the distribution. 161541Srgrimes * 3. All advertising materials mentioning features or use of this software 171541Srgrimes * must display the following acknowledgement: 181541Srgrimes * This product includes software developed by the University of 191541Srgrimes * California, Berkeley and its contributors. 201541Srgrimes * 4. Neither the name of the University nor the names of its contributors 211541Srgrimes * may be used to endorse or promote products derived from this software 221541Srgrimes * without specific prior written permission. 231541Srgrimes * 241541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341541Srgrimes * SUCH DAMAGE. 351541Srgrimes * 361541Srgrimes * @(#)fdesc_vfsops.c 8.4 (Berkeley) 1/21/94 371541Srgrimes * 382946Swollman * $Id: fdesc_vfsops.c,v 1.1.1.1 1994/05/24 10:04:59 rgrimes Exp $ 391541Srgrimes */ 401541Srgrimes 411541Srgrimes/* 421541Srgrimes * /dev/fd Filesystem 431541Srgrimes */ 441541Srgrimes 451541Srgrimes#include <sys/param.h> 461541Srgrimes#include <sys/systm.h> 472946Swollman#include <sys/kernel.h> 481541Srgrimes#include <sys/time.h> 491541Srgrimes#include <sys/types.h> 501541Srgrimes#include <sys/proc.h> 511541Srgrimes#include <sys/resourcevar.h> 521541Srgrimes#include <sys/filedesc.h> 531541Srgrimes#include <sys/vnode.h> 541541Srgrimes#include <sys/mount.h> 551541Srgrimes#include <sys/namei.h> 561541Srgrimes#include <sys/malloc.h> 571541Srgrimes#include <miscfs/fdesc/fdesc.h> 581541Srgrimes 591541Srgrimes/* 601541Srgrimes * Mount the per-process file descriptors (/dev/fd) 611541Srgrimes */ 621541Srgrimesint 631541Srgrimesfdesc_mount(mp, path, data, ndp, p) 641541Srgrimes struct mount *mp; 651541Srgrimes char *path; 661541Srgrimes caddr_t data; 671541Srgrimes struct nameidata *ndp; 681541Srgrimes struct proc *p; 691541Srgrimes{ 701541Srgrimes int error = 0; 711541Srgrimes u_int size; 721541Srgrimes struct fdescmount *fmp; 731541Srgrimes struct vnode *rvp; 741541Srgrimes 751541Srgrimes /* 761541Srgrimes * Update is a no-op 771541Srgrimes */ 781541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 791541Srgrimes return (EOPNOTSUPP); 801541Srgrimes 811541Srgrimes error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 821541Srgrimes if (error) 831541Srgrimes return (error); 841541Srgrimes 851541Srgrimes MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 861541Srgrimes M_UFSMNT, M_WAITOK); /* XXX */ 871541Srgrimes rvp->v_type = VDIR; 881541Srgrimes rvp->v_flag |= VROOT; 891541Srgrimes fmp->f_root = rvp; 901541Srgrimes /* XXX -- don't mark as local to work around fts() problems */ 911541Srgrimes /*mp->mnt_flag |= MNT_LOCAL;*/ 921541Srgrimes mp->mnt_data = (qaddr_t) fmp; 931541Srgrimes getnewfsid(mp, MOUNT_FDESC); 941541Srgrimes 951541Srgrimes (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 961541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 971541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 981541Srgrimes bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 991541Srgrimes return (0); 1001541Srgrimes} 1011541Srgrimes 1021541Srgrimesint 1031541Srgrimesfdesc_start(mp, flags, p) 1041541Srgrimes struct mount *mp; 1051541Srgrimes int flags; 1061541Srgrimes struct proc *p; 1071541Srgrimes{ 1081541Srgrimes return (0); 1091541Srgrimes} 1101541Srgrimes 1111541Srgrimesint 1121541Srgrimesfdesc_unmount(mp, mntflags, p) 1131541Srgrimes struct mount *mp; 1141541Srgrimes int mntflags; 1151541Srgrimes struct proc *p; 1161541Srgrimes{ 1171541Srgrimes int error; 1181541Srgrimes int flags = 0; 1191541Srgrimes extern int doforce; 1201541Srgrimes struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 1211541Srgrimes 1221541Srgrimes if (mntflags & MNT_FORCE) { 1231541Srgrimes /* fdesc can never be rootfs so don't check for it */ 1241541Srgrimes if (!doforce) 1251541Srgrimes return (EINVAL); 1261541Srgrimes flags |= FORCECLOSE; 1271541Srgrimes } 1281541Srgrimes 1291541Srgrimes /* 1301541Srgrimes * Clear out buffer cache. I don't think we 1311541Srgrimes * ever get anything cached at this level at the 1321541Srgrimes * moment, but who knows... 1331541Srgrimes */ 1341541Srgrimes if (rootvp->v_usecount > 1) 1351541Srgrimes return (EBUSY); 1361541Srgrimes if (error = vflush(mp, rootvp, flags)) 1371541Srgrimes return (error); 1381541Srgrimes 1391541Srgrimes /* 1401541Srgrimes * Release reference on underlying root vnode 1411541Srgrimes */ 1421541Srgrimes vrele(rootvp); 1431541Srgrimes /* 1441541Srgrimes * And blow it away for future re-use 1451541Srgrimes */ 1461541Srgrimes vgone(rootvp); 1471541Srgrimes /* 1481541Srgrimes * Finally, throw away the fdescmount structure 1491541Srgrimes */ 1501541Srgrimes free(mp->mnt_data, M_UFSMNT); /* XXX */ 1511541Srgrimes mp->mnt_data = 0; 1521541Srgrimes 1531541Srgrimes return (0); 1541541Srgrimes} 1551541Srgrimes 1561541Srgrimesint 1571541Srgrimesfdesc_root(mp, vpp) 1581541Srgrimes struct mount *mp; 1591541Srgrimes struct vnode **vpp; 1601541Srgrimes{ 1611541Srgrimes struct vnode *vp; 1621541Srgrimes 1631541Srgrimes /* 1641541Srgrimes * Return locked reference to root. 1651541Srgrimes */ 1661541Srgrimes vp = VFSTOFDESC(mp)->f_root; 1671541Srgrimes VREF(vp); 1681541Srgrimes VOP_LOCK(vp); 1691541Srgrimes *vpp = vp; 1701541Srgrimes return (0); 1711541Srgrimes} 1721541Srgrimes 1731541Srgrimesint 1741541Srgrimesfdesc_quotactl(mp, cmd, uid, arg, p) 1751541Srgrimes struct mount *mp; 1761541Srgrimes int cmd; 1771541Srgrimes uid_t uid; 1781541Srgrimes caddr_t arg; 1791541Srgrimes struct proc *p; 1801541Srgrimes{ 1811541Srgrimes 1821541Srgrimes return (EOPNOTSUPP); 1831541Srgrimes} 1841541Srgrimes 1851541Srgrimesint 1861541Srgrimesfdesc_statfs(mp, sbp, p) 1871541Srgrimes struct mount *mp; 1881541Srgrimes struct statfs *sbp; 1891541Srgrimes struct proc *p; 1901541Srgrimes{ 1911541Srgrimes struct filedesc *fdp; 1921541Srgrimes int lim; 1931541Srgrimes int i; 1941541Srgrimes int last; 1951541Srgrimes int freefd; 1961541Srgrimes 1971541Srgrimes /* 1981541Srgrimes * Compute number of free file descriptors. 1991541Srgrimes * [ Strange results will ensue if the open file 2001541Srgrimes * limit is ever reduced below the current number 2011541Srgrimes * of open files... ] 2021541Srgrimes */ 2031541Srgrimes lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 2041541Srgrimes fdp = p->p_fd; 2051541Srgrimes last = min(fdp->fd_nfiles, lim); 2061541Srgrimes freefd = 0; 2071541Srgrimes for (i = fdp->fd_freefile; i < last; i++) 2081541Srgrimes if (fdp->fd_ofiles[i] == NULL) 2091541Srgrimes freefd++; 2101541Srgrimes 2111541Srgrimes /* 2121541Srgrimes * Adjust for the fact that the fdesc array may not 2131541Srgrimes * have been fully allocated yet. 2141541Srgrimes */ 2151541Srgrimes if (fdp->fd_nfiles < lim) 2161541Srgrimes freefd += (lim - fdp->fd_nfiles); 2171541Srgrimes 2181541Srgrimes sbp->f_type = MOUNT_FDESC; 2191541Srgrimes sbp->f_flags = 0; 2201541Srgrimes sbp->f_bsize = DEV_BSIZE; 2211541Srgrimes sbp->f_iosize = DEV_BSIZE; 2221541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2231541Srgrimes sbp->f_bfree = 0; 2241541Srgrimes sbp->f_bavail = 0; 2251541Srgrimes sbp->f_files = lim + 1; /* Allow for "." */ 2261541Srgrimes sbp->f_ffree = freefd; /* See comments above */ 2271541Srgrimes if (sbp != &mp->mnt_stat) { 2281541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2291541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2301541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2311541Srgrimes } 2321541Srgrimes return (0); 2331541Srgrimes} 2341541Srgrimes 2351541Srgrimesint 2361541Srgrimesfdesc_sync(mp, waitfor) 2371541Srgrimes struct mount *mp; 2381541Srgrimes int waitfor; 2391541Srgrimes{ 2401541Srgrimes 2411541Srgrimes return (0); 2421541Srgrimes} 2431541Srgrimes 2441541Srgrimes/* 2451541Srgrimes * Fdesc flat namespace lookup. 2461541Srgrimes * Currently unsupported. 2471541Srgrimes */ 2481541Srgrimesint 2491541Srgrimesfdesc_vget(mp, ino, vpp) 2501541Srgrimes struct mount *mp; 2511541Srgrimes ino_t ino; 2521541Srgrimes struct vnode **vpp; 2531541Srgrimes{ 2541541Srgrimes 2551541Srgrimes return (EOPNOTSUPP); 2561541Srgrimes} 2571541Srgrimes 2581541Srgrimesint 2591541Srgrimesfdesc_fhtovp(mp, fhp, setgen, vpp) 2601541Srgrimes struct mount *mp; 2611541Srgrimes struct fid *fhp; 2621541Srgrimes int setgen; 2631541Srgrimes struct vnode **vpp; 2641541Srgrimes{ 2651541Srgrimes return (EOPNOTSUPP); 2661541Srgrimes} 2671541Srgrimes 2681541Srgrimesint 2691541Srgrimesfdesc_vptofh(vp, fhp) 2701541Srgrimes struct vnode *vp; 2711541Srgrimes struct fid *fhp; 2721541Srgrimes{ 2731541Srgrimes 2741541Srgrimes return (EOPNOTSUPP); 2751541Srgrimes} 2761541Srgrimes 2771541Srgrimesstruct vfsops fdesc_vfsops = { 2781541Srgrimes fdesc_mount, 2791541Srgrimes fdesc_start, 2801541Srgrimes fdesc_unmount, 2811541Srgrimes fdesc_root, 2821541Srgrimes fdesc_quotactl, 2831541Srgrimes fdesc_statfs, 2841541Srgrimes fdesc_sync, 2851541Srgrimes fdesc_vget, 2861541Srgrimes fdesc_fhtovp, 2871541Srgrimes fdesc_vptofh, 2881541Srgrimes fdesc_init, 2891541Srgrimes}; 2902946Swollman 2912946SwollmanVFS_SET(fdesc_vfsops, fdesc, MOUNT_FDESC, 0); 292