1 /* 2 * Copyright (c) 1992 The Regents of the University of California 3 * Copyright (c) 1990, 1992 Jan-Simon Pendry 4 * All rights reserved. 5 * 6 * This code is derived from software donated to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * From: 38 * Id: kernfs_vfsops.c,v 4.1 1994/01/02 14:42:00 jsp Exp 39 * 40 * $Id: kernfs_vfsops.c,v 1.14 1994/04/23 07:54:55 cgd Exp $ 41 */ 42 43 /* 44 * Kernel params Filesystem 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/time.h> 50 #include <sys/types.h> 51 #include <sys/proc.h> 52 #include <sys/vnode.h> 53 #include <sys/mount.h> 54 #include <sys/namei.h> 55 #include <sys/malloc.h> 56 #include <miscfs/kernfs/kernfs.h> 57 58 kernfs_init() 59 { 60 #ifdef KERNFS_DIAGNOSTIC 61 printf("kernfs_init\n"); /* printed during system boot */ 62 #endif 63 } 64 65 #ifdef notyet 66 void 67 kernfs_rrootdevvp_init() 68 { 69 int error, bmaj, cmaj; 70 71 if (rrootdevvp != NULL) /* then we've already done this */ 72 return; 73 74 error = ENXIO; 75 bmaj = major(rootdev); 76 77 /* 78 * hunt for the raw root device by looking in cdevsw for a matching 79 * open routine... 80 */ 81 for (cmaj = 0; cmaj < nchrdev; cmaj++) { 82 if (cdevsw[cmaj].d_open == bdevsw[bmaj].d_open) { 83 dev_t cdev = makedev(cmaj, minor(rootdev)); 84 85 error = cdevvp(cdev, &rrootdevvp); 86 if (error == 0) 87 return; 88 } 89 } 90 91 /* this isn't fatal... */ 92 if (error) { 93 printf("kernfs: no raw root device\n"); 94 rrootdevvp = NULL; 95 } 96 } 97 #endif 98 99 /* 100 * Mount the kernel parameter filesystem 101 */ 102 kernfs_mount(mp, path, data, ndp, p) 103 struct mount *mp; 104 char *path; 105 caddr_t data; 106 struct nameidata *ndp; 107 struct proc *p; 108 { 109 int error = 0; 110 u_int size; 111 struct kernfs_mount *fmp; 112 struct vnode *rvp; 113 114 #ifdef KERNFS_DIAGNOSTIC 115 printf("kernfs_mount(mp = %x)\n", mp); 116 #endif 117 118 /* 119 * Update is a no-op 120 */ 121 if (mp->mnt_flag & MNT_UPDATE) 122 return (EOPNOTSUPP); 123 124 error = getnewvnode(VT_KERNFS, mp, &kernfs_vnodeops, &rvp); 125 if (error) 126 return (error); 127 128 fmp = (struct kernfs_mount *) malloc(sizeof(struct kernfs_mount), 129 M_MISCFSMNT, M_WAITOK); 130 rvp->v_type = VDIR; 131 rvp->v_flag |= VROOT; 132 #ifdef KERNFS_DIAGNOSTIC 133 printf("kernfs_mount: root vp = %x\n", rvp); 134 #endif 135 fmp->kf_root = rvp; 136 mp->mnt_flag |= MNT_LOCAL; 137 mp->mnt_data = (qaddr_t) fmp; 138 getnewfsid(mp, makefstype(MOUNT_KERNFS)); 139 140 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 141 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 142 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 143 bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs")); 144 #ifdef KERNFS_DIAGNOSTIC 145 printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname); 146 #endif 147 148 #ifdef notyet 149 kernfs_rrootdevvp_init(); 150 #endif 151 152 return (0); 153 } 154 155 kernfs_start(mp, flags, p) 156 struct mount *mp; 157 int flags; 158 struct proc *p; 159 { 160 return (0); 161 } 162 163 kernfs_unmount(mp, mntflags, p) 164 struct mount *mp; 165 int mntflags; 166 struct proc *p; 167 { 168 int error; 169 int flags = 0; 170 extern int doforce; 171 struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; 172 173 #ifdef KERNFS_DIAGNOSTIC 174 printf("kernfs_unmount(mp = %x)\n", mp); 175 #endif 176 177 if (mntflags & MNT_FORCE) { 178 /* kernfs can never be rootfs so don't check for it */ 179 if (!doforce) 180 return (EINVAL); 181 flags |= FORCECLOSE; 182 } 183 184 /* 185 * Clear out buffer cache. I don't think we 186 * ever get anything cached at this level at the 187 * moment, but who knows... 188 */ 189 #ifdef KERNFS_DIAGNOSTIC 190 printf("kernfs_unmount: calling mntflushbuf\n"); 191 #endif 192 mntflushbuf(mp, 0); 193 #ifdef KERNFS_DIAGNOSTIC 194 printf("kernfs_unmount: calling mntinvalbuf\n"); 195 #endif 196 if (mntinvalbuf(mp, 1)) 197 return (EBUSY); 198 if (rootvp->v_usecount > 1) 199 return (EBUSY); 200 #ifdef KERNFS_DIAGNOSTIC 201 printf("kernfs_unmount: calling vflush\n"); 202 #endif 203 if (error = vflush(mp, rootvp, flags)) 204 return (error); 205 206 #ifdef KERNFS_DIAGNOSTIC 207 vprint("kernfs root", rootvp); 208 #endif 209 /* 210 * Release reference on underlying root vnode 211 */ 212 vrele(rootvp); 213 /* 214 * And blow it away for future re-use 215 */ 216 vgone(rootvp); 217 /* 218 * Finally, throw away the kernfs_mount structure 219 */ 220 free(mp->mnt_data, M_MISCFSMNT); 221 mp->mnt_data = 0; 222 return 0; 223 } 224 225 kernfs_root(mp, vpp) 226 struct mount *mp; 227 struct vnode **vpp; 228 { 229 struct vnode *vp; 230 int error; 231 232 #ifdef KERNFS_DIAGNOSTIC 233 printf("kernfs_root(mp = %x)\n", mp); 234 #endif 235 236 /* 237 * Return locked reference to root. 238 */ 239 vp = VFSTOKERNFS(mp)->kf_root; 240 VREF(vp); 241 VOP_LOCK(vp); 242 *vpp = vp; 243 return (0); 244 } 245 246 kernfs_quotactl(mp, cmd, uid, arg, p) 247 struct mount *mp; 248 int cmd; 249 uid_t uid; 250 caddr_t arg; 251 struct proc *p; 252 { 253 return (EOPNOTSUPP); 254 } 255 256 kernfs_statfs(mp, sbp, p) 257 struct mount *mp; 258 struct statfs *sbp; 259 struct proc *p; 260 { 261 struct filedesc *fdp; 262 int lim; 263 int i; 264 int last; 265 int freefd; 266 267 #ifdef KERNFS_DIAGNOSTIC 268 printf("kernfs_statfs(mp = %x)\n", mp); 269 #endif 270 271 #ifdef COMPAT_09 272 sbp->f_type = 7; 273 #else 274 sbp->f_type = 0; 275 #endif 276 sbp->f_flags = 0; 277 sbp->f_bsize = DEV_BSIZE; 278 sbp->f_iosize = DEV_BSIZE; 279 sbp->f_blocks = 2; /* 1K to keep df happy */ 280 sbp->f_bfree = 0; 281 sbp->f_bavail = 0; 282 sbp->f_files = 0; /* Allow for "." */ 283 sbp->f_ffree = 0; /* See comments above */ 284 if (sbp != &mp->mnt_stat) { 285 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 286 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 287 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 288 } 289 strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN); 290 sbp->f_fstypename[MFSNAMELEN] = '\0'; 291 return (0); 292 } 293 294 kernfs_sync(mp, waitfor) 295 struct mount *mp; 296 int waitfor; 297 { 298 return (0); 299 } 300 301 kernfs_fhtovp(mp, fhp, vpp) 302 struct mount *mp; 303 struct fid *fhp; 304 struct vnode **vpp; 305 { 306 return (EOPNOTSUPP); 307 } 308 309 kernfs_vptofh(vp, fhp) 310 struct vnode *vp; 311 struct fid *fhp; 312 { 313 return (EOPNOTSUPP); 314 } 315 316 struct vfsops kernfs_vfsops = { 317 MOUNT_KERNFS, 318 kernfs_mount, 319 kernfs_start, 320 kernfs_unmount, 321 kernfs_root, 322 kernfs_quotactl, 323 kernfs_statfs, 324 kernfs_sync, 325 kernfs_fhtovp, 326 kernfs_vptofh, 327 kernfs_init, 328 }; 329