153838Spendry /* 253838Spendry * Copyright (c) 1992 The Regents of the University of California 353838Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 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*59255Spendry * @(#)fdesc_vfsops.c 7.3 (Berkeley) 04/22/93 1253838Spendry * 13*59255Spendry * $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 33*59255Spendry dev_t devctty; 3453838Spendry 3553838Spendry fdesc_init() 3653838Spendry { 3753838Spendry #ifdef FDESC_DIAGNOSTIC 3853838Spendry printf("fdesc_init\n"); /* printed during system boot */ 3953838Spendry #endif 40*59255Spendry 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 68*59255Spendry 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; 8053838Spendry mp->mnt_flag |= MNT_LOCAL; 8153838Spendry mp->mnt_data = (qaddr_t) fmp; 8253838Spendry getnewfsid(mp, MOUNT_FDESC); 8353838Spendry 8453838Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 8553838Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 8653838Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 8753838Spendry bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc")); 8853838Spendry #ifdef FDESC_DIAGNOSTIC 8953838Spendry printf("fdesc_mount: at %s\n", mp->mnt_stat.f_mntonname); 9053838Spendry #endif 9153838Spendry return (0); 9253838Spendry } 9353838Spendry 9453838Spendry fdesc_start(mp, flags, p) 9553838Spendry struct mount *mp; 9653838Spendry int flags; 9753838Spendry struct proc *p; 9853838Spendry { 9953838Spendry return (0); 10053838Spendry } 10153838Spendry 10253838Spendry fdesc_unmount(mp, mntflags, p) 10353838Spendry struct mount *mp; 10453838Spendry int mntflags; 10553838Spendry struct proc *p; 10653838Spendry { 10753838Spendry int error; 10853838Spendry int flags = 0; 10953838Spendry extern int doforce; 11053838Spendry struct vnode *rootvp = VFSTOFDESC(mp)->f_root; 11153838Spendry 11253838Spendry #ifdef FDESC_DIAGNOSTIC 11353838Spendry printf("fdesc_unmount(mp = %x)\n", mp); 11453838Spendry #endif 11553838Spendry 11653838Spendry if (mntflags & MNT_FORCE) { 11753838Spendry /* fdesc can never be rootfs so don't check for it */ 11853838Spendry if (!doforce) 11953838Spendry return (EINVAL); 12053838Spendry flags |= FORCECLOSE; 12153838Spendry } 12253838Spendry 12353838Spendry /* 12453838Spendry * Clear out buffer cache. I don't think we 12553838Spendry * ever get anything cached at this level at the 12653838Spendry * moment, but who knows... 12753838Spendry */ 12854980Spendry #if 0 12953838Spendry #ifdef FDESC_DIAGNOSTIC 13053838Spendry printf("fdesc_unmount: calling mntflushbuf\n"); 13153838Spendry #endif 13253838Spendry mntflushbuf(mp, 0); 13353838Spendry #ifdef FDESC_DIAGNOSTIC 13453838Spendry printf("fdesc_unmount: calling mntinvalbuf\n"); 13553838Spendry #endif 13653838Spendry if (mntinvalbuf(mp, 1)) 13753838Spendry return (EBUSY); 13854980Spendry #endif 13953838Spendry if (rootvp->v_usecount > 1) 14053838Spendry return (EBUSY); 14153838Spendry #ifdef FDESC_DIAGNOSTIC 14253838Spendry printf("fdesc_unmount: calling vflush\n"); 14353838Spendry #endif 14453838Spendry if (error = vflush(mp, rootvp, flags)) 14553838Spendry return (error); 14653838Spendry 14753838Spendry #ifdef FDESC_DIAGNOSTIC 14853838Spendry vprint("fdesc root", rootvp); 14953838Spendry #endif 15053838Spendry /* 15153838Spendry * Release reference on underlying root vnode 15253838Spendry */ 15353838Spendry vrele(rootvp); 15453838Spendry /* 15553838Spendry * And blow it away for future re-use 15653838Spendry */ 15753838Spendry vgone(rootvp); 15853838Spendry /* 15953838Spendry * Finally, throw away the fdescmount structure 16053838Spendry */ 16153838Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 16253838Spendry mp->mnt_data = 0; 16353838Spendry return 0; 16453838Spendry } 16553838Spendry 16653838Spendry fdesc_root(mp, vpp) 16753838Spendry struct mount *mp; 16853838Spendry struct vnode **vpp; 16953838Spendry { 17053838Spendry struct vnode *vp; 17153838Spendry int error; 17253838Spendry 17353838Spendry #ifdef FDESC_DIAGNOSTIC 17453838Spendry printf("fdesc_root(mp = %x)\n", mp); 17553838Spendry #endif 17653838Spendry 17753838Spendry /* 17853838Spendry * Return locked reference to root. 17953838Spendry */ 18053838Spendry vp = VFSTOFDESC(mp)->f_root; 18153838Spendry VREF(vp); 18253838Spendry VOP_LOCK(vp); 18353838Spendry *vpp = vp; 18453838Spendry return (0); 18553838Spendry } 18653838Spendry 18753838Spendry fdesc_quotactl(mp, cmd, uid, arg, p) 18853838Spendry struct mount *mp; 18953838Spendry int cmd; 19053838Spendry uid_t uid; 19153838Spendry caddr_t arg; 19253838Spendry struct proc *p; 19353838Spendry { 19453838Spendry return (EOPNOTSUPP); 19553838Spendry } 19653838Spendry 19753838Spendry fdesc_statfs(mp, sbp, p) 19853838Spendry struct mount *mp; 19953838Spendry struct statfs *sbp; 20053838Spendry struct proc *p; 20153838Spendry { 20253838Spendry struct filedesc *fdp; 20353838Spendry int lim; 20453838Spendry int i; 20553838Spendry int last; 20653838Spendry int freefd; 20753838Spendry 20853838Spendry #ifdef FDESC_DIAGNOSTIC 20953838Spendry printf("fdesc_statfs(mp = %x)\n", mp); 21053838Spendry #endif 21153838Spendry 21253838Spendry /* 21353838Spendry * Compute number of free file descriptors. 21453838Spendry * [ Strange results will ensue if the open file 21553838Spendry * limit is ever reduced below the current number 21653838Spendry * of open files... ] 21753838Spendry */ 21856938Smckusick lim = p->p_rlimit[RLIMIT_NOFILE].rlim_cur; 21953838Spendry fdp = p->p_fd; 22053838Spendry last = min(fdp->fd_nfiles, lim); 22153838Spendry freefd = 0; 22253838Spendry for (i = fdp->fd_freefile; i < last; i++) 22353838Spendry if (fdp->fd_ofiles[i] == NULL) 22453838Spendry freefd++; 22553838Spendry 22653838Spendry /* 22753838Spendry * Adjust for the fact that the fdesc array may not 22853838Spendry * have been fully allocated yet. 22953838Spendry */ 23053838Spendry if (fdp->fd_nfiles < lim) 23153838Spendry freefd += (lim - fdp->fd_nfiles); 23253838Spendry 23353838Spendry sbp->f_type = MOUNT_FDESC; 23453838Spendry sbp->f_flags = 0; 23553838Spendry sbp->f_bsize = DEV_BSIZE; 23653838Spendry sbp->f_iosize = DEV_BSIZE; 23753838Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 23853838Spendry sbp->f_bfree = 0; 23953838Spendry sbp->f_bavail = 0; 24053838Spendry sbp->f_files = lim + 1; /* Allow for "." */ 24153838Spendry sbp->f_ffree = freefd; /* See comments above */ 24253838Spendry if (sbp != &mp->mnt_stat) { 24353838Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 24453838Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 24553838Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 24653838Spendry } 24753838Spendry return (0); 24853838Spendry } 24953838Spendry 25053838Spendry fdesc_sync(mp, waitfor) 25153838Spendry struct mount *mp; 25253838Spendry int waitfor; 25353838Spendry { 25453838Spendry return (0); 25553838Spendry } 25653838Spendry 25754980Spendry /* 25854980Spendry * Fdesc flat namespace lookup. 25954980Spendry * Currently unsupported. 26054980Spendry */ 26154980Spendry fdesc_vget(mp, ino, vpp) 26254980Spendry struct mount *mp; 26354980Spendry ino_t ino; 26454980Spendry struct vnode **vpp; 26554980Spendry { 26654980Spendry 26754980Spendry return (EOPNOTSUPP); 26854980Spendry } 26954980Spendry 27054980Spendry 27153838Spendry fdesc_fhtovp(mp, fhp, setgen, vpp) 27253838Spendry struct mount *mp; 27353838Spendry struct fid *fhp; 27453838Spendry int setgen; 27553838Spendry struct vnode **vpp; 27653838Spendry { 27753838Spendry return (EOPNOTSUPP); 27853838Spendry } 27953838Spendry 28053838Spendry fdesc_vptofh(vp, fhp) 28153838Spendry struct vnode *vp; 28253838Spendry struct fid *fhp; 28353838Spendry { 28453838Spendry return (EOPNOTSUPP); 28553838Spendry } 28653838Spendry 28753838Spendry struct vfsops fdesc_vfsops = { 28853838Spendry fdesc_mount, 28953838Spendry fdesc_start, 29053838Spendry fdesc_unmount, 29153838Spendry fdesc_root, 29253838Spendry fdesc_quotactl, 29353838Spendry fdesc_statfs, 29453838Spendry fdesc_sync, 29554980Spendry fdesc_vget, 29653838Spendry fdesc_fhtovp, 29753838Spendry fdesc_vptofh, 29853838Spendry fdesc_init, 29953838Spendry }; 300