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 * %sccs.include.redist.c% 10 * 11 * @(#)kernfs_vfsops.c 7.1 (Berkeley) 07/18/92 12 */ 13 14 /* 15 * Kernel params Filesystem 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/time.h> 21 #include <sys/types.h> 22 #include <sys/proc.h> 23 #include <sys/vnode.h> 24 #include <sys/mount.h> 25 #include <sys/namei.h> 26 #include <sys/malloc.h> 27 #include <miscfs/kernfs/kernfs.h> 28 29 kernfs_init() 30 { 31 #ifdef KERNFS_DIAGNOSTIC 32 printf("kernfs_init\n"); /* printed during system boot */ 33 #endif 34 } 35 36 /* 37 * Mount the Kernel params filesystem 38 */ 39 kernfs_mount(mp, path, data, ndp, p) 40 struct mount *mp; 41 char *path; 42 caddr_t data; 43 struct nameidata *ndp; 44 struct proc *p; 45 { 46 int error = 0; 47 u_int size; 48 struct kernfs_mount *fmp; 49 struct vnode *rvp; 50 51 #ifdef KERNFS_DIAGNOSTIC 52 printf("kernfs_mount(mp = %x)\n", mp); 53 #endif 54 55 /* 56 * Update is a no-op 57 */ 58 if (mp->mnt_flag & MNT_UPDATE) 59 return (EOPNOTSUPP); 60 61 error = getnewvnode(VT_UFS, mp, kernfs_vnodeop_p, &rvp); /* XXX */ 62 if (error) 63 return (error); 64 65 MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount), 66 M_UFSMNT, M_WAITOK); /* XXX */ 67 rvp->v_type = VDIR; 68 rvp->v_flag |= VROOT; 69 #ifdef KERNFS_DIAGNOSTIC 70 printf("kernfs_mount: root vp = %x\n", rvp); 71 #endif 72 fmp->kf_root = rvp; 73 mp->mnt_flag |= MNT_LOCAL; 74 mp->mnt_data = (qaddr_t) fmp; 75 getnewfsid(mp, MOUNT_KERNFS); 76 77 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 78 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 79 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 80 bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs")); 81 #ifdef KERNFS_DIAGNOSTIC 82 printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname); 83 #endif 84 return (0); 85 } 86 87 kernfs_start(mp, flags, p) 88 struct mount *mp; 89 int flags; 90 struct proc *p; 91 { 92 return (0); 93 } 94 95 kernfs_unmount(mp, mntflags, p) 96 struct mount *mp; 97 int mntflags; 98 struct proc *p; 99 { 100 int error; 101 int flags = 0; 102 extern int doforce; 103 struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; 104 105 #ifdef KERNFS_DIAGNOSTIC 106 printf("kernfs_unmount(mp = %x)\n", mp); 107 #endif 108 109 if (mntflags & MNT_FORCE) { 110 /* kernfs can never be rootfs so don't check for it */ 111 if (!doforce) 112 return (EINVAL); 113 flags |= FORCECLOSE; 114 } 115 116 /* 117 * Clear out buffer cache. I don't think we 118 * ever get anything cached at this level at the 119 * moment, but who knows... 120 */ 121 #if 0 122 #ifdef KERNFS_DIAGNOSTIC 123 printf("kernfs_unmount: calling mntflushbuf\n"); 124 #endif 125 mntflushbuf(mp, 0); 126 #ifdef KERNFS_DIAGNOSTIC 127 printf("kernfs_unmount: calling mntinvalbuf\n"); 128 #endif 129 if (mntinvalbuf(mp, 1)) 130 return (EBUSY); 131 #endif 132 if (rootvp->v_usecount > 1) 133 return (EBUSY); 134 #ifdef KERNFS_DIAGNOSTIC 135 printf("kernfs_unmount: calling vflush\n"); 136 #endif 137 if (error = vflush(mp, rootvp, flags)) 138 return (error); 139 140 #ifdef KERNFS_DIAGNOSTIC 141 vprint("kernfs root", rootvp); 142 #endif 143 /* 144 * Release reference on underlying root vnode 145 */ 146 vrele(rootvp); 147 /* 148 * And blow it away for future re-use 149 */ 150 vgone(rootvp); 151 /* 152 * Finally, throw away the kernfs_mount structure 153 */ 154 free(mp->mnt_data, M_UFSMNT); /* XXX */ 155 mp->mnt_data = 0; 156 return 0; 157 } 158 159 kernfs_root(mp, vpp) 160 struct mount *mp; 161 struct vnode **vpp; 162 { 163 struct vnode *vp; 164 int error; 165 166 #ifdef KERNFS_DIAGNOSTIC 167 printf("kernfs_root(mp = %x)\n", mp); 168 #endif 169 170 /* 171 * Return locked reference to root. 172 */ 173 vp = VFSTOKERNFS(mp)->kf_root; 174 VREF(vp); 175 VOP_LOCK(vp); 176 *vpp = vp; 177 return (0); 178 } 179 180 kernfs_quotactl(mp, cmd, uid, arg, p) 181 struct mount *mp; 182 int cmd; 183 uid_t uid; 184 caddr_t arg; 185 struct proc *p; 186 { 187 return (EOPNOTSUPP); 188 } 189 190 kernfs_statfs(mp, sbp, p) 191 struct mount *mp; 192 struct statfs *sbp; 193 struct proc *p; 194 { 195 #ifdef KERNFS_DIAGNOSTIC 196 printf("kernfs_statfs(mp = %x)\n", mp); 197 #endif 198 199 sbp->f_type = MOUNT_KERNFS; 200 sbp->f_flags = 0; 201 sbp->f_bsize = DEV_BSIZE; 202 sbp->f_iosize = DEV_BSIZE; 203 sbp->f_blocks = 2; /* 1K to keep df happy */ 204 sbp->f_bfree = 0; 205 sbp->f_bavail = 0; 206 sbp->f_files = 0; /* Allow for "." */ 207 sbp->f_ffree = 0; /* See comments above */ 208 if (sbp != &mp->mnt_stat) { 209 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 210 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 211 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 212 } 213 return (0); 214 } 215 216 kernfs_sync(mp, waitfor) 217 struct mount *mp; 218 int waitfor; 219 { 220 return (0); 221 } 222 223 /* 224 * Fdesc flat namespace lookup. 225 * Currently unsupported. 226 */ 227 kernfs_vget(mp, ino, vpp) 228 struct mount *mp; 229 ino_t ino; 230 struct vnode **vpp; 231 { 232 233 return (EOPNOTSUPP); 234 } 235 236 237 kernfs_fhtovp(mp, fhp, setgen, vpp) 238 struct mount *mp; 239 struct fid *fhp; 240 int setgen; 241 struct vnode **vpp; 242 { 243 return (EOPNOTSUPP); 244 } 245 246 kernfs_vptofh(vp, fhp) 247 struct vnode *vp; 248 struct fid *fhp; 249 { 250 return (EOPNOTSUPP); 251 } 252 253 struct vfsops kernfs_vfsops = { 254 kernfs_mount, 255 kernfs_start, 256 kernfs_unmount, 257 kernfs_root, 258 kernfs_quotactl, 259 kernfs_statfs, 260 kernfs_sync, 261 kernfs_vget, 262 kernfs_fhtovp, 263 kernfs_vptofh, 264 kernfs_init, 265 }; 266