fdesc_vfsops.c revision 22521
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 * 3821673Sjkh * $FreeBSD: head/sys/fs/fdescfs/fdesc_vfsops.c 22521 1997-02-10 02:22:35Z dyson $ 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 5912333Sbdestatic int fdesc_fhtovp __P((struct mount *mp, struct fid *fhp, 6012333Sbde struct mbuf *nam, struct vnode **vpp, 6112333Sbde int *exflagsp, struct ucred **credanonp)); 6212333Sbdestatic int fdesc_mount __P((struct mount *mp, char *path, caddr_t data, 6312333Sbde struct nameidata *ndp, struct proc *p)); 6412333Sbdestatic int fdesc_quotactl __P((struct mount *mp, int cmd, uid_t uid, 6512333Sbde caddr_t arg, struct proc *p)); 6612333Sbdestatic int fdesc_start __P((struct mount *mp, int flags, struct proc *p)); 6712333Sbdestatic int fdesc_unmount __P((struct mount *mp, int mntflags, 6812333Sbde struct proc *p)); 6912333Sbdestatic int fdesc_statfs __P((struct mount *mp, struct statfs *sbp, 7012333Sbde struct proc *p)); 7112333Sbdestatic int fdesc_sync __P((struct mount *mp, int waitfor, 7212333Sbde struct ucred *cred, struct proc *p)); 7312333Sbdestatic int fdesc_vget __P((struct mount *mp, ino_t ino, 7412333Sbde struct vnode **vpp)); 7512333Sbdestatic int fdesc_vptofh __P((struct vnode *vp, struct fid *fhp)); 7612333Sbde 771541Srgrimes/* 781541Srgrimes * Mount the per-process file descriptors (/dev/fd) 791541Srgrimes */ 8012143Sphkstatic int 811541Srgrimesfdesc_mount(mp, path, data, ndp, p) 821541Srgrimes struct mount *mp; 831541Srgrimes char *path; 841541Srgrimes caddr_t data; 851541Srgrimes struct nameidata *ndp; 861541Srgrimes struct proc *p; 871541Srgrimes{ 881541Srgrimes int error = 0; 891541Srgrimes u_int size; 901541Srgrimes struct fdescmount *fmp; 911541Srgrimes struct vnode *rvp; 921541Srgrimes 931541Srgrimes /* 941541Srgrimes * Update is a no-op 951541Srgrimes */ 961541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 971541Srgrimes return (EOPNOTSUPP); 981541Srgrimes 991541Srgrimes error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 1001541Srgrimes if (error) 1011541Srgrimes return (error); 1021541Srgrimes 1031541Srgrimes MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 1041541Srgrimes M_UFSMNT, M_WAITOK); /* XXX */ 1051541Srgrimes rvp->v_type = VDIR; 1061541Srgrimes rvp->v_flag |= VROOT; 1071541Srgrimes fmp->f_root = rvp; 1081541Srgrimes /* XXX -- don't mark as local to work around fts() problems */ 1091541Srgrimes /*mp->mnt_flag |= MNT_LOCAL;*/ 1101541Srgrimes mp->mnt_data = (qaddr_t) fmp; 11122521Sdyson vfs_getnewfsid(mp); 1121541Srgrimes 1131541Srgrimes (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 1141541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 1151541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1161541Srgrimes bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 11710533Smpp (void)fdesc_statfs(mp, &mp->mnt_stat, p); 1181541Srgrimes return (0); 1191541Srgrimes} 1201541Srgrimes 12112143Sphkstatic int 1221541Srgrimesfdesc_start(mp, flags, p) 1231541Srgrimes struct mount *mp; 1241541Srgrimes int flags; 1251541Srgrimes struct proc *p; 1261541Srgrimes{ 1271541Srgrimes return (0); 1281541Srgrimes} 1291541Srgrimes 13012143Sphkstatic int 1311541Srgrimesfdesc_unmount(mp, mntflags, p) 1321541Srgrimes struct mount *mp; 1331541Srgrimes int mntflags; 1341541Srgrimes struct proc *p; 1351541Srgrimes{ 1361541Srgrimes int error; 1371541Srgrimes int flags = 0; 1381541Srgrimes struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 1391541Srgrimes 14022521Sdyson if (mntflags & MNT_FORCE) 1411541Srgrimes flags |= FORCECLOSE; 1421541Srgrimes 1431541Srgrimes /* 1441541Srgrimes * Clear out buffer cache. I don't think we 1451541Srgrimes * ever get anything cached at this level at the 1461541Srgrimes * moment, but who knows... 1471541Srgrimes */ 1481541Srgrimes if (rootvp->v_usecount > 1) 1491541Srgrimes return (EBUSY); 1501541Srgrimes if (error = vflush(mp, rootvp, flags)) 1511541Srgrimes return (error); 1521541Srgrimes 1531541Srgrimes /* 1541541Srgrimes * Release reference on underlying root vnode 1551541Srgrimes */ 1561541Srgrimes vrele(rootvp); 1571541Srgrimes /* 1581541Srgrimes * And blow it away for future re-use 1591541Srgrimes */ 1601541Srgrimes vgone(rootvp); 1611541Srgrimes /* 1621541Srgrimes * Finally, throw away the fdescmount structure 1631541Srgrimes */ 1641541Srgrimes free(mp->mnt_data, M_UFSMNT); /* XXX */ 1651541Srgrimes mp->mnt_data = 0; 1661541Srgrimes 1671541Srgrimes return (0); 1681541Srgrimes} 1691541Srgrimes 1701541Srgrimesint 1711541Srgrimesfdesc_root(mp, vpp) 1721541Srgrimes struct mount *mp; 1731541Srgrimes struct vnode **vpp; 1741541Srgrimes{ 17522521Sdyson struct proc *p = curproc; /* XXX */ 1761541Srgrimes struct vnode *vp; 1771541Srgrimes 1781541Srgrimes /* 1791541Srgrimes * Return locked reference to root. 1801541Srgrimes */ 1811541Srgrimes vp = VFSTOFDESC(mp)->f_root; 1821541Srgrimes VREF(vp); 18322521Sdyson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1841541Srgrimes *vpp = vp; 1851541Srgrimes return (0); 1861541Srgrimes} 1871541Srgrimes 18812143Sphkstatic int 1891541Srgrimesfdesc_statfs(mp, sbp, p) 1901541Srgrimes struct mount *mp; 1911541Srgrimes struct statfs *sbp; 1921541Srgrimes struct proc *p; 1931541Srgrimes{ 1941541Srgrimes struct filedesc *fdp; 1951541Srgrimes int lim; 1961541Srgrimes int i; 1971541Srgrimes int last; 1981541Srgrimes int freefd; 1991541Srgrimes 2001541Srgrimes /* 2011541Srgrimes * Compute number of free file descriptors. 2021541Srgrimes * [ Strange results will ensue if the open file 2031541Srgrimes * limit is ever reduced below the current number 2041541Srgrimes * of open files... ] 2051541Srgrimes */ 2061541Srgrimes lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 2071541Srgrimes fdp = p->p_fd; 2081541Srgrimes last = min(fdp->fd_nfiles, lim); 2091541Srgrimes freefd = 0; 2101541Srgrimes for (i = fdp->fd_freefile; i < last; i++) 2111541Srgrimes if (fdp->fd_ofiles[i] == NULL) 2121541Srgrimes freefd++; 2131541Srgrimes 2141541Srgrimes /* 2151541Srgrimes * Adjust for the fact that the fdesc array may not 2161541Srgrimes * have been fully allocated yet. 2171541Srgrimes */ 2181541Srgrimes if (fdp->fd_nfiles < lim) 2191541Srgrimes freefd += (lim - fdp->fd_nfiles); 2201541Srgrimes 2211541Srgrimes sbp->f_flags = 0; 2221541Srgrimes sbp->f_bsize = DEV_BSIZE; 2231541Srgrimes sbp->f_iosize = DEV_BSIZE; 2241541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2251541Srgrimes sbp->f_bfree = 0; 2261541Srgrimes sbp->f_bavail = 0; 2271541Srgrimes sbp->f_files = lim + 1; /* Allow for "." */ 2281541Srgrimes sbp->f_ffree = freefd; /* See comments above */ 2291541Srgrimes if (sbp != &mp->mnt_stat) { 23022521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2311541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2321541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2331541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2341541Srgrimes } 2351541Srgrimes return (0); 2361541Srgrimes} 2371541Srgrimes 23812143Sphkstatic int 23912333Sbdefdesc_sync(mp, waitfor, cred, p) 2401541Srgrimes struct mount *mp; 2411541Srgrimes int waitfor; 24212333Sbde struct ucred *cred; 24312333Sbde struct proc *p; 2441541Srgrimes{ 2451541Srgrimes 2461541Srgrimes return (0); 2471541Srgrimes} 2481541Srgrimes 24922521Sdyson#define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 25022521Sdyson struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 25122521Sdyson#define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 25222521Sdyson struct proc *)))eopnotsupp) 25322521Sdyson#define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 25422521Sdyson size_t, struct proc *)))eopnotsupp) 25522521Sdyson#define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 25622521Sdyson eopnotsupp) 25722521Sdyson#define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 2581541Srgrimes 25912143Sphkstatic struct vfsops fdesc_vfsops = { 2601541Srgrimes fdesc_mount, 2611541Srgrimes fdesc_start, 2621541Srgrimes fdesc_unmount, 2631541Srgrimes fdesc_root, 2641541Srgrimes fdesc_quotactl, 2651541Srgrimes fdesc_statfs, 2661541Srgrimes fdesc_sync, 2671541Srgrimes fdesc_vget, 2681541Srgrimes fdesc_fhtovp, 2691541Srgrimes fdesc_vptofh, 2701541Srgrimes fdesc_init, 2711541Srgrimes}; 2722946Swollman 2737095SwollmanVFS_SET(fdesc_vfsops, fdesc, MOUNT_FDESC, VFCF_SYNTHETIC); 274