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