1 /*
2 * Copyright (c) 1992, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software donated to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)portal_vfsops.c 8.11 (Berkeley) 05/14/95
11 *
12 * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $
13 */
14
15 /*
16 * Portal Filesystem
17 */
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/proc.h>
24 #include <sys/filedesc.h>
25 #include <sys/file.h>
26 #include <sys/vnode.h>
27 #include <sys/mount.h>
28 #include <sys/namei.h>
29 #include <sys/malloc.h>
30 #include <sys/mbuf.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.h>
33 #include <sys/protosw.h>
34 #include <sys/domain.h>
35 #include <sys/un.h>
36 #include <miscfs/portal/portal.h>
37
38 int
portal_init(vfsp)39 portal_init(vfsp)
40 struct vfsconf *vfsp;
41 {
42
43 return (0);
44 }
45
46 /*
47 * Mount the per-process file descriptors (/dev/fd)
48 */
49 int
portal_mount(mp,path,data,ndp,p)50 portal_mount(mp, path, data, ndp, p)
51 struct mount *mp;
52 char *path;
53 caddr_t data;
54 struct nameidata *ndp;
55 struct proc *p;
56 {
57 struct file *fp;
58 struct portal_args args;
59 struct portalmount *fmp;
60 struct socket *so;
61 struct vnode *rvp;
62 u_int size;
63 int error;
64
65 /*
66 * Update is a no-op
67 */
68 if (mp->mnt_flag & MNT_UPDATE)
69 return (EOPNOTSUPP);
70
71 if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)))
72 return (error);
73
74 if (error = getsock(p->p_fd, args.pa_socket, &fp))
75 return (error);
76 so = (struct socket *) fp->f_data;
77 if (so->so_proto->pr_domain->dom_family != AF_UNIX)
78 return (ESOCKTNOSUPPORT);
79
80 error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */
81 if (error)
82 return (error);
83 MALLOC(rvp->v_data, void *, sizeof(struct portalnode),
84 M_TEMP, M_WAITOK);
85
86 fmp = (struct portalmount *) malloc(sizeof(struct portalmount),
87 M_UFSMNT, M_WAITOK); /* XXX */
88 rvp->v_type = VDIR;
89 rvp->v_flag |= VROOT;
90 VTOPORTAL(rvp)->pt_arg = 0;
91 VTOPORTAL(rvp)->pt_size = 0;
92 VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID;
93 fmp->pm_root = rvp;
94 fmp->pm_server = fp; fp->f_count++;
95
96 mp->mnt_flag |= MNT_LOCAL;
97 mp->mnt_data = (qaddr_t) fmp;
98 vfs_getnewfsid(mp);
99
100 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
101 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
102 (void)copyinstr(args.pa_config,
103 mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
104 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
105
106 #ifdef notdef
107 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
108 bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal"));
109 #endif
110
111 return (0);
112 }
113
114 int
portal_start(mp,flags,p)115 portal_start(mp, flags, p)
116 struct mount *mp;
117 int flags;
118 struct proc *p;
119 {
120
121 return (0);
122 }
123
124 int
portal_unmount(mp,mntflags,p)125 portal_unmount(mp, mntflags, p)
126 struct mount *mp;
127 int mntflags;
128 struct proc *p;
129 {
130 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root;
131 int error, flags = 0;
132
133
134 if (mntflags & MNT_FORCE)
135 flags |= FORCECLOSE;
136
137 /*
138 * Clear out buffer cache. I don't think we
139 * ever get anything cached at this level at the
140 * moment, but who knows...
141 */
142 #ifdef notyet
143 mntflushbuf(mp, 0);
144 if (mntinvalbuf(mp, 1))
145 return (EBUSY);
146 #endif
147 if (rootvp->v_usecount > 1)
148 return (EBUSY);
149 if (error = vflush(mp, rootvp, flags))
150 return (error);
151
152 /*
153 * Release reference on underlying root vnode
154 */
155 vrele(rootvp);
156 /*
157 * And blow it away for future re-use
158 */
159 vgone(rootvp);
160 /*
161 * Shutdown the socket. This will cause the select in the
162 * daemon to wake up, and then the accept will get ECONNABORTED
163 * which it interprets as a request to go and bury itself.
164 */
165 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2);
166 /*
167 * Discard reference to underlying file. Must call closef because
168 * this may be the last reference.
169 */
170 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0);
171 /*
172 * Finally, throw away the portalmount structure
173 */
174 free(mp->mnt_data, M_UFSMNT); /* XXX */
175 mp->mnt_data = 0;
176 return (0);
177 }
178
179 int
portal_root(mp,vpp)180 portal_root(mp, vpp)
181 struct mount *mp;
182 struct vnode **vpp;
183 {
184 struct proc *p = curproc; /* XXX */
185 struct vnode *vp;
186
187 /*
188 * Return locked reference to root.
189 */
190 vp = VFSTOPORTAL(mp)->pm_root;
191 VREF(vp);
192 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
193 *vpp = vp;
194 return (0);
195 }
196
197 int
portal_statfs(mp,sbp,p)198 portal_statfs(mp, sbp, p)
199 struct mount *mp;
200 struct statfs *sbp;
201 struct proc *p;
202 {
203
204 sbp->f_flags = 0;
205 sbp->f_bsize = DEV_BSIZE;
206 sbp->f_iosize = DEV_BSIZE;
207 sbp->f_blocks = 2; /* 1K to keep df happy */
208 sbp->f_bfree = 0;
209 sbp->f_bavail = 0;
210 sbp->f_files = 1; /* Allow for "." */
211 sbp->f_ffree = 0; /* See comments above */
212 if (sbp != &mp->mnt_stat) {
213 sbp->f_type = mp->mnt_vfc->vfc_typenum;
214 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
215 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
216 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
217 }
218 return (0);
219 }
220
221 #define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \
222 struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp)
223 #define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
224 struct proc *)))eopnotsupp)
225 #define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \
226 struct proc *)))nullop)
227 #define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
228 size_t, struct proc *)))eopnotsupp)
229 #define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
230 eopnotsupp)
231 #define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp)
232
233 struct vfsops portal_vfsops = {
234 portal_mount,
235 portal_start,
236 portal_unmount,
237 portal_root,
238 portal_quotactl,
239 portal_statfs,
240 portal_sync,
241 portal_vget,
242 portal_fhtovp,
243 portal_vptofh,
244 portal_init,
245 portal_sysctl,
246 };
247