fdesc_vfsops.c revision 1541
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 * 381541Srgrimes * $Id: fdesc_vfsops.c,v 1.9 1993/04/06 15:28:33 jsp Exp $ 391541Srgrimes */ 401541Srgrimes 411541Srgrimes/* 421541Srgrimes * /dev/fd Filesystem 431541Srgrimes */ 441541Srgrimes 451541Srgrimes#include <sys/param.h> 461541Srgrimes#include <sys/systm.h> 471541Srgrimes#include <sys/time.h> 481541Srgrimes#include <sys/types.h> 491541Srgrimes#include <sys/proc.h> 501541Srgrimes#include <sys/resourcevar.h> 511541Srgrimes#include <sys/filedesc.h> 521541Srgrimes#include <sys/vnode.h> 531541Srgrimes#include <sys/mount.h> 541541Srgrimes#include <sys/namei.h> 551541Srgrimes#include <sys/malloc.h> 561541Srgrimes#include <miscfs/fdesc/fdesc.h> 571541Srgrimes 581541Srgrimes/* 591541Srgrimes * Mount the per-process file descriptors (/dev/fd) 601541Srgrimes */ 611541Srgrimesint 621541Srgrimesfdesc_mount(mp, path, data, ndp, p) 631541Srgrimes struct mount *mp; 641541Srgrimes char *path; 651541Srgrimes caddr_t data; 661541Srgrimes struct nameidata *ndp; 671541Srgrimes struct proc *p; 681541Srgrimes{ 691541Srgrimes int error = 0; 701541Srgrimes u_int size; 711541Srgrimes struct fdescmount *fmp; 721541Srgrimes struct vnode *rvp; 731541Srgrimes 741541Srgrimes /* 751541Srgrimes * Update is a no-op 761541Srgrimes */ 771541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 781541Srgrimes return (EOPNOTSUPP); 791541Srgrimes 801541Srgrimes error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 811541Srgrimes if (error) 821541Srgrimes return (error); 831541Srgrimes 841541Srgrimes MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 851541Srgrimes M_UFSMNT, M_WAITOK); /* XXX */ 861541Srgrimes rvp->v_type = VDIR; 871541Srgrimes rvp->v_flag |= VROOT; 881541Srgrimes fmp->f_root = rvp; 891541Srgrimes /* XXX -- don't mark as local to work around fts() problems */ 901541Srgrimes /*mp->mnt_flag |= MNT_LOCAL;*/ 911541Srgrimes mp->mnt_data = (qaddr_t) fmp; 921541Srgrimes getnewfsid(mp, MOUNT_FDESC); 931541Srgrimes 941541Srgrimes (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 951541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 961541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 971541Srgrimes bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 981541Srgrimes return (0); 991541Srgrimes} 1001541Srgrimes 1011541Srgrimesint 1021541Srgrimesfdesc_start(mp, flags, p) 1031541Srgrimes struct mount *mp; 1041541Srgrimes int flags; 1051541Srgrimes struct proc *p; 1061541Srgrimes{ 1071541Srgrimes return (0); 1081541Srgrimes} 1091541Srgrimes 1101541Srgrimesint 1111541Srgrimesfdesc_unmount(mp, mntflags, p) 1121541Srgrimes struct mount *mp; 1131541Srgrimes int mntflags; 1141541Srgrimes struct proc *p; 1151541Srgrimes{ 1161541Srgrimes int error; 1171541Srgrimes int flags = 0; 1181541Srgrimes extern int doforce; 1191541Srgrimes struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 1201541Srgrimes 1211541Srgrimes if (mntflags & MNT_FORCE) { 1221541Srgrimes /* fdesc can never be rootfs so don't check for it */ 1231541Srgrimes if (!doforce) 1241541Srgrimes return (EINVAL); 1251541Srgrimes flags |= FORCECLOSE; 1261541Srgrimes } 1271541Srgrimes 1281541Srgrimes /* 1291541Srgrimes * Clear out buffer cache. I don't think we 1301541Srgrimes * ever get anything cached at this level at the 1311541Srgrimes * moment, but who knows... 1321541Srgrimes */ 1331541Srgrimes if (rootvp->v_usecount > 1) 1341541Srgrimes return (EBUSY); 1351541Srgrimes if (error = vflush(mp, rootvp, flags)) 1361541Srgrimes return (error); 1371541Srgrimes 1381541Srgrimes /* 1391541Srgrimes * Release reference on underlying root vnode 1401541Srgrimes */ 1411541Srgrimes vrele(rootvp); 1421541Srgrimes /* 1431541Srgrimes * And blow it away for future re-use 1441541Srgrimes */ 1451541Srgrimes vgone(rootvp); 1461541Srgrimes /* 1471541Srgrimes * Finally, throw away the fdescmount structure 1481541Srgrimes */ 1491541Srgrimes free(mp->mnt_data, M_UFSMNT); /* XXX */ 1501541Srgrimes mp->mnt_data = 0; 1511541Srgrimes 1521541Srgrimes return (0); 1531541Srgrimes} 1541541Srgrimes 1551541Srgrimesint 1561541Srgrimesfdesc_root(mp, vpp) 1571541Srgrimes struct mount *mp; 1581541Srgrimes struct vnode **vpp; 1591541Srgrimes{ 1601541Srgrimes struct vnode *vp; 1611541Srgrimes 1621541Srgrimes /* 1631541Srgrimes * Return locked reference to root. 1641541Srgrimes */ 1651541Srgrimes vp = VFSTOFDESC(mp)->f_root; 1661541Srgrimes VREF(vp); 1671541Srgrimes VOP_LOCK(vp); 1681541Srgrimes *vpp = vp; 1691541Srgrimes return (0); 1701541Srgrimes} 1711541Srgrimes 1721541Srgrimesint 1731541Srgrimesfdesc_quotactl(mp, cmd, uid, arg, p) 1741541Srgrimes struct mount *mp; 1751541Srgrimes int cmd; 1761541Srgrimes uid_t uid; 1771541Srgrimes caddr_t arg; 1781541Srgrimes struct proc *p; 1791541Srgrimes{ 1801541Srgrimes 1811541Srgrimes return (EOPNOTSUPP); 1821541Srgrimes} 1831541Srgrimes 1841541Srgrimesint 1851541Srgrimesfdesc_statfs(mp, sbp, p) 1861541Srgrimes struct mount *mp; 1871541Srgrimes struct statfs *sbp; 1881541Srgrimes struct proc *p; 1891541Srgrimes{ 1901541Srgrimes struct filedesc *fdp; 1911541Srgrimes int lim; 1921541Srgrimes int i; 1931541Srgrimes int last; 1941541Srgrimes int freefd; 1951541Srgrimes 1961541Srgrimes /* 1971541Srgrimes * Compute number of free file descriptors. 1981541Srgrimes * [ Strange results will ensue if the open file 1991541Srgrimes * limit is ever reduced below the current number 2001541Srgrimes * of open files... ] 2011541Srgrimes */ 2021541Srgrimes lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 2031541Srgrimes fdp = p->p_fd; 2041541Srgrimes last = min(fdp->fd_nfiles, lim); 2051541Srgrimes freefd = 0; 2061541Srgrimes for (i = fdp->fd_freefile; i < last; i++) 2071541Srgrimes if (fdp->fd_ofiles[i] == NULL) 2081541Srgrimes freefd++; 2091541Srgrimes 2101541Srgrimes /* 2111541Srgrimes * Adjust for the fact that the fdesc array may not 2121541Srgrimes * have been fully allocated yet. 2131541Srgrimes */ 2141541Srgrimes if (fdp->fd_nfiles < lim) 2151541Srgrimes freefd += (lim - fdp->fd_nfiles); 2161541Srgrimes 2171541Srgrimes sbp->f_type = MOUNT_FDESC; 2181541Srgrimes sbp->f_flags = 0; 2191541Srgrimes sbp->f_bsize = DEV_BSIZE; 2201541Srgrimes sbp->f_iosize = DEV_BSIZE; 2211541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2221541Srgrimes sbp->f_bfree = 0; 2231541Srgrimes sbp->f_bavail = 0; 2241541Srgrimes sbp->f_files = lim + 1; /* Allow for "." */ 2251541Srgrimes sbp->f_ffree = freefd; /* See comments above */ 2261541Srgrimes if (sbp != &mp->mnt_stat) { 2271541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2281541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2291541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2301541Srgrimes } 2311541Srgrimes return (0); 2321541Srgrimes} 2331541Srgrimes 2341541Srgrimesint 2351541Srgrimesfdesc_sync(mp, waitfor) 2361541Srgrimes struct mount *mp; 2371541Srgrimes int waitfor; 2381541Srgrimes{ 2391541Srgrimes 2401541Srgrimes return (0); 2411541Srgrimes} 2421541Srgrimes 2431541Srgrimes/* 2441541Srgrimes * Fdesc flat namespace lookup. 2451541Srgrimes * Currently unsupported. 2461541Srgrimes */ 2471541Srgrimesint 2481541Srgrimesfdesc_vget(mp, ino, vpp) 2491541Srgrimes struct mount *mp; 2501541Srgrimes ino_t ino; 2511541Srgrimes struct vnode **vpp; 2521541Srgrimes{ 2531541Srgrimes 2541541Srgrimes return (EOPNOTSUPP); 2551541Srgrimes} 2561541Srgrimes 2571541Srgrimesint 2581541Srgrimesfdesc_fhtovp(mp, fhp, setgen, vpp) 2591541Srgrimes struct mount *mp; 2601541Srgrimes struct fid *fhp; 2611541Srgrimes int setgen; 2621541Srgrimes struct vnode **vpp; 2631541Srgrimes{ 2641541Srgrimes return (EOPNOTSUPP); 2651541Srgrimes} 2661541Srgrimes 2671541Srgrimesint 2681541Srgrimesfdesc_vptofh(vp, fhp) 2691541Srgrimes struct vnode *vp; 2701541Srgrimes struct fid *fhp; 2711541Srgrimes{ 2721541Srgrimes 2731541Srgrimes return (EOPNOTSUPP); 2741541Srgrimes} 2751541Srgrimes 2761541Srgrimesstruct vfsops fdesc_vfsops = { 2771541Srgrimes fdesc_mount, 2781541Srgrimes fdesc_start, 2791541Srgrimes fdesc_unmount, 2801541Srgrimes fdesc_root, 2811541Srgrimes fdesc_quotactl, 2821541Srgrimes fdesc_statfs, 2831541Srgrimes fdesc_sync, 2841541Srgrimes fdesc_vget, 2851541Srgrimes fdesc_fhtovp, 2861541Srgrimes fdesc_vptofh, 2871541Srgrimes fdesc_init, 2881541Srgrimes}; 289