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.2 (Berkeley) 07/12/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 #if 0 164 #ifdef PORTAL_DIAGNOSTIC 165 printf("portal_unmount: calling mntflushbuf\n"); 166 #endif 167 mntflushbuf(mp, 0); 168 #ifdef PORTAL_DIAGNOSTIC 169 printf("portal_unmount: calling mntinvalbuf\n"); 170 #endif 171 if (mntinvalbuf(mp, 1)) 172 return (EBUSY); 173 #endif 174 if (rootvp->v_usecount > 1) 175 return (EBUSY); 176 #ifdef PORTAL_DIAGNOSTIC 177 printf("portal_unmount: calling vflush\n"); 178 #endif 179 if (error = vflush(mp, rootvp, flags)) 180 return (error); 181 182 #ifdef PORTAL_DIAGNOSTIC 183 vprint("portal root", rootvp); 184 #endif 185 /* 186 * Release reference on underlying root vnode 187 */ 188 vrele(rootvp); 189 /* 190 * And blow it away for future re-use 191 */ 192 vgone(rootvp); 193 /* 194 * Shutdown the socket. This will cause the select in the 195 * daemon to wake up, and then the accept will get ECONNABORTED 196 * which it interprets as a request to go and bury itself. 197 */ 198 #ifdef PORTAL_DIAGNOSTIC 199 printf("portal_unmount: shutdown socket\n"); 200 #endif 201 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 202 /* 203 * Discard reference to underlying file. Must call closef because 204 * this may be the last reference. 205 */ 206 #ifdef PORTAL_DIAGNOSTIC 207 printf("portal_unmount: closef(%x)\n", VFSTOPORTAL(mp)->pm_server); 208 #endif 209 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 210 /* 211 * Finally, throw away the portalmount structure 212 */ 213 free(mp->mnt_data, M_UFSMNT); /* XXX */ 214 mp->mnt_data = 0; 215 return 0; 216 } 217 218 portal_root(mp, vpp) 219 struct mount *mp; 220 struct vnode **vpp; 221 { 222 struct vnode *vp; 223 int error; 224 225 #ifdef PORTAL_DIAGNOSTIC 226 printf("portal_root(mp = %x)\n", mp); 227 #endif 228 229 /* 230 * Return locked reference to root. 231 */ 232 vp = VFSTOPORTAL(mp)->pm_root; 233 VREF(vp); 234 VOP_LOCK(vp); 235 *vpp = vp; 236 return (0); 237 } 238 239 portal_quotactl(mp, cmd, uid, arg, p) 240 struct mount *mp; 241 int cmd; 242 uid_t uid; 243 caddr_t arg; 244 struct proc *p; 245 { 246 return (EOPNOTSUPP); 247 } 248 249 portal_statfs(mp, sbp, p) 250 struct mount *mp; 251 struct statfs *sbp; 252 struct proc *p; 253 { 254 struct filedesc *fdp; 255 int lim; 256 int i; 257 int last; 258 int freefd; 259 260 #ifdef PORTAL_DIAGNOSTIC 261 printf("portal_statfs(mp = %x)\n", mp); 262 #endif 263 264 sbp->f_type = MOUNT_PORTAL; 265 sbp->f_flags = 0; 266 sbp->f_bsize = DEV_BSIZE; 267 sbp->f_iosize = DEV_BSIZE; 268 sbp->f_blocks = 2; /* 1K to keep df happy */ 269 sbp->f_bfree = 0; 270 sbp->f_bavail = 0; 271 sbp->f_files = 1; /* Allow for "." */ 272 sbp->f_ffree = 0; /* See comments above */ 273 if (sbp != &mp->mnt_stat) { 274 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 275 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 276 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 277 } 278 return (0); 279 } 280 281 portal_sync(mp, waitfor) 282 struct mount *mp; 283 int waitfor; 284 { 285 return (0); 286 } 287 288 portal_vget(mp, ino, vpp) 289 struct mount *mp; 290 ino_t ino; 291 struct vnode **vpp; 292 { 293 294 return (EOPNOTSUPP); 295 } 296 297 portal_fhtovp(mp, fhp, vpp) 298 struct mount *mp; 299 struct fid *fhp; 300 struct vnode **vpp; 301 { 302 return (EOPNOTSUPP); 303 } 304 305 portal_vptofh(vp, fhp) 306 struct vnode *vp; 307 struct fid *fhp; 308 { 309 return (EOPNOTSUPP); 310 } 311 312 struct vfsops portal_vfsops = { 313 portal_mount, 314 portal_start, 315 portal_unmount, 316 portal_root, 317 portal_quotactl, 318 portal_statfs, 319 portal_sync, 320 portal_vget, 321 portal_fhtovp, 322 portal_vptofh, 323 portal_init, 324 }; 325