1 /* 2 * Copyright (c) 1992, 1993, 1995 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.10 (Berkeley) 05/10/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 struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 131 int error, flags = 0; 132 133 134 if (mntflags & MNT_FORCE) 135 flags |= FORCECLOSE; 136 137 /* 138 * Clear out buffer cache. I don't think we 139 * ever get anything cached at this level at the 140 * moment, but who knows... 141 */ 142 #ifdef notyet 143 mntflushbuf(mp, 0); 144 if (mntinvalbuf(mp, 1)) 145 return (EBUSY); 146 #endif 147 if (rootvp->v_usecount > 1) 148 return (EBUSY); 149 if (error = vflush(mp, rootvp, flags)) 150 return (error); 151 152 /* 153 * Release reference on underlying root vnode 154 */ 155 vrele(rootvp); 156 /* 157 * And blow it away for future re-use 158 */ 159 vgone(rootvp); 160 /* 161 * Shutdown the socket. This will cause the select in the 162 * daemon to wake up, and then the accept will get ECONNABORTED 163 * which it interprets as a request to go and bury itself. 164 */ 165 soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 166 /* 167 * Discard reference to underlying file. Must call closef because 168 * this may be the last reference. 169 */ 170 closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 171 /* 172 * Finally, throw away the portalmount structure 173 */ 174 free(mp->mnt_data, M_UFSMNT); /* XXX */ 175 mp->mnt_data = 0; 176 return (0); 177 } 178 179 int 180 portal_root(mp, vpp) 181 struct mount *mp; 182 struct vnode **vpp; 183 { 184 struct vnode *vp; 185 186 187 /* 188 * Return locked reference to root. 189 */ 190 vp = VFSTOPORTAL(mp)->pm_root; 191 VREF(vp); 192 VOP_LOCK(vp); 193 *vpp = vp; 194 return (0); 195 } 196 197 int 198 portal_statfs(mp, sbp, p) 199 struct mount *mp; 200 struct statfs *sbp; 201 struct proc *p; 202 { 203 204 sbp->f_flags = 0; 205 sbp->f_bsize = DEV_BSIZE; 206 sbp->f_iosize = DEV_BSIZE; 207 sbp->f_blocks = 2; /* 1K to keep df happy */ 208 sbp->f_bfree = 0; 209 sbp->f_bavail = 0; 210 sbp->f_files = 1; /* Allow for "." */ 211 sbp->f_ffree = 0; /* See comments above */ 212 if (sbp != &mp->mnt_stat) { 213 sbp->f_type = mp->mnt_vfc->vfc_typenum; 214 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 215 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 216 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 217 } 218 return (0); 219 } 220 221 #define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 222 struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 223 #define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 224 struct proc *)))eopnotsupp) 225 #define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ 226 struct proc *)))nullop) 227 #define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 228 size_t, struct proc *)))eopnotsupp) 229 #define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 230 eopnotsupp) 231 #define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 232 233 struct vfsops portal_vfsops = { 234 portal_mount, 235 portal_start, 236 portal_unmount, 237 portal_root, 238 portal_quotactl, 239 portal_statfs, 240 portal_sync, 241 portal_vget, 242 portal_fhtovp, 243 portal_vptofh, 244 portal_init, 245 portal_sysctl, 246 }; 247