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