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