portal_vfsops.c revision 8876
1193326Sed/*
2193326Sed * Copyright (c) 1992, 1993
3193326Sed *	The Regents of the University of California.  All rights reserved.
4193326Sed *
5193326Sed * This code is derived from software donated to Berkeley by
6193326Sed * Jan-Simon Pendry.
7193326Sed *
8193326Sed * Redistribution and use in source and binary forms, with or without
9193326Sed * modification, are permitted provided that the following conditions
10205219Srdivacky * are met:
11205219Srdivacky * 1. Redistributions of source code must retain the above copyright
12193326Sed *    notice, this list of conditions and the following disclaimer.
13193326Sed * 2. Redistributions in binary form must reproduce the above copyright
14193326Sed *    notice, this list of conditions and the following disclaimer in the
15193326Sed *    documentation and/or other materials provided with the distribution.
16193326Sed * 3. All advertising materials mentioning features or use of this software
17193326Sed *    must display the following acknowledgement:
18198092Srdivacky *	This product includes software developed by the University of
19235633Sdim *	California, Berkeley and its contributors.
20193326Sed * 4. Neither the name of the University nor the names of its contributors
21212904Sdim *    may be used to endorse or promote products derived from this software
22202879Srdivacky *    without specific prior written permission.
23235633Sdim *
24235633Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25198092Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26235633Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27193326Sed * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28193326Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29193326Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30193326Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31198092Srdivacky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32198092Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33198092Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34193326Sed * SUCH DAMAGE.
35198092Srdivacky *
36193326Sed *	@(#)portal_vfsops.c	8.6 (Berkeley) 1/21/94
37193326Sed *
38198092Srdivacky * $Id: portal_vfsops.c,v 1.7 1995/03/16 20:23:41 wollman Exp $
39198092Srdivacky */
40206084Srdivacky
41218893Sdim/*
42205219Srdivacky * Portal Filesystem
43235633Sdim */
44245431Sdim
45235633Sdim#include <sys/param.h>
46198092Srdivacky#include <sys/systm.h>
47195099Sed#include <sys/kernel.h>
48195099Sed#include <sys/time.h>
49195099Sed#include <sys/types.h>
50198092Srdivacky#include <sys/proc.h>
51195341Sed#include <sys/filedesc.h>
52198092Srdivacky#include <sys/file.h>
53195099Sed#include <sys/vnode.h>
54195099Sed#include <sys/mount.h>
55195099Sed#include <sys/namei.h>
56198092Srdivacky#include <sys/malloc.h>
57198092Srdivacky#include <sys/mbuf.h>
58195099Sed#include <sys/socket.h>
59195099Sed#include <sys/socketvar.h>
60198092Srdivacky#include <sys/protosw.h>
61195099Sed#include <sys/domain.h>
62195099Sed#include <sys/un.h>
63198092Srdivacky#include <miscfs/portal/portal.h>
64198092Srdivacky
65195341Sedint
66195341Sedportal_init()
67195099Sed{
68198092Srdivacky
69195099Sed	return (0);
70195099Sed}
71195099Sed
72198092Srdivacky/*
73195099Sed * Mount the per-process file descriptors (/dev/fd)
74195099Sed */
75195099Sedint
76195099Sedportal_mount(mp, path, data, ndp, p)
77195099Sed	struct mount *mp;
78195099Sed	char *path;
79195099Sed	caddr_t data;
80195099Sed	struct nameidata *ndp;
81195099Sed	struct proc *p;
82198092Srdivacky{
83195341Sed	struct file *fp;
84195341Sed	struct portal_args args;
85195341Sed	struct portalmount *fmp;
86195341Sed	struct socket *so;
87195341Sed	struct vnode *rvp;
88198092Srdivacky	u_int size;
89195341Sed	int error;
90195341Sed
91195341Sed	/*
92195341Sed	 * Update is a no-op
93195341Sed	 */
94198092Srdivacky	if (mp->mnt_flag & MNT_UPDATE)
95195341Sed		return (EOPNOTSUPP);
96195341Sed
97198092Srdivacky	error = copyin(data, (caddr_t) &args, sizeof(struct portal_args));
98195099Sed	if (error)
99195099Sed		return (error);
100195099Sed
101198092Srdivacky	error = getsock(p->p_fd, args.pa_socket, &fp);
102245431Sdim	if (error)
103210299Sed		return (error);
104210299Sed	so = (struct socket *) fp->f_data;
105210299Sed	if (so->so_proto->pr_domain->dom_family != AF_UNIX)
106210299Sed		return (ESOCKTNOSUPPORT);
107210299Sed
108210299Sed	error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */
109210299Sed	if (error)
110210299Sed		return (error);
111210299Sed	MALLOC(rvp->v_data, void *, sizeof(struct portalnode),
112210299Sed		M_TEMP, M_WAITOK);
113235633Sdim
114245431Sdim	fmp = (struct portalmount *) malloc(sizeof(struct portalmount),
115210299Sed				 M_UFSMNT, M_WAITOK);	/* XXX */
116210299Sed	rvp->v_type = VDIR;
117210299Sed	rvp->v_flag |= VROOT;
118210299Sed	VTOPORTAL(rvp)->pt_arg = 0;
119210299Sed	VTOPORTAL(rvp)->pt_size = 0;
120210299Sed	VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID;
121210299Sed	fmp->pm_root = rvp;
122218893Sdim	fmp->pm_server = fp; fp->f_count++;
123218893Sdim
124210299Sed	mp->mnt_flag |= MNT_LOCAL;
125245431Sdim	mp->mnt_data = (qaddr_t) fmp;
126210299Sed	getnewfsid(mp, MOUNT_PORTAL);
127245431Sdim
128210299Sed	(void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
129210299Sed	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
130245431Sdim	(void)copyinstr(args.pa_config,
131210299Sed	    mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
132245431Sdim	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
133210299Sed
134210299Sed#ifdef notdef
135235633Sdim	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
136210299Sed	bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal"));
137210299Sed#endif
138210299Sed
139210299Sed	return (0);
140210299Sed}
141210299Sed
142210299Sedint
143210299Sedportal_start(mp, flags, p)
144235633Sdim	struct mount *mp;
145210299Sed	int flags;
146210299Sed	struct proc *p;
147210299Sed{
148210299Sed
149210299Sed	return (0);
150210299Sed}
151210299Sed
152245431Sdimint
153193326Sedportal_unmount(mp, mntflags, p)
154193326Sed	struct mount *mp;
155193326Sed	int mntflags;
156193326Sed	struct proc *p;
157193326Sed{
158193326Sed	struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root;
159193326Sed	int error, flags = 0;
160193326Sed
161193326Sed
162193326Sed	if (mntflags & MNT_FORCE) {
163193326Sed		/* portal can never be rootfs so don't check for it */
164193326Sed		if (!doforce)
165193326Sed			return (EINVAL);
166193326Sed		flags |= FORCECLOSE;
167193326Sed	}
168193326Sed
169193326Sed	/*
170193326Sed	 * Clear out buffer cache.  I don't think we
171193326Sed	 * ever get anything cached at this level at the
172193326Sed	 * moment, but who knows...
173193326Sed	 */
174218893Sdim#ifdef notyet
175218893Sdim	mntflushbuf(mp, 0);
176218893Sdim	if (mntinvalbuf(mp, 1))
177235633Sdim		return (EBUSY);
178245431Sdim#endif
179193326Sed	if (rootvp->v_usecount > 1)
180193326Sed		return (EBUSY);
181193326Sed	error = vflush(mp, rootvp, flags);
182193326Sed	if (error)
183193326Sed		return (error);
184193326Sed
185198092Srdivacky	/*
186193326Sed	 * Release reference on underlying root vnode
187193326Sed	 */
188193326Sed	vrele(rootvp);
189193326Sed	/*
190193326Sed	 * And blow it away for future re-use
191193326Sed	 */
192193326Sed	vgone(rootvp);
193218893Sdim	/*
194218893Sdim	 * Shutdown the socket.  This will cause the select in the
195218893Sdim	 * daemon to wake up, and then the accept will get ECONNABORTED
196218893Sdim	 * which it interprets as a request to go and bury itself.
197212904Sdim	 */
198212904Sdim	soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2);
199212904Sdim	/*
200212904Sdim	 * Discard reference to underlying file.  Must call closef because
201198092Srdivacky	 * this may be the last reference.
202193326Sed	 */
203193326Sed	closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0);
204193326Sed	/*
205212904Sdim	 * Finally, throw away the portalmount structure
206218893Sdim	 */
207235633Sdim	free(mp->mnt_data, M_UFSMNT);	/* XXX */
208218893Sdim	mp->mnt_data = 0;
209193326Sed	return (0);
210193326Sed}
211193326Sed
212235633Sdimint
213235633Sdimportal_root(mp, vpp)
214235633Sdim	struct mount *mp;
215198092Srdivacky	struct vnode **vpp;
216193326Sed{
217193326Sed	struct vnode *vp;
218193326Sed
219193326Sed
220212904Sdim	/*
221203955Srdivacky	 * Return locked reference to root.
222203955Srdivacky	 */
223235633Sdim	vp = VFSTOPORTAL(mp)->pm_root;
224218893Sdim	VREF(vp);
225218893Sdim	VOP_LOCK(vp);
226218893Sdim	*vpp = vp;
227218893Sdim	return (0);
228218893Sdim}
229218893Sdim
230218893Sdimint
231218893Sdimportal_quotactl(mp, cmd, uid, arg, p)
232218893Sdim	struct mount *mp;
233218893Sdim	int cmd;
234218893Sdim	uid_t uid;
235218893Sdim	caddr_t arg;
236218893Sdim	struct proc *p;
237218893Sdim{
238218893Sdim
239218893Sdim	return (EOPNOTSUPP);
240193326Sed}
241193326Sed
242193326Sedint
243193326Sedportal_statfs(mp, sbp, p)
244193326Sed	struct mount *mp;
245198092Srdivacky	struct statfs *sbp;
246193326Sed	struct proc *p;
247193326Sed{
248193326Sed
249198092Srdivacky	sbp->f_type = MOUNT_PORTAL;
250193326Sed	sbp->f_flags = 0;
251193326Sed	sbp->f_bsize = DEV_BSIZE;
252193326Sed	sbp->f_iosize = DEV_BSIZE;
253193326Sed	sbp->f_blocks = 2;		/* 1K to keep df happy */
254193326Sed	sbp->f_bfree = 0;
255193326Sed	sbp->f_bavail = 0;
256193326Sed	sbp->f_files = 1;		/* Allow for "." */
257193326Sed	sbp->f_ffree = 0;		/* See comments above */
258193326Sed	if (sbp != &mp->mnt_stat) {
259193326Sed		bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
260193326Sed		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
261193326Sed		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
262212904Sdim	}
263212904Sdim	return (0);
264212904Sdim}
265212904Sdim
266193326Sedint
267193326Sedportal_sync(mp, waitfor)
268193326Sed	struct mount *mp;
269193326Sed	int waitfor;
270193326Sed{
271193326Sed
272193326Sed	return (0);
273203955Srdivacky}
274193326Sed
275203955Srdivackyint
276203955Srdivackyportal_vget(mp, ino, vpp)
277193326Sed	struct mount *mp;
278203955Srdivacky	ino_t ino;
279203955Srdivacky	struct vnode **vpp;
280203955Srdivacky{
281193326Sed
282203955Srdivacky	return (EOPNOTSUPP);
283203955Srdivacky}
284203955Srdivacky
285193326Sedint
286223017Sdimportal_fhtovp(mp, fhp, vpp)
287223017Sdim	struct mount *mp;
288223017Sdim	struct fid *fhp;
289223017Sdim	struct vnode **vpp;
290203955Srdivacky{
291203955Srdivacky
292203955Srdivacky	return (EOPNOTSUPP);
293193326Sed}
294223017Sdim
295223017Sdimint
296223017Sdimportal_vptofh(vp, fhp)
297223017Sdim	struct vnode *vp;
298203955Srdivacky	struct fid *fhp;
299203955Srdivacky{
300203955Srdivacky
301198092Srdivacky	return (EOPNOTSUPP);
302203955Srdivacky}
303203955Srdivacky
304193326Sedstruct vfsops portal_vfsops = {
305203955Srdivacky	portal_mount,
306203955Srdivacky	portal_start,
307198092Srdivacky	portal_unmount,
308203955Srdivacky	portal_root,
309203955Srdivacky	portal_quotactl,
310203955Srdivacky	portal_statfs,
311203955Srdivacky	portal_sync,
312203955Srdivacky	portal_vget,
313198092Srdivacky	portal_fhtovp,
314203955Srdivacky	portal_vptofh,
315203955Srdivacky	portal_init,
316203955Srdivacky};
317198092Srdivacky
318203955SrdivackyVFS_SET(portal_vfsops, portal, MOUNT_PORTAL, VFCF_SYNTHETIC);
319203955Srdivacky