fdesc_vfsops.c revision 158611
1119404Ssos/*- 2230132Suqs * Copyright (c) 1992, 1993, 1995 3119404Ssos * The Regents of the University of California. All rights reserved. 4119404Ssos * 5119404Ssos * This code is derived from software donated to Berkeley by 6119404Ssos * Jan-Simon Pendry. 7119404Ssos * 8119404Ssos * Redistribution and use in source and binary forms, with or without 9119404Ssos * modification, are permitted provided that the following conditions 10119404Ssos * are met: 11119404Ssos * 1. Redistributions of source code must retain the above copyright 12119404Ssos * notice, this list of conditions and the following disclaimer. 13119404Ssos * 2. Redistributions in binary form must reproduce the above copyright 14119404Ssos * notice, this list of conditions and the following disclaimer in the 15119404Ssos * documentation and/or other materials provided with the distribution. 16119404Ssos * 4. Neither the name of the University nor the names of its contributors 17119404Ssos * may be used to endorse or promote products derived from this software 18119404Ssos * without specific prior written permission. 19119404Ssos * 20119404Ssos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21119404Ssos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22119404Ssos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23119404Ssos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24119404Ssos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25119404Ssos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26119404Ssos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27119418Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28119418Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29119418Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30119404Ssos * SUCH DAMAGE. 31119404Ssos * 32144330Ssos * @(#)fdesc_vfsops.c 8.4 (Berkeley) 1/21/94 33144330Ssos * 34119404Ssos * $FreeBSD: head/sys/fs/fdescfs/fdesc_vfsops.c 158611 2006-05-15 19:42:10Z kbyanc $ 35119404Ssos */ 36144330Ssos 37119404Ssos/* 38124403Ssos * /dev/fd Filesystem 39119404Ssos */ 40124534Ssos 41119404Ssos#include <sys/param.h> 42119404Ssos#include <sys/systm.h> 43119404Ssos#include <sys/filedesc.h> 44144330Ssos#include <sys/kernel.h> 45144330Ssos#include <sys/lock.h> 46119404Ssos#include <sys/mutex.h> 47119404Ssos#include <sys/malloc.h> 48154507Ssos#include <sys/mount.h> 49198717Smav#include <sys/proc.h> 50119450Ssos#include <sys/resourcevar.h> 51119450Ssos#include <sys/vnode.h> 52174576Ssos 53174576Ssos#include <fs/fdescfs/fdesc.h> 54119404Ssos 55119404Ssosstatic MALLOC_DEFINE(M_FDESCMNT, "fdesc_mount", "FDESC mount structure"); 56119404Ssos 57119404Ssosstatic vfs_cmount_t fdesc_cmount; 58119404Ssosstatic vfs_mount_t fdesc_mount; 59145713Ssosstatic vfs_unmount_t fdesc_unmount; 60119404Ssosstatic vfs_statfs_t fdesc_statfs; 61145713Ssosstatic vfs_root_t fdesc_root; 62145713Ssos 63135819Ssos/* 64135819Ssos * Compatibility shim for old mount(2) system call. 65154507Ssos */ 66178067Ssosint 67128183Ssosfdesc_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) 68174576Ssos{ 69174576Ssos return kernel_mount(ma, flags); 70178067Ssos} 71178067Ssos 72119404Ssos/* 73119404Ssos * Mount the per-process file descriptors (/dev/fd) 74145354Ssos */ 75154507Ssosstatic int 76135819Ssosfdesc_mount(struct mount *mp, struct thread *td) 77119404Ssos{ 78178067Ssos int error = 0; 79153142Ssos struct fdescmount *fmp; 80128183Ssos struct vnode *rvp; 81135819Ssos 82124403Ssos /* 83119404Ssos * Update is a no-op 84200171Smav */ 85200171Smav if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) 86200171Smav return (EOPNOTSUPP); 87128183Ssos 88120938Ssos error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp, td); 89120938Ssos if (error) 90119404Ssos return (error); 91119404Ssos 92119404Ssos MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 93119404Ssos M_FDESCMNT, M_WAITOK); /* XXX */ 94119404Ssos rvp->v_type = VDIR; 95119404Ssos rvp->v_vflag |= VV_ROOT; 96119404Ssos fmp->f_root = rvp; 97124403Ssos /* XXX -- don't mark as local to work around fts() problems */ 98119404Ssos /*mp->mnt_flag |= MNT_LOCAL;*/ 99119404Ssos mp->mnt_data = (qaddr_t) fmp; 100119404Ssos vfs_getnewfsid(mp); 101145818Ssos 102198717Smav vfs_mountedfrom(mp, "fdescfs"); 103133834Ssos return (0); 104119404Ssos} 105145354Ssos 106119404Ssosstatic int 107119404Ssosfdesc_unmount(mp, mntflags, td) 108132582Ssos struct mount *mp; 109144330Ssos int mntflags; 110168430Ssos struct thread *td; 111132606Ssos{ 112132606Ssos int error; 113132606Ssos int flags = 0; 114132606Ssos 115132606Ssos if (mntflags & MNT_FORCE) 116133184Ssos flags |= FORCECLOSE; 117132582Ssos 118242156Smav /* 119145354Ssos * Clear out buffer cache. I don't think we 120132582Ssos * ever get anything cached at this level at the 121132582Ssos * moment, but who knows... 122119404Ssos * 123119404Ssos * There is 1 extra root vnode reference corresponding 124198717Smav * to f_root. 125198717Smav */ 126150129Ssos if ((error = vflush(mp, 1, flags, td)) != 0) 127119404Ssos return (error); 128145354Ssos 129119404Ssos /* 130119404Ssos * Finally, throw away the fdescmount structure 131119404Ssos */ 132119404Ssos free(mp->mnt_data, M_FDESCMNT); /* XXX */ 133145354Ssos mp->mnt_data = 0; 134119404Ssos 135119404Ssos return (0); 136119404Ssos} 137121310Ssos 138178067Ssosstatic int 139198717Smavfdesc_root(mp, flags, vpp, td) 140153142Ssos struct mount *mp; 141145354Ssos int flags; 142119404Ssos struct vnode **vpp; 143119404Ssos struct thread *td; 144208870Snwhitehorn{ 145208870Snwhitehorn struct vnode *vp; 146208870Snwhitehorn 147208870Snwhitehorn /* 148208870Snwhitehorn * Return locked reference to root. 149208870Snwhitehorn */ 150208870Snwhitehorn vp = VFSTOFDESC(mp)->f_root; 151208870Snwhitehorn VREF(vp); 152119404Ssos vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 153145818Ssos *vpp = vp; 154198717Smav return (0); 155133834Ssos} 156119404Ssos 157145354Ssosstatic int 158119404Ssosfdesc_statfs(mp, sbp, td) 159119404Ssos struct mount *mp; 160119404Ssos struct statfs *sbp; 161208870Snwhitehorn struct thread *td; 162208870Snwhitehorn{ 163198717Smav struct filedesc *fdp; 164119404Ssos int lim; 165145354Ssos int i; 166119404Ssos int last; 167145354Ssos int freefd; 168119404Ssos 169119404Ssos /* 170119404Ssos * Compute number of free file descriptors. 171119404Ssos * [ Strange results will ensue if the open file 172119404Ssos * limit is ever reduced below the current number 173198717Smav * of open files... ] 174119404Ssos */ 175144707Ssos PROC_LOCK(td->td_proc); 176119404Ssos lim = lim_cur(td->td_proc, RLIMIT_NOFILE); 177145354Ssos PROC_UNLOCK(td->td_proc); 178119404Ssos fdp = td->td_proc->p_fd; 179119404Ssos FILEDESC_LOCK_FAST(fdp); 180119404Ssos last = min(fdp->fd_nfiles, lim); 181145818Ssos freefd = 0; 182198717Smav for (i = fdp->fd_freefile; i < last; i++) 183119404Ssos if (fdp->fd_ofiles[i] == NULL) 184145354Ssos freefd++; 185119404Ssos 186145354Ssos /* 187119404Ssos * Adjust for the fact that the fdesc array may not 188145713Ssos * have been fully allocated yet. 189119404Ssos */ 190119404Ssos if (fdp->fd_nfiles < lim) 191119404Ssos freefd += (lim - fdp->fd_nfiles); 192198717Smav FILEDESC_UNLOCK_FAST(fdp); 193119404Ssos 194144707Ssos sbp->f_flags = 0; 195119404Ssos sbp->f_bsize = DEV_BSIZE; 196145354Ssos sbp->f_iosize = DEV_BSIZE; 197119404Ssos sbp->f_blocks = 2; /* 1K to keep df happy */ 198119404Ssos sbp->f_bfree = 0; 199121310Ssos sbp->f_bavail = 0; 200178067Ssos sbp->f_files = lim + 1; /* Allow for "." */ 201198717Smav sbp->f_ffree = freefd; /* See comments above */ 202153142Ssos return (0); 203145354Ssos} 204119404Ssos 205119404Ssosstatic struct vfsops fdesc_vfsops = { 206119404Ssos .vfs_cmount = fdesc_cmount, 207145818Ssos .vfs_init = fdesc_init, 208198717Smav .vfs_mount = fdesc_mount, 209119404Ssos .vfs_root = fdesc_root, 210145354Ssos .vfs_statfs = fdesc_statfs, 211119404Ssos .vfs_unmount = fdesc_unmount, 212119404Ssos}; 213119404Ssos 214178067SsosVFS_SET(fdesc_vfsops, fdescfs, VFCF_SYNTHETIC); 215119404Ssos