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 * %sccs.include.redist.c% 9 * 10 * @(#)portal_vfsops.c 8.7 (Berkeley) 02/23/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 39 portal_init() 40 { 41 42 return (0); 43 } 44 45 /* 46 * Mount the per-process file descriptors (/dev/fd) 47 */ 48 int 49 portal_mount(mp, path, data, ndp, p) 50 struct mount *mp; 51 char *path; 52 caddr_t data; 53 struct nameidata *ndp; 54 struct proc *p; 55 { 56 struct file *fp; 57 struct portal_args args; 58 struct portalmount *fmp; 59 struct socket *so; 60 struct vnode *rvp; 61 u_int size; 62 int error; 63 64 /* 65 * Update is a no-op 66 */ 67 if (mp->mnt_flag & MNT_UPDATE) 68 return (EOPNOTSUPP); 69 70 if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 71 return (error); 72 73 if (error = getsock(p->p_fd, args.pa_socket, &fp)) 74 return (error); 75 so = (struct socket *) fp->f_data; 76 if (so->so_proto->pr_domain->dom_family != AF_UNIX) 77 return (ESOCKTNOSUPPORT); 78 79 error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 80 if (error) 81 return (error); 82 MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 83 M_TEMP, M_WAITOK); 84 85 fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 86 M_UFSMNT, M_WAITOK); /* XXX */ 87 rvp->v_type = VDIR; 88 rvp->v_flag |= VROOT; 89 VTOPORTAL(rvp)->pt_arg = 0; 90 VTOPORTAL(rvp)->pt_size = 0; 91 VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 92 fmp->pm_root = rvp; 93 fmp->pm_server = fp; fp->f_count++; 94 95 mp->mnt_flag |= MNT_LOCAL; 96 mp->mnt_data = (qaddr_t) fmp; 97 getnewfsid(mp, MOUNT_PORTAL); 98 99 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 100 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 101 (void)copyinstr(args.pa_config, 102 mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 103 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 104 105 #ifdef notdef 106 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 107 bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 108 #endif 109 110 return (0); 111 } 112 113 int 114 portal_start(mp, flags, p) 115 struct mount *mp; 116 int flags; 117 struct proc *p; 118 { 119 120 return (0); 121 } 122 123 int 124 portal_unmount(mp, mntflags, p) 125 struct mount *mp; 126 int mntflags; 127 struct proc *p; 128 { 129 extern int doforce; 130 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 131 int error, flags = 0; 132 133 134 if (mntflags & MNT_FORCE) { 135 /* portal can never be rootfs so don't check for it */ 136 if (!doforce) 137 return (EINVAL); 138 flags |= FORCECLOSE; 139 } 140 141 /* 142 * Clear out buffer cache. I don't think we 143 * ever get anything cached at this level at the 144 * moment, but who knows... 145 */ 146 #ifdef notyet 147 mntflushbuf(mp, 0); 148 if (mntinvalbuf(mp, 1)) 149 return (EBUSY); 150 #endif 151 if (rootvp->v_usecount > 1) 152 return (EBUSY); 153 if (error = vflush(mp, rootvp, flags)) 154 return (error); 155 156 /* 157 * Release reference on underlying root vnode 158 */ 159 vrele(rootvp); 160 /* 161 * And blow it away for future re-use 162 */ 163 VOP_REVOKE(rootvp, 0); 164 /* 165 * Shutdown the socket. This will cause the select in the 166 * daemon to wake up, and then the accept will get ECONNABORTED 167 * which it interprets as a request to go and bury itself. 168 */ 169 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 170 /* 171 * Discard reference to underlying file. Must call closef because 172 * this may be the last reference. 173 */ 174 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 175 /* 176 * Finally, throw away the portalmount structure 177 */ 178 free(mp->mnt_data, M_UFSMNT); /* XXX */ 179 mp->mnt_data = 0; 180 return (0); 181 } 182 183 int 184 portal_root(mp, vpp) 185 struct mount *mp; 186 struct vnode **vpp; 187 { 188 struct vnode *vp; 189 190 191 /* 192 * Return locked reference to root. 193 */ 194 vp = VFSTOPORTAL(mp)->pm_root; 195 VREF(vp); 196 VOP_LOCK(vp); 197 *vpp = vp; 198 return (0); 199 } 200 201 int 202 portal_quotactl(mp, cmd, uid, arg, p) 203 struct mount *mp; 204 int cmd; 205 uid_t uid; 206 caddr_t arg; 207 struct proc *p; 208 { 209 210 return (EOPNOTSUPP); 211 } 212 213 int 214 portal_statfs(mp, sbp, p) 215 struct mount *mp; 216 struct statfs *sbp; 217 struct proc *p; 218 { 219 220 sbp->f_type = MOUNT_PORTAL; 221 sbp->f_flags = 0; 222 sbp->f_bsize = DEV_BSIZE; 223 sbp->f_iosize = DEV_BSIZE; 224 sbp->f_blocks = 2; /* 1K to keep df happy */ 225 sbp->f_bfree = 0; 226 sbp->f_bavail = 0; 227 sbp->f_files = 1; /* Allow for "." */ 228 sbp->f_ffree = 0; /* See comments above */ 229 if (sbp != &mp->mnt_stat) { 230 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 231 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 232 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 233 } 234 return (0); 235 } 236 237 int 238 portal_sync(mp, waitfor) 239 struct mount *mp; 240 int waitfor; 241 { 242 243 return (0); 244 } 245 246 int 247 portal_vget(mp, ino, vpp) 248 struct mount *mp; 249 ino_t ino; 250 struct vnode **vpp; 251 { 252 253 return (EOPNOTSUPP); 254 } 255 256 int 257 portal_fhtovp(mp, fhp, vpp) 258 struct mount *mp; 259 struct fid *fhp; 260 struct vnode **vpp; 261 { 262 263 return (EOPNOTSUPP); 264 } 265 266 int 267 portal_vptofh(vp, fhp) 268 struct vnode *vp; 269 struct fid *fhp; 270 { 271 272 return (EOPNOTSUPP); 273 } 274 275 struct vfsops portal_vfsops = { 276 portal_mount, 277 portal_start, 278 portal_unmount, 279 portal_root, 280 portal_quotactl, 281 portal_statfs, 282 portal_sync, 283 portal_vget, 284 portal_fhtovp, 285 portal_vptofh, 286 portal_init, 287 }; 288