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