1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software donated to Berkeley by 6 * Jan-Simon Pendry. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)portal_vfsops.c 8.8 (Berkeley) 03/29/95 11 * 12 * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 13 */ 14 15 /* 16 * Portal Filesystem 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/time.h> 22 #include <sys/types.h> 23 #include <sys/proc.h> 24 #include <sys/filedesc.h> 25 #include <sys/file.h> 26 #include <sys/vnode.h> 27 #include <sys/mount.h> 28 #include <sys/namei.h> 29 #include <sys/malloc.h> 30 #include <sys/mbuf.h> 31 #include <sys/socket.h> 32 #include <sys/socketvar.h> 33 #include <sys/protosw.h> 34 #include <sys/domain.h> 35 #include <sys/un.h> 36 #include <miscfs/portal/portal.h> 37 38 int 39 portal_init(vfsp) 40 struct vfsconf *vfsp; 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 vfs_getnewfsid(mp); 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 VOP_REVOKE(rootvp, 0); 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_statfs(mp, sbp, p) 204 struct mount *mp; 205 struct statfs *sbp; 206 struct proc *p; 207 { 208 209 sbp->f_flags = 0; 210 sbp->f_bsize = DEV_BSIZE; 211 sbp->f_iosize = DEV_BSIZE; 212 sbp->f_blocks = 2; /* 1K to keep df happy */ 213 sbp->f_bfree = 0; 214 sbp->f_bavail = 0; 215 sbp->f_files = 1; /* Allow for "." */ 216 sbp->f_ffree = 0; /* See comments above */ 217 if (sbp != &mp->mnt_stat) { 218 sbp->f_type = mp->mnt_vfc->vfc_typenum; 219 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 220 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 221 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 222 } 223 return (0); 224 } 225 226 #define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 227 struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 228 #define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 229 struct proc *)))eopnotsupp) 230 #define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ 231 struct proc *)))nullop) 232 #define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 233 size_t, struct proc *)))eopnotsupp) 234 #define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 235 eopnotsupp) 236 #define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 237 238 struct vfsops portal_vfsops = { 239 portal_mount, 240 portal_start, 241 portal_unmount, 242 portal_root, 243 portal_quotactl, 244 portal_statfs, 245 portal_sync, 246 portal_vget, 247 portal_fhtovp, 248 portal_vptofh, 249 portal_init, 250 portal_sysctl, 251 }; 252