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.3 (Berkeley) 01/04/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 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 file *fp; 65 struct socket *so; 66 67 #ifdef PORTAL_DIAGNOSTIC 68 printf("portal_mount(mp = %x)\n", mp); 69 #endif 70 71 /* 72 * Update is a no-op 73 */ 74 if (mp->mnt_flag & MNT_UPDATE) 75 return (EOPNOTSUPP); 76 77 if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 78 return (error); 79 80 if (error = getsock(p->p_fd, args.pa_socket, &fp)) 81 return (error); 82 so = (struct socket *) fp->f_data; 83 if (so->so_proto->pr_domain->dom_family != AF_UNIX) 84 return (ESOCKTNOSUPPORT); 85 86 error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 87 if (error) 88 return (error); 89 MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 90 M_TEMP, M_WAITOK); 91 92 fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 93 M_UFSMNT, M_WAITOK); /* XXX */ 94 rvp->v_type = VDIR; 95 rvp->v_flag |= VROOT; 96 VTOPORTAL(rvp)->pt_arg = 0; 97 VTOPORTAL(rvp)->pt_size = 0; 98 VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 99 #ifdef PORTAL_DIAGNOSTIC 100 printf("portal_mount: root vp = %x\n", rvp); 101 #endif 102 fmp->pm_root = rvp; 103 fmp->pm_server = fp; fp->f_count++; 104 105 mp->mnt_flag |= MNT_LOCAL; 106 mp->mnt_data = (qaddr_t) fmp; 107 getnewfsid(mp, MOUNT_PORTAL); 108 109 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 110 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 111 (void) copyinstr(args.pa_config, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 112 &size); 113 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 114 115 #ifdef notdef 116 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 117 bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 118 #endif 119 120 #ifdef PORTAL_DIAGNOSTIC 121 printf("portal_mount: config %s at %s\n", 122 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); 123 #endif 124 return (0); 125 } 126 127 portal_start(mp, flags, p) 128 struct mount *mp; 129 int flags; 130 struct proc *p; 131 { 132 133 return (0); 134 } 135 136 portal_unmount(mp, mntflags, p) 137 struct mount *mp; 138 int mntflags; 139 struct proc *p; 140 { 141 extern int doforce; 142 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 143 int error, flags = 0; 144 145 #ifdef PORTAL_DIAGNOSTIC 146 printf("portal_unmount(mp = %x)\n", mp); 147 #endif 148 149 if (mntflags & MNT_FORCE) { 150 /* portal can never be rootfs so don't check for it */ 151 if (!doforce) 152 return (EINVAL); 153 flags |= FORCECLOSE; 154 } 155 156 /* 157 * Clear out buffer cache. I don't think we 158 * ever get anything cached at this level at the 159 * moment, but who knows... 160 */ 161 #ifdef notyet 162 #ifdef PORTAL_DIAGNOSTIC 163 printf("portal_unmount: calling mntflushbuf\n"); 164 #endif 165 mntflushbuf(mp, 0); 166 #ifdef PORTAL_DIAGNOSTIC 167 printf("portal_unmount: calling mntinvalbuf\n"); 168 #endif 169 if (mntinvalbuf(mp, 1)) 170 return (EBUSY); 171 #endif 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 struct vnode *vp; 221 222 #ifdef PORTAL_DIAGNOSTIC 223 printf("portal_root(mp = %x)\n", mp); 224 #endif 225 226 /* 227 * Return locked reference to root. 228 */ 229 vp = VFSTOPORTAL(mp)->pm_root; 230 VREF(vp); 231 VOP_LOCK(vp); 232 *vpp = vp; 233 return (0); 234 } 235 236 portal_quotactl(mp, cmd, uid, arg, p) 237 struct mount *mp; 238 int cmd; 239 uid_t uid; 240 caddr_t arg; 241 struct proc *p; 242 { 243 244 return (EOPNOTSUPP); 245 } 246 247 portal_statfs(mp, sbp, p) 248 struct mount *mp; 249 struct statfs *sbp; 250 struct proc *p; 251 { 252 #ifdef PORTAL_DIAGNOSTIC 253 printf("portal_statfs(mp = %x)\n", mp); 254 #endif 255 256 sbp->f_type = MOUNT_PORTAL; 257 sbp->f_flags = 0; 258 sbp->f_bsize = DEV_BSIZE; 259 sbp->f_iosize = DEV_BSIZE; 260 sbp->f_blocks = 2; /* 1K to keep df happy */ 261 sbp->f_bfree = 0; 262 sbp->f_bavail = 0; 263 sbp->f_files = 1; /* Allow for "." */ 264 sbp->f_ffree = 0; /* See comments above */ 265 if (sbp != &mp->mnt_stat) { 266 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 267 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 268 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 269 } 270 return (0); 271 } 272 273 portal_sync(mp, waitfor) 274 struct mount *mp; 275 int waitfor; 276 { 277 278 return (0); 279 } 280 281 portal_vget(mp, ino, vpp) 282 struct mount *mp; 283 ino_t ino; 284 struct vnode **vpp; 285 { 286 287 return (EOPNOTSUPP); 288 } 289 290 portal_fhtovp(mp, fhp, vpp) 291 struct mount *mp; 292 struct fid *fhp; 293 struct vnode **vpp; 294 { 295 296 return (EOPNOTSUPP); 297 } 298 299 portal_vptofh(vp, fhp) 300 struct vnode *vp; 301 struct fid *fhp; 302 { 303 304 return (EOPNOTSUPP); 305 } 306 307 struct vfsops portal_vfsops = { 308 portal_mount, 309 portal_start, 310 portal_unmount, 311 portal_root, 312 portal_quotactl, 313 portal_statfs, 314 portal_sync, 315 portal_vget, 316 portal_fhtovp, 317 portal_vptofh, 318 portal_init, 319 }; 320