1 /* $NetBSD: procfs_vfsops.c,v 1.34 2000/06/10 18:27:03 assar Exp $ */ 2 3 /* 4 * Copyright (c) 1993 Jan-Simon Pendry 5 * Copyright (c) 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95 40 */ 41 42 /* 43 * procfs VFS interface 44 */ 45 46 #if defined(_KERNEL) && !defined(_LKM) 47 #include "opt_compat_netbsd.h" 48 #endif 49 50 #include <sys/param.h> 51 #include <sys/time.h> 52 #include <sys/kernel.h> 53 #include <sys/systm.h> 54 #include <sys/proc.h> 55 #include <sys/buf.h> 56 #include <sys/syslog.h> 57 #include <sys/mount.h> 58 #include <sys/signalvar.h> 59 #include <sys/vnode.h> 60 #include <sys/malloc.h> 61 #include <miscfs/procfs/procfs.h> 62 #include <vm/vm.h> /* for PAGE_SIZE */ 63 64 void procfs_init __P((void)); 65 void procfs_done __P((void)); 66 int procfs_mount __P((struct mount *, const char *, void *, 67 struct nameidata *, struct proc *)); 68 int procfs_start __P((struct mount *, int, struct proc *)); 69 int procfs_unmount __P((struct mount *, int, struct proc *)); 70 int procfs_quotactl __P((struct mount *, int, uid_t, caddr_t, 71 struct proc *)); 72 int procfs_statfs __P((struct mount *, struct statfs *, struct proc *)); 73 int procfs_sync __P((struct mount *, int, struct ucred *, struct proc *)); 74 int procfs_vget __P((struct mount *, ino_t, struct vnode **)); 75 int procfs_fhtovp __P((struct mount *, struct fid *, struct vnode **)); 76 int procfs_checkexp __P((struct mount *, struct mbuf *, int *, 77 struct ucred **)); 78 int procfs_vptofh __P((struct vnode *, struct fid *)); 79 int procfs_sysctl __P((int *, u_int, void *, size_t *, void *, size_t, 80 struct proc *)); 81 /* 82 * VFS Operations. 83 * 84 * mount system call 85 */ 86 /* ARGSUSED */ 87 int 88 procfs_mount(mp, path, data, ndp, p) 89 struct mount *mp; 90 const char *path; 91 void *data; 92 struct nameidata *ndp; 93 struct proc *p; 94 { 95 size_t size; 96 struct procfsmount *pmnt; 97 98 if (UIO_MX & (UIO_MX-1)) { 99 log(LOG_ERR, "procfs: invalid directory entry size"); 100 return (EINVAL); 101 } 102 103 if (mp->mnt_flag & MNT_UPDATE) 104 return (EOPNOTSUPP); 105 106 mp->mnt_flag |= MNT_LOCAL; 107 pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount), 108 M_UFSMNT, M_WAITOK); /* XXX need new malloc type */ 109 110 mp->mnt_data = (qaddr_t)pmnt; 111 vfs_getnewfsid(mp); 112 113 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN, &size); 114 memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size); 115 memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); 116 memcpy(mp->mnt_stat.f_mntfromname, "procfs", sizeof("procfs")); 117 118 pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp); 119 pmnt->pmnt_mp = mp; 120 121 return (0); 122 } 123 124 /* 125 * unmount system call 126 */ 127 int 128 procfs_unmount(mp, mntflags, p) 129 struct mount *mp; 130 int mntflags; 131 struct proc *p; 132 { 133 int error; 134 int flags = 0; 135 136 if (mntflags & MNT_FORCE) 137 flags |= FORCECLOSE; 138 139 if ((error = vflush(mp, 0, flags)) != 0) 140 return (error); 141 142 exechook_disestablish(VFSTOPROC(mp)->pmnt_exechook); 143 144 free(mp->mnt_data, M_UFSMNT); 145 mp->mnt_data = 0; 146 147 return (0); 148 } 149 150 int 151 procfs_root(mp, vpp) 152 struct mount *mp; 153 struct vnode **vpp; 154 { 155 156 return (procfs_allocvp(mp, vpp, 0, Proot)); 157 } 158 159 /* ARGSUSED */ 160 int 161 procfs_start(mp, flags, p) 162 struct mount *mp; 163 int flags; 164 struct proc *p; 165 { 166 167 return (0); 168 } 169 170 /* 171 * Get file system statistics. 172 */ 173 int 174 procfs_statfs(mp, sbp, p) 175 struct mount *mp; 176 struct statfs *sbp; 177 struct proc *p; 178 { 179 180 sbp->f_bsize = PAGE_SIZE; 181 sbp->f_iosize = PAGE_SIZE; 182 sbp->f_blocks = 1; /* avoid divide by zero in some df's */ 183 sbp->f_bfree = 0; 184 sbp->f_bavail = 0; 185 sbp->f_files = maxproc; /* approx */ 186 sbp->f_ffree = maxproc - nprocs; /* approx */ 187 #ifdef COMPAT_09 188 sbp->f_type = 10; 189 #else 190 sbp->f_type = 0; 191 #endif 192 if (sbp != &mp->mnt_stat) { 193 memcpy(&sbp->f_fsid, &mp->mnt_stat.f_fsid, sizeof(sbp->f_fsid)); 194 memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN); 195 memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN); 196 } 197 strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); 198 return (0); 199 } 200 201 /*ARGSUSED*/ 202 int 203 procfs_quotactl(mp, cmds, uid, arg, p) 204 struct mount *mp; 205 int cmds; 206 uid_t uid; 207 caddr_t arg; 208 struct proc *p; 209 { 210 211 return (EOPNOTSUPP); 212 } 213 214 /*ARGSUSED*/ 215 int 216 procfs_sync(mp, waitfor, uc, p) 217 struct mount *mp; 218 int waitfor; 219 struct ucred *uc; 220 struct proc *p; 221 { 222 223 return (0); 224 } 225 226 /*ARGSUSED*/ 227 int 228 procfs_vget(mp, ino, vpp) 229 struct mount *mp; 230 ino_t ino; 231 struct vnode **vpp; 232 { 233 234 return (EOPNOTSUPP); 235 } 236 237 /*ARGSUSED*/ 238 int 239 procfs_fhtovp(mp, fhp, vpp) 240 struct mount *mp; 241 struct fid *fhp; 242 struct vnode **vpp; 243 { 244 245 return (EINVAL); 246 } 247 248 /*ARGSUSED*/ 249 int 250 procfs_checkexp(mp, mb, what, anon) 251 struct mount *mp; 252 struct mbuf *mb; 253 int *what; 254 struct ucred **anon; 255 { 256 257 return (EINVAL); 258 } 259 260 /*ARGSUSED*/ 261 int 262 procfs_vptofh(vp, fhp) 263 struct vnode *vp; 264 struct fid *fhp; 265 { 266 267 return (EINVAL); 268 } 269 270 void 271 procfs_init() 272 { 273 procfs_hashinit(); 274 } 275 276 void 277 procfs_done() 278 { 279 procfs_hashdone(); 280 } 281 282 int 283 procfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 284 int *name; 285 u_int namelen; 286 void *oldp; 287 size_t *oldlenp; 288 void *newp; 289 size_t newlen; 290 struct proc *p; 291 { 292 return (EOPNOTSUPP); 293 } 294 295 extern struct vnodeopv_desc procfs_vnodeop_opv_desc; 296 297 struct vnodeopv_desc *procfs_vnodeopv_descs[] = { 298 &procfs_vnodeop_opv_desc, 299 NULL, 300 }; 301 302 struct vfsops procfs_vfsops = { 303 MOUNT_PROCFS, 304 procfs_mount, 305 procfs_start, 306 procfs_unmount, 307 procfs_root, 308 procfs_quotactl, 309 procfs_statfs, 310 procfs_sync, 311 procfs_vget, 312 procfs_fhtovp, 313 procfs_vptofh, 314 procfs_init, 315 procfs_done, 316 procfs_sysctl, 317 NULL, /* vfs_mountroot */ 318 procfs_checkexp, 319 procfs_vnodeopv_descs, 320 }; 321