153838Spendry /* 2*63231Sbostic * Copyright (c) 1992, 1993 3*63231Sbostic * The Regents of the University of California. All rights reserved. 453838Spendry * All rights reserved. 553838Spendry * 653838Spendry * This code is derived from software donated to Berkeley by 753838Spendry * Jan-Simon Pendry. 853838Spendry * 953838Spendry * %sccs.include.redist.c% 1053838Spendry * 11*63231Sbostic * @(#)fdesc_vfsops.c 8.1 (Berkeley) 06/10/93 1253838Spendry * 1359255Spendry * $Id: fdesc_vfsops.c,v 1.9 1993/04/06 15:28:33 jsp Exp $ 1453838Spendry */ 1553838Spendry 1653838Spendry /* 1753838Spendry * /dev/fd Filesystem 1853838Spendry */ 1953838Spendry 2053838Spendry #include <sys/param.h> 2153838Spendry #include <sys/systm.h> 2253838Spendry #include <sys/time.h> 2353838Spendry #include <sys/types.h> 2453838Spendry #include <sys/proc.h> 2553838Spendry #include <sys/resourcevar.h> 2653838Spendry #include <sys/filedesc.h> 2753838Spendry #include <sys/vnode.h> 2853838Spendry #include <sys/mount.h> 2953838Spendry #include <sys/namei.h> 3053838Spendry #include <sys/malloc.h> 3155016Smckusick #include <miscfs/fdesc/fdesc.h> 3253838Spendry 3359255Spendry dev_t devctty; 3453838Spendry 3553838Spendry fdesc_init() 3653838Spendry { 3753838Spendry #ifdef FDESC_DIAGNOSTIC 3853838Spendry printf("fdesc_init\n"); /* printed during system boot */ 3953838Spendry #endif 4059255Spendry devctty = makedev(nchrdev, 0); 4153838Spendry } 4253838Spendry 4353838Spendry /* 4453838Spendry * Mount the per-process file descriptors (/dev/fd) 4553838Spendry */ 4653838Spendry fdesc_mount(mp, path, data, ndp, p) 4753838Spendry struct mount *mp; 4853838Spendry char *path; 4953838Spendry caddr_t data; 5053838Spendry struct nameidata *ndp; 5153838Spendry struct proc *p; 5253838Spendry { 5353838Spendry int error = 0; 5453838Spendry u_int size; 5553838Spendry struct fdescmount *fmp; 5653838Spendry struct vnode *rvp; 5753838Spendry 5853838Spendry #ifdef FDESC_DIAGNOSTIC 5953838Spendry printf("fdesc_mount(mp = %x)\n", mp); 6053838Spendry #endif 6153838Spendry 6253838Spendry /* 6353838Spendry * Update is a no-op 6453838Spendry */ 6553838Spendry if (mp->mnt_flag & MNT_UPDATE) 6653838Spendry return (EOPNOTSUPP); 6753838Spendry 6859255Spendry error = fdesc_allocvp(Froot, FD_ROOT, mp, &rvp); 6953838Spendry if (error) 7053838Spendry return (error); 7153838Spendry 7253838Spendry MALLOC(fmp, struct fdescmount *, sizeof(struct fdescmount), 7353838Spendry M_UFSMNT, M_WAITOK); /* XXX */ 7453838Spendry rvp->v_type = VDIR; 7553838Spendry rvp->v_flag |= VROOT; 7653838Spendry #ifdef FDESC_DIAGNOSTIC 7753838Spendry printf("fdesc_mount: root vp = %x\n", rvp); 7853838Spendry #endif 7953838Spendry fmp->f_root = rvp; 8059557Spendry /* XXX -- don't mark as local to work around fts() problems */ 8159557Spendry /*mp->mnt_flag |= MNT_LOCAL;*/ 8253838Spendry mp->mnt_data = (qaddr_t) fmp; 8353838Spendry getnewfsid(mp, MOUNT_FDESC); 8453838Spendry 8553838Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 8653838Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 8753838Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 8853838Spendry bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 8953838Spendry #ifdef FDESC_DIAGNOSTIC 9053838Spendry printf("fdesc_mount: at %s\n", mp->mnt_stat.f_mntonname); 9153838Spendry #endif 9253838Spendry return (0); 9353838Spendry } 9453838Spendry 9553838Spendry fdesc_start(mp, flags, p) 9653838Spendry struct mount *mp; 9753838Spendry int flags; 9853838Spendry struct proc *p; 9953838Spendry { 10053838Spendry return (0); 10153838Spendry } 10253838Spendry 10353838Spendry fdesc_unmount(mp, mntflags, p) 10453838Spendry struct mount *mp; 10553838Spendry int mntflags; 10653838Spendry struct proc *p; 10753838Spendry { 10853838Spendry int error; 10953838Spendry int flags = 0; 11053838Spendry extern int doforce; 11153838Spendry struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 11253838Spendry 11353838Spendry #ifdef FDESC_DIAGNOSTIC 11453838Spendry printf("fdesc_unmount(mp = %x)\n", mp); 11553838Spendry #endif 11653838Spendry 11753838Spendry if (mntflags & MNT_FORCE) { 11853838Spendry /* fdesc can never be rootfs so don't check for it */ 11953838Spendry if (!doforce) 12053838Spendry return (EINVAL); 12153838Spendry flags |= FORCECLOSE; 12253838Spendry } 12353838Spendry 12453838Spendry /* 12553838Spendry * Clear out buffer cache. I don't think we 12653838Spendry * ever get anything cached at this level at the 12753838Spendry * moment, but who knows... 12853838Spendry */ 12954980Spendry #if 0 13053838Spendry #ifdef FDESC_DIAGNOSTIC 13153838Spendry printf("fdesc_unmount: calling mntflushbuf\n"); 13253838Spendry #endif 13353838Spendry mntflushbuf(mp, 0); 13453838Spendry #ifdef FDESC_DIAGNOSTIC 13553838Spendry printf("fdesc_unmount: calling mntinvalbuf\n"); 13653838Spendry #endif 13753838Spendry if (mntinvalbuf(mp, 1)) 13853838Spendry return (EBUSY); 13954980Spendry #endif 14053838Spendry if (rootvp->v_usecount > 1) 14153838Spendry return (EBUSY); 14253838Spendry #ifdef FDESC_DIAGNOSTIC 14353838Spendry printf("fdesc_unmount: calling vflush\n"); 14453838Spendry #endif 14553838Spendry if (error = vflush(mp, rootvp, flags)) 14653838Spendry return (error); 14753838Spendry 14853838Spendry #ifdef FDESC_DIAGNOSTIC 14953838Spendry vprint("fdesc root", rootvp); 15053838Spendry #endif 15153838Spendry /* 15253838Spendry * Release reference on underlying root vnode 15353838Spendry */ 15453838Spendry vrele(rootvp); 15553838Spendry /* 15653838Spendry * And blow it away for future re-use 15753838Spendry */ 15853838Spendry vgone(rootvp); 15953838Spendry /* 16053838Spendry * Finally, throw away the fdescmount structure 16153838Spendry */ 16253838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 16353838Spendry mp->mnt_data = 0; 16453838Spendry return 0; 16553838Spendry } 16653838Spendry 16753838Spendry fdesc_root(mp, vpp) 16853838Spendry struct mount *mp; 16953838Spendry struct vnode **vpp; 17053838Spendry { 17153838Spendry struct vnode *vp; 17253838Spendry int error; 17353838Spendry 17453838Spendry #ifdef FDESC_DIAGNOSTIC 17553838Spendry printf("fdesc_root(mp = %x)\n", mp); 17653838Spendry #endif 17753838Spendry 17853838Spendry /* 17953838Spendry * Return locked reference to root. 18053838Spendry */ 18153838Spendry vp = VFSTOFDESC(mp)->f_root; 18253838Spendry VREF(vp); 18353838Spendry VOP_LOCK(vp); 18453838Spendry *vpp = vp; 18553838Spendry return (0); 18653838Spendry } 18753838Spendry 18853838Spendry fdesc_quotactl(mp, cmd, uid, arg, p) 18953838Spendry struct mount *mp; 19053838Spendry int cmd; 19153838Spendry uid_t uid; 19253838Spendry caddr_t arg; 19353838Spendry struct proc *p; 19453838Spendry { 19553838Spendry return (EOPNOTSUPP); 19653838Spendry } 19753838Spendry 19853838Spendry fdesc_statfs(mp, sbp, p) 19953838Spendry struct mount *mp; 20053838Spendry struct statfs *sbp; 20153838Spendry struct proc *p; 20253838Spendry { 20353838Spendry struct filedesc *fdp; 20453838Spendry int lim; 20553838Spendry int i; 20653838Spendry int last; 20753838Spendry int freefd; 20853838Spendry 20953838Spendry #ifdef FDESC_DIAGNOSTIC 21053838Spendry printf("fdesc_statfs(mp = %x)\n", mp); 21153838Spendry #endif 21253838Spendry 21353838Spendry /* 21453838Spendry * Compute number of free file descriptors. 21553838Spendry * [ Strange results will ensue if the open file 21653838Spendry * limit is ever reduced below the current number 21753838Spendry * of open files... ] 21853838Spendry */ 21956938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 22053838Spendry fdp = p->p_fd; 22153838Spendry last = min(fdp->fd_nfiles, lim); 22253838Spendry freefd = 0; 22353838Spendry for (i = fdp->fd_freefile; i < last; i++) 22453838Spendry if (fdp->fd_ofiles[i] == NULL) 22553838Spendry freefd++; 22653838Spendry 22753838Spendry /* 22853838Spendry * Adjust for the fact that the fdesc array may not 22953838Spendry * have been fully allocated yet. 23053838Spendry */ 23153838Spendry if (fdp->fd_nfiles < lim) 23253838Spendry freefd += (lim - fdp->fd_nfiles); 23353838Spendry 23453838Spendry sbp->f_type = MOUNT_FDESC; 23553838Spendry sbp->f_flags = 0; 23653838Spendry sbp->f_bsize = DEV_BSIZE; 23753838Spendry sbp->f_iosize = DEV_BSIZE; 23853838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 23953838Spendry sbp->f_bfree = 0; 24053838Spendry sbp->f_bavail = 0; 24153838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 24253838Spendry sbp->f_ffree = freefd; /* See comments above */ 24353838Spendry if (sbp != &mp->mnt_stat) { 24453838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 24553838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 24653838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 24753838Spendry } 24853838Spendry return (0); 24953838Spendry } 25053838Spendry 25153838Spendry fdesc_sync(mp, waitfor) 25253838Spendry struct mount *mp; 25353838Spendry int waitfor; 25453838Spendry { 25553838Spendry return (0); 25653838Spendry } 25753838Spendry 25854980Spendry /* 25954980Spendry * Fdesc flat namespace lookup. 26054980Spendry * Currently unsupported. 26154980Spendry */ 26254980Spendry fdesc_vget(mp, ino, vpp) 26354980Spendry struct mount *mp; 26454980Spendry ino_t ino; 26554980Spendry struct vnode **vpp; 26654980Spendry { 26754980Spendry 26854980Spendry return (EOPNOTSUPP); 26954980Spendry } 27054980Spendry 27154980Spendry 27253838Spendry fdesc_fhtovp(mp, fhp, setgen, vpp) 27353838Spendry struct mount *mp; 27453838Spendry struct fid *fhp; 27553838Spendry int setgen; 27653838Spendry struct vnode **vpp; 27753838Spendry { 27853838Spendry return (EOPNOTSUPP); 27953838Spendry } 28053838Spendry 28153838Spendry fdesc_vptofh(vp, fhp) 28253838Spendry struct vnode *vp; 28353838Spendry struct fid *fhp; 28453838Spendry { 28553838Spendry return (EOPNOTSUPP); 28653838Spendry } 28753838Spendry 28853838Spendry struct vfsops fdesc_vfsops = { 28953838Spendry fdesc_mount, 29053838Spendry fdesc_start, 29153838Spendry fdesc_unmount, 29253838Spendry fdesc_root, 29353838Spendry fdesc_quotactl, 29453838Spendry fdesc_statfs, 29553838Spendry fdesc_sync, 29654980Spendry fdesc_vget, 29753838Spendry fdesc_fhtovp, 29853838Spendry fdesc_vptofh, 29953838Spendry fdesc_init, 30053838Spendry }; 301