1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * All rights reserved. 5 * 6 * This code is derived from software donated to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)portal_vfsops.c 8.5 (Berkeley) 01/05/94 12 * 13 * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 14 */ 15 16 /* 17 * Portal Filesystem 18 */ 19 20 #include <sys/param.h> 21 #include <sys/systm.h> 22 #include <sys/time.h> 23 #include <sys/types.h> 24 #include <sys/proc.h> 25 #include <sys/filedesc.h> 26 #include <sys/file.h> 27 #include <sys/vnode.h> 28 #include <sys/mount.h> 29 #include <sys/namei.h> 30 #include <sys/malloc.h> 31 #include <sys/mbuf.h> 32 #include <sys/socket.h> 33 #include <sys/socketvar.h> 34 #include <sys/protosw.h> 35 #include <sys/domain.h> 36 #include <sys/un.h> 37 #include <miscfs/portal/portal.h> 38 39 int 40 portal_init() 41 { 42 43 return (0); 44 } 45 46 /* 47 * Mount the per-process file descriptors (/dev/fd) 48 */ 49 int 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 getnewfsid(mp, MOUNT_PORTAL); 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 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 125 portal_unmount(mp, mntflags, p) 126 struct mount *mp; 127 int mntflags; 128 struct proc *p; 129 { 130 extern int doforce; 131 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 132 int error, flags = 0; 133 134 135 if (mntflags & MNT_FORCE) { 136 /* portal can never be rootfs so don't check for it */ 137 if (!doforce) 138 return (EINVAL); 139 flags |= FORCECLOSE; 140 } 141 142 /* 143 * Clear out buffer cache. I don't think we 144 * ever get anything cached at this level at the 145 * moment, but who knows... 146 */ 147 #ifdef notyet 148 mntflushbuf(mp, 0); 149 if (mntinvalbuf(mp, 1)) 150 return (EBUSY); 151 #endif 152 if (rootvp->v_usecount > 1) 153 return (EBUSY); 154 if (error = vflush(mp, rootvp, flags)) 155 return (error); 156 157 /* 158 * Release reference on underlying root vnode 159 */ 160 vrele(rootvp); 161 /* 162 * And blow it away for future re-use 163 */ 164 vgone(rootvp); 165 /* 166 * Shutdown the socket. This will cause the select in the 167 * daemon to wake up, and then the accept will get ECONNABORTED 168 * which it interprets as a request to go and bury itself. 169 */ 170 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 171 /* 172 * Discard reference to underlying file. Must call closef because 173 * this may be the last reference. 174 */ 175 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 176 /* 177 * Finally, throw away the portalmount structure 178 */ 179 free(mp->mnt_data, M_UFSMNT); /* XXX */ 180 mp->mnt_data = 0; 181 return (0); 182 } 183 184 int 185 portal_root(mp, vpp) 186 struct mount *mp; 187 struct vnode **vpp; 188 { 189 struct vnode *vp; 190 191 192 /* 193 * Return locked reference to root. 194 */ 195 vp = VFSTOPORTAL(mp)->pm_root; 196 VREF(vp); 197 VOP_LOCK(vp); 198 *vpp = vp; 199 return (0); 200 } 201 202 int 203 portal_quotactl(mp, cmd, uid, arg, p) 204 struct mount *mp; 205 int cmd; 206 uid_t uid; 207 caddr_t arg; 208 struct proc *p; 209 { 210 211 return (EOPNOTSUPP); 212 } 213 214 int 215 portal_statfs(mp, sbp, p) 216 struct mount *mp; 217 struct statfs *sbp; 218 struct proc *p; 219 { 220 221 sbp->f_type = MOUNT_PORTAL; 222 sbp->f_flags = 0; 223 sbp->f_bsize = DEV_BSIZE; 224 sbp->f_iosize = DEV_BSIZE; 225 sbp->f_blocks = 2; /* 1K to keep df happy */ 226 sbp->f_bfree = 0; 227 sbp->f_bavail = 0; 228 sbp->f_files = 1; /* Allow for "." */ 229 sbp->f_ffree = 0; /* See comments above */ 230 if (sbp != &mp->mnt_stat) { 231 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 232 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 233 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 234 } 235 return (0); 236 } 237 238 int 239 portal_sync(mp, waitfor) 240 struct mount *mp; 241 int waitfor; 242 { 243 244 return (0); 245 } 246 247 int 248 portal_vget(mp, ino, vpp) 249 struct mount *mp; 250 ino_t ino; 251 struct vnode **vpp; 252 { 253 254 return (EOPNOTSUPP); 255 } 256 257 int 258 portal_fhtovp(mp, fhp, vpp) 259 struct mount *mp; 260 struct fid *fhp; 261 struct vnode **vpp; 262 { 263 264 return (EOPNOTSUPP); 265 } 266 267 int 268 portal_vptofh(vp, fhp) 269 struct vnode *vp; 270 struct fid *fhp; 271 { 272 273 return (EOPNOTSUPP); 274 } 275 276 struct vfsops portal_vfsops = { 277 portal_mount, 278 portal_start, 279 portal_unmount, 280 portal_root, 281 portal_quotactl, 282 portal_statfs, 283 portal_sync, 284 portal_vget, 285 portal_fhtovp, 286 portal_vptofh, 287 portal_init, 288 }; 289