fdesc_vfsops.c revision 125454
1155192Srwatson/* 2155192Srwatson * Copyright (c) 1992, 1993, 1995 3155192Srwatson * The Regents of the University of California. All rights reserved. 4155192Srwatson * 5155192Srwatson * This code is derived from software donated to Berkeley by 6155192Srwatson * Jan-Simon Pendry. 7155192Srwatson * 8155192Srwatson * Redistribution and use in source and binary forms, with or without 9155192Srwatson * modification, are permitted provided that the following conditions 10155192Srwatson * are met: 11155192Srwatson * 1. Redistributions of source code must retain the above copyright 12155192Srwatson * notice, this list of conditions and the following disclaimer. 13155192Srwatson * 2. Redistributions in binary form must reproduce the above copyright 14155192Srwatson * notice, this list of conditions and the following disclaimer in the 15155192Srwatson * documentation and/or other materials provided with the distribution. 16155192Srwatson * 3. All advertising materials mentioning features or use of this software 17155192Srwatson * must display the following acknowledgement: 18155192Srwatson * This product includes software developed by the University of 19155192Srwatson * California, Berkeley and its contributors. 20155192Srwatson * 4. Neither the name of the University nor the names of its contributors 21155192Srwatson * may be used to endorse or promote products derived from this software 22155192Srwatson * without specific prior written permission. 23155192Srwatson * 24155192Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28155192Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30178186Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31178186Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32178186Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33155192Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34155192Srwatson * SUCH DAMAGE. 35155192Srwatson * 36155192Srwatson * @(#)fdesc_vfsops.c 8.4 (Berkeley) 1/21/94 37155192Srwatson * 38155192Srwatson * $FreeBSD: head/sys/fs/fdescfs/fdesc_vfsops.c 125454 2004-02-04 21:52:57Z jhb $ 39155192Srwatson */ 40160136Swsalamon 41155192Srwatson/* 42155192Srwatson * /dev/fd Filesystem 43155192Srwatson */ 44155192Srwatson 45155192Srwatson#include <sys/param.h> 46155192Srwatson#include <sys/systm.h> 47155192Srwatson#include <sys/filedesc.h> 48155192Srwatson#include <sys/kernel.h> 49155192Srwatson#include <sys/lock.h> 50155192Srwatson#include <sys/mutex.h> 51155192Srwatson#include <sys/malloc.h> 52155192Srwatson#include <sys/mount.h> 53155192Srwatson#include <sys/proc.h> 54155192Srwatson#include <sys/resourcevar.h> 55155192Srwatson#include <sys/vnode.h> 56155192Srwatson 57155192Srwatson#include <fs/fdescfs/fdesc.h> 58155192Srwatson 59155192Srwatsonstatic MALLOC_DEFINE(M_FDESCMNT, "FDESC mount", "FDESC mount structure"); 60155192Srwatson 61155192Srwatsonstatic vfs_nmount_t fdesc_mount; 62155192Srwatsonstatic vfs_unmount_t fdesc_unmount; 63155192Srwatsonstatic vfs_statfs_t fdesc_statfs; 64155192Srwatson 65155192Srwatson/* 66155192Srwatson * Mount the per-process file descriptors (/dev/fd) 67155192Srwatson */ 68155192Srwatsonstatic int 69155192Srwatsonfdesc_mount(mp, ndp, td) 70155192Srwatson struct mount *mp; 71155192Srwatson struct nameidata *ndp; 72155192Srwatson struct thread *td; 73156889Srwatson{ 74156889Srwatson int error = 0; 75156889Srwatson struct fdescmount *fmp; 76156889Srwatson struct vnode *rvp; 77156889Srwatson 78156889Srwatson /* 79155192Srwatson * Update is a no-op 80156889Srwatson */ 81155192Srwatson if (mp->mnt_flag & MNT_UPDATE) 82156889Srwatson return (EOPNOTSUPP); 83155192Srwatson 84162466Srwatson error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, td); 85155192Srwatson if (error) 86155192Srwatson return (error); 87155192Srwatson 88155192Srwatson MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 89155192Srwatson M_FDESCMNT, M_WAITOK); /* XXX */ 90155192Srwatson rvp->v_type = VDIR; 91155192Srwatson rvp->v_vflag |= VV_ROOT; 92155192Srwatson fmp->f_root = rvp; 93155192Srwatson /* XXX -- don't mark as local to work around fts() problems */ 94156889Srwatson /*mp->mnt_flag |= MNT_LOCAL;*/ 95155192Srwatson mp->mnt_data = (qaddr_t) fmp; 96155192Srwatson vfs_getnewfsid(mp); 97155192Srwatson 98155192Srwatson bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 99155192Srwatson bcopy("fdescfs", mp->mnt_stat.f_mntfromname, sizeof("fdescfs")); 100155192Srwatson (void)fdesc_statfs(mp, &mp->mnt_stat, td); 101155192Srwatson return (0); 102155192Srwatson} 103155192Srwatson 104155192Srwatsonstatic int 105155192Srwatsonfdesc_unmount(mp, mntflags, td) 106155192Srwatson struct mount *mp; 107155192Srwatson int mntflags; 108155192Srwatson struct thread *td; 109155192Srwatson{ 110155192Srwatson int error; 111155192Srwatson int flags = 0; 112155192Srwatson 113155192Srwatson if (mntflags & MNT_FORCE) 114155192Srwatson flags |= FORCECLOSE; 115155192Srwatson 116156889Srwatson /* 117161635Srwatson * Clear out buffer cache. I don't think we 118162466Srwatson * ever get anything cached at this level at the 119170196Srwatson * moment, but who knows... 120162466Srwatson * 121162466Srwatson * There is 1 extra root vnode reference corresponding 122162466Srwatson * to f_root. 123162466Srwatson */ 124155192Srwatson if ((error = vflush(mp, 1, flags)) != 0) 125162466Srwatson return (error); 126162466Srwatson 127155192Srwatson /* 128162466Srwatson * Finally, throw away the fdescmount structure 129162466Srwatson */ 130162466Srwatson free(mp->mnt_data, M_FDESCMNT); /* XXX */ 131162466Srwatson mp->mnt_data = 0; 132162466Srwatson 133155192Srwatson return (0); 134155192Srwatson} 135155192Srwatson 136155192Srwatsonint 137156889Srwatsonfdesc_root(mp, vpp) 138156889Srwatson struct mount *mp; 139155192Srwatson struct vnode **vpp; 140155192Srwatson{ 141155192Srwatson struct thread *td = curthread; /* XXX */ 142155192Srwatson struct vnode *vp; 143155192Srwatson 144155192Srwatson /* 145156889Srwatson * Return locked reference to root. 146155192Srwatson */ 147155192Srwatson vp = VFSTOFDESC(mp)->f_root; 148155192Srwatson VREF(vp); 149155192Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 150156889Srwatson *vpp = vp; 151155192Srwatson return (0); 152155192Srwatson} 153156889Srwatson 154155192Srwatsonstatic int 155155192Srwatsonfdesc_statfs(mp, sbp, td) 156155192Srwatson struct mount *mp; 157155192Srwatson struct statfs *sbp; 158155192Srwatson struct thread *td; 159170196Srwatson{ 160155192Srwatson struct filedesc *fdp; 161155192Srwatson int lim; 162155192Srwatson int i; 163155192Srwatson int last; 164155192Srwatson int freefd; 165155192Srwatson 166155192Srwatson /* 167155192Srwatson * Compute number of free file descriptors. 168155192Srwatson * [ Strange results will ensue if the open file 169155192Srwatson * limit is ever reduced below the current number 170155192Srwatson * of open files... ] 171155192Srwatson */ 172155192Srwatson PROC_LOCK(td->td_proc); 173155192Srwatson lim = lim_cur(td->td_proc, RLIMIT_NOFILE); 174155192Srwatson PROC_UNLOCK(td->td_proc); 175155192Srwatson fdp = td->td_proc->p_fd; 176155192Srwatson FILEDESC_LOCK(fdp); 177155192Srwatson last = min(fdp->fd_nfiles, lim); 178155192Srwatson freefd = 0; 179155192Srwatson for (i = fdp->fd_freefile; i < last; i++) 180155192Srwatson if (fdp->fd_ofiles[i] == NULL) 181155192Srwatson freefd++; 182155192Srwatson 183155192Srwatson /* 184155192Srwatson * Adjust for the fact that the fdesc array may not 185155192Srwatson * have been fully allocated yet. 186155192Srwatson */ 187155192Srwatson if (fdp->fd_nfiles < lim) 188155192Srwatson freefd += (lim - fdp->fd_nfiles); 189155192Srwatson FILEDESC_UNLOCK(fdp); 190155192Srwatson 191155192Srwatson sbp->f_flags = 0; 192155192Srwatson sbp->f_bsize = DEV_BSIZE; 193155192Srwatson sbp->f_iosize = DEV_BSIZE; 194155192Srwatson sbp->f_blocks = 2; /* 1K to keep df happy */ 195155192Srwatson sbp->f_bfree = 0; 196155192Srwatson sbp->f_bavail = 0; 197155192Srwatson sbp->f_files = lim + 1; /* Allow for "." */ 198155192Srwatson sbp->f_ffree = freefd; /* See comments above */ 199155192Srwatson if (sbp != &mp->mnt_stat) { 200155192Srwatson sbp->f_type = mp->mnt_vfc->vfc_typenum; 201155192Srwatson bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 202155192Srwatson bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 203155192Srwatson bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 204155192Srwatson } 205155192Srwatson return (0); 206155192Srwatson} 207155192Srwatson 208155192Srwatsonstatic struct vfsops fdesc_vfsops = { 209155192Srwatson .vfs_init = fdesc_init, 210155192Srwatson .vfs_nmount = fdesc_mount, 211155192Srwatson .vfs_root = fdesc_root, 212155192Srwatson .vfs_statfs = fdesc_statfs, 213156889Srwatson .vfs_unmount = fdesc_unmount, 214156889Srwatson}; 215155192Srwatson 216155192SrwatsonVFS_SET(fdesc_vfsops, fdescfs, VFCF_SYNTHETIC); 217155192Srwatson