portal_vfsops.c revision 1541
1/* 2 * Copyright (c) 1992, 1993 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 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)portal_vfsops.c 8.6 (Berkeley) 1/21/94 37 * 38 * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 39 */ 40 41/* 42 * Portal Filesystem 43 */ 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/time.h> 48#include <sys/types.h> 49#include <sys/proc.h> 50#include <sys/filedesc.h> 51#include <sys/file.h> 52#include <sys/vnode.h> 53#include <sys/mount.h> 54#include <sys/namei.h> 55#include <sys/malloc.h> 56#include <sys/mbuf.h> 57#include <sys/socket.h> 58#include <sys/socketvar.h> 59#include <sys/protosw.h> 60#include <sys/domain.h> 61#include <sys/un.h> 62#include <miscfs/portal/portal.h> 63 64int 65portal_init() 66{ 67 68 return (0); 69} 70 71/* 72 * Mount the per-process file descriptors (/dev/fd) 73 */ 74int 75portal_mount(mp, path, data, ndp, p) 76 struct mount *mp; 77 char *path; 78 caddr_t data; 79 struct nameidata *ndp; 80 struct proc *p; 81{ 82 struct file *fp; 83 struct portal_args args; 84 struct portalmount *fmp; 85 struct socket *so; 86 struct vnode *rvp; 87 u_int size; 88 int error; 89 90 /* 91 * Update is a no-op 92 */ 93 if (mp->mnt_flag & MNT_UPDATE) 94 return (EOPNOTSUPP); 95 96 if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 97 return (error); 98 99 if (error = getsock(p->p_fd, args.pa_socket, &fp)) 100 return (error); 101 so = (struct socket *) fp->f_data; 102 if (so->so_proto->pr_domain->dom_family != AF_UNIX) 103 return (ESOCKTNOSUPPORT); 104 105 error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 106 if (error) 107 return (error); 108 MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 109 M_TEMP, M_WAITOK); 110 111 fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 112 M_UFSMNT, M_WAITOK); /* XXX */ 113 rvp->v_type = VDIR; 114 rvp->v_flag |= VROOT; 115 VTOPORTAL(rvp)->pt_arg = 0; 116 VTOPORTAL(rvp)->pt_size = 0; 117 VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 118 fmp->pm_root = rvp; 119 fmp->pm_server = fp; fp->f_count++; 120 121 mp->mnt_flag |= MNT_LOCAL; 122 mp->mnt_data = (qaddr_t) fmp; 123 getnewfsid(mp, MOUNT_PORTAL); 124 125 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 126 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 127 (void)copyinstr(args.pa_config, 128 mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 129 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 130 131#ifdef notdef 132 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 133 bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 134#endif 135 136 return (0); 137} 138 139int 140portal_start(mp, flags, p) 141 struct mount *mp; 142 int flags; 143 struct proc *p; 144{ 145 146 return (0); 147} 148 149int 150portal_unmount(mp, mntflags, p) 151 struct mount *mp; 152 int mntflags; 153 struct proc *p; 154{ 155 extern int doforce; 156 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 157 int error, flags = 0; 158 159 160 if (mntflags & MNT_FORCE) { 161 /* portal can never be rootfs so don't check for it */ 162 if (!doforce) 163 return (EINVAL); 164 flags |= FORCECLOSE; 165 } 166 167 /* 168 * Clear out buffer cache. I don't think we 169 * ever get anything cached at this level at the 170 * moment, but who knows... 171 */ 172#ifdef notyet 173 mntflushbuf(mp, 0); 174 if (mntinvalbuf(mp, 1)) 175 return (EBUSY); 176#endif 177 if (rootvp->v_usecount > 1) 178 return (EBUSY); 179 if (error = vflush(mp, rootvp, flags)) 180 return (error); 181 182 /* 183 * Release reference on underlying root vnode 184 */ 185 vrele(rootvp); 186 /* 187 * And blow it away for future re-use 188 */ 189 vgone(rootvp); 190 /* 191 * Shutdown the socket. This will cause the select in the 192 * daemon to wake up, and then the accept will get ECONNABORTED 193 * which it interprets as a request to go and bury itself. 194 */ 195 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 196 /* 197 * Discard reference to underlying file. Must call closef because 198 * this may be the last reference. 199 */ 200 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 201 /* 202 * Finally, throw away the portalmount structure 203 */ 204 free(mp->mnt_data, M_UFSMNT); /* XXX */ 205 mp->mnt_data = 0; 206 return (0); 207} 208 209int 210portal_root(mp, vpp) 211 struct mount *mp; 212 struct vnode **vpp; 213{ 214 struct vnode *vp; 215 216 217 /* 218 * Return locked reference to root. 219 */ 220 vp = VFSTOPORTAL(mp)->pm_root; 221 VREF(vp); 222 VOP_LOCK(vp); 223 *vpp = vp; 224 return (0); 225} 226 227int 228portal_quotactl(mp, cmd, uid, arg, p) 229 struct mount *mp; 230 int cmd; 231 uid_t uid; 232 caddr_t arg; 233 struct proc *p; 234{ 235 236 return (EOPNOTSUPP); 237} 238 239int 240portal_statfs(mp, sbp, p) 241 struct mount *mp; 242 struct statfs *sbp; 243 struct proc *p; 244{ 245 246 sbp->f_type = MOUNT_PORTAL; 247 sbp->f_flags = 0; 248 sbp->f_bsize = DEV_BSIZE; 249 sbp->f_iosize = DEV_BSIZE; 250 sbp->f_blocks = 2; /* 1K to keep df happy */ 251 sbp->f_bfree = 0; 252 sbp->f_bavail = 0; 253 sbp->f_files = 1; /* Allow for "." */ 254 sbp->f_ffree = 0; /* See comments above */ 255 if (sbp != &mp->mnt_stat) { 256 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 257 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 258 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 259 } 260 return (0); 261} 262 263int 264portal_sync(mp, waitfor) 265 struct mount *mp; 266 int waitfor; 267{ 268 269 return (0); 270} 271 272int 273portal_vget(mp, ino, vpp) 274 struct mount *mp; 275 ino_t ino; 276 struct vnode **vpp; 277{ 278 279 return (EOPNOTSUPP); 280} 281 282int 283portal_fhtovp(mp, fhp, vpp) 284 struct mount *mp; 285 struct fid *fhp; 286 struct vnode **vpp; 287{ 288 289 return (EOPNOTSUPP); 290} 291 292int 293portal_vptofh(vp, fhp) 294 struct vnode *vp; 295 struct fid *fhp; 296{ 297 298 return (EOPNOTSUPP); 299} 300 301struct vfsops portal_vfsops = { 302 portal_mount, 303 portal_start, 304 portal_unmount, 305 portal_root, 306 portal_quotactl, 307 portal_statfs, 308 portal_sync, 309 portal_vget, 310 portal_fhtovp, 311 portal_vptofh, 312 portal_init, 313}; 314