fdesc_vfsops.c revision 76688
11541Srgrimes/* 222521Sdyson * Copyright (c) 1992, 1993, 1995 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 * 3850477Speter * $FreeBSD: head/sys/fs/fdescfs/fdesc_vfsops.c 76688 2001-05-16 18:04:37Z iedowse $ 391541Srgrimes */ 401541Srgrimes 411541Srgrimes/* 421541Srgrimes * /dev/fd Filesystem 431541Srgrimes */ 441541Srgrimes 451541Srgrimes#include <sys/param.h> 461541Srgrimes#include <sys/systm.h> 4776166Smarkm#include <sys/filedesc.h> 482946Swollman#include <sys/kernel.h> 4976166Smarkm#include <sys/lock.h> 5076166Smarkm#include <sys/malloc.h> 5176166Smarkm#include <sys/mount.h> 521541Srgrimes#include <sys/proc.h> 531541Srgrimes#include <sys/resourcevar.h> 5476166Smarkm#include <sys/socket.h> 551541Srgrimes#include <sys/vnode.h> 5676166Smarkm 571541Srgrimes#include <miscfs/fdesc/fdesc.h> 581541Srgrimes 5930354Sphkstatic MALLOC_DEFINE(M_FDESCMNT, "FDESC mount", "FDESC mount structure"); 6030354Sphk 6112333Sbdestatic int fdesc_mount __P((struct mount *mp, char *path, caddr_t data, 6212333Sbde struct nameidata *ndp, struct proc *p)); 6312333Sbdestatic int fdesc_unmount __P((struct mount *mp, int mntflags, 6412333Sbde struct proc *p)); 6512333Sbdestatic int fdesc_statfs __P((struct mount *mp, struct statfs *sbp, 6612333Sbde struct proc *p)); 6712333Sbde 681541Srgrimes/* 691541Srgrimes * Mount the per-process file descriptors (/dev/fd) 701541Srgrimes */ 7112143Sphkstatic int 721541Srgrimesfdesc_mount(mp, path, data, ndp, p) 731541Srgrimes struct mount *mp; 741541Srgrimes char *path; 751541Srgrimes caddr_t data; 761541Srgrimes struct nameidata *ndp; 771541Srgrimes struct proc *p; 781541Srgrimes{ 791541Srgrimes int error = 0; 801541Srgrimes struct fdescmount *fmp; 811541Srgrimes struct vnode *rvp; 821541Srgrimes 831541Srgrimes /* 841541Srgrimes * Update is a no-op 851541Srgrimes */ 861541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 871541Srgrimes return (EOPNOTSUPP); 881541Srgrimes 8966894Schris error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, p); 901541Srgrimes if (error) 911541Srgrimes return (error); 921541Srgrimes 931541Srgrimes MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 9430354Sphk M_FDESCMNT, M_WAITOK); /* XXX */ 951541Srgrimes rvp->v_type = VDIR; 961541Srgrimes rvp->v_flag |= VROOT; 971541Srgrimes fmp->f_root = rvp; 981541Srgrimes /* XXX -- don't mark as local to work around fts() problems */ 991541Srgrimes /*mp->mnt_flag |= MNT_LOCAL;*/ 1001541Srgrimes mp->mnt_data = (qaddr_t) fmp; 10122521Sdyson vfs_getnewfsid(mp); 1021541Srgrimes 1031541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1041541Srgrimes bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 10510533Smpp (void)fdesc_statfs(mp, &mp->mnt_stat, p); 1061541Srgrimes return (0); 1071541Srgrimes} 1081541Srgrimes 10912143Sphkstatic int 1101541Srgrimesfdesc_unmount(mp, mntflags, p) 1111541Srgrimes struct mount *mp; 1121541Srgrimes int mntflags; 1131541Srgrimes struct proc *p; 1141541Srgrimes{ 1151541Srgrimes int error; 1161541Srgrimes int flags = 0; 1171541Srgrimes 11822521Sdyson if (mntflags & MNT_FORCE) 1191541Srgrimes flags |= FORCECLOSE; 1201541Srgrimes 1211541Srgrimes /* 1221541Srgrimes * Clear out buffer cache. I don't think we 1231541Srgrimes * ever get anything cached at this level at the 1241541Srgrimes * moment, but who knows... 12576688Siedowse * 12676688Siedowse * There is 1 extra root vnode reference corresponding 12776688Siedowse * to f_root. 1281541Srgrimes */ 12976688Siedowse if ((error = vflush(mp, 1, flags)) != 0) 1301541Srgrimes return (error); 1311541Srgrimes 1321541Srgrimes /* 1331541Srgrimes * Finally, throw away the fdescmount structure 1341541Srgrimes */ 13530354Sphk free(mp->mnt_data, M_FDESCMNT); /* XXX */ 1361541Srgrimes mp->mnt_data = 0; 1371541Srgrimes 1381541Srgrimes return (0); 1391541Srgrimes} 1401541Srgrimes 1411541Srgrimesint 1421541Srgrimesfdesc_root(mp, vpp) 1431541Srgrimes struct mount *mp; 1441541Srgrimes struct vnode **vpp; 1451541Srgrimes{ 14622521Sdyson struct proc *p = curproc; /* XXX */ 1471541Srgrimes struct vnode *vp; 1481541Srgrimes 1491541Srgrimes /* 1501541Srgrimes * Return locked reference to root. 1511541Srgrimes */ 1521541Srgrimes vp = VFSTOFDESC(mp)->f_root; 1531541Srgrimes VREF(vp); 15422521Sdyson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1551541Srgrimes *vpp = vp; 1561541Srgrimes return (0); 1571541Srgrimes} 1581541Srgrimes 15912143Sphkstatic int 1601541Srgrimesfdesc_statfs(mp, sbp, p) 1611541Srgrimes struct mount *mp; 1621541Srgrimes struct statfs *sbp; 1631541Srgrimes struct proc *p; 1641541Srgrimes{ 1651541Srgrimes struct filedesc *fdp; 1661541Srgrimes int lim; 1671541Srgrimes int i; 1681541Srgrimes int last; 1691541Srgrimes int freefd; 1701541Srgrimes 1711541Srgrimes /* 1721541Srgrimes * Compute number of free file descriptors. 1731541Srgrimes * [ Strange results will ensue if the open file 1741541Srgrimes * limit is ever reduced below the current number 1751541Srgrimes * of open files... ] 1761541Srgrimes */ 1771541Srgrimes lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 1781541Srgrimes fdp = p->p_fd; 1791541Srgrimes last = min(fdp->fd_nfiles, lim); 1801541Srgrimes freefd = 0; 1811541Srgrimes for (i = fdp->fd_freefile; i < last; i++) 1821541Srgrimes if (fdp->fd_ofiles[i] == NULL) 1831541Srgrimes freefd++; 1841541Srgrimes 1851541Srgrimes /* 1861541Srgrimes * Adjust for the fact that the fdesc array may not 1871541Srgrimes * have been fully allocated yet. 1881541Srgrimes */ 1891541Srgrimes if (fdp->fd_nfiles < lim) 1901541Srgrimes freefd += (lim - fdp->fd_nfiles); 1911541Srgrimes 1921541Srgrimes sbp->f_flags = 0; 1931541Srgrimes sbp->f_bsize = DEV_BSIZE; 1941541Srgrimes sbp->f_iosize = DEV_BSIZE; 1951541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 1961541Srgrimes sbp->f_bfree = 0; 1971541Srgrimes sbp->f_bavail = 0; 1981541Srgrimes sbp->f_files = lim + 1; /* Allow for "." */ 1991541Srgrimes sbp->f_ffree = freefd; /* See comments above */ 2001541Srgrimes if (sbp != &mp->mnt_stat) { 20122521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2021541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2031541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2041541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2051541Srgrimes } 2061541Srgrimes return (0); 2071541Srgrimes} 2081541Srgrimes 20912143Sphkstatic struct vfsops fdesc_vfsops = { 2101541Srgrimes fdesc_mount, 21151068Salfred vfs_stdstart, 2121541Srgrimes fdesc_unmount, 2131541Srgrimes fdesc_root, 21451068Salfred vfs_stdquotactl, 2151541Srgrimes fdesc_statfs, 21651068Salfred vfs_stdsync, 21751068Salfred vfs_stdvget, 21851068Salfred vfs_stdfhtovp, 21951138Salfred vfs_stdcheckexp, 22051068Salfred vfs_stdvptofh, 2211541Srgrimes fdesc_init, 22254803Srwatson vfs_stduninit, 22354803Srwatson vfs_stdextattrctl, 2241541Srgrimes}; 2252946Swollman 22638909SbdeVFS_SET(fdesc_vfsops, fdesc, VFCF_SYNTHETIC); 227