Home | History | Annotate | Line # | Download | only in kernfs
kernfs_vfsops.c revision 1.8
      1 /*
      2  * Copyright (c) 1990, 1992 Jan-Simon Pendry
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed 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  *	$Id: kernfs_vfsops.c,v 1.8 1993/08/23 05:02:14 cgd Exp $
     37  */
     38 
     39 /*
     40  * Kernel params Filesystem
     41  */
     42 
     43 #include "param.h"
     44 #include "systm.h"
     45 #include "time.h"
     46 #include "types.h"
     47 #include "proc.h"
     48 #include "vnode.h"
     49 #include "mount.h"
     50 #include "namei.h"
     51 #include "malloc.h"
     52 #include "conf.h"
     53 #include "miscfs/kernfs/kernfs.h"
     54 
     55 /* bring in the spec vnodeops for cdevvp */
     56 extern struct vnodeops spec_vnodeops;
     57 
     58 struct vnode *rrootdevvp;
     59 
     60 kernfs_init()
     61 {
     62   int error, bmaj, cmaj;
     63 
     64 #ifdef KERNFS_DIAGNOSTIC
     65   printf("kernfs_init\n");                 /* printed during system boot */
     66 #endif
     67 
     68   bmaj = major(rootdev);
     69 
     70   /* hunt for the raw root device by looking in cdevsw for a matching
     71    * open routine...
     72    */
     73   for (cmaj = 0; cmaj < nchrdev; cmaj++) {
     74     if (cdevsw[cmaj].d_open == bdevsw[bmaj].d_open) {
     75       dev_t cdev = makedev(cmaj, minor(rootdev));
     76       error = cdevvp(cdev, &rrootdevvp);
     77       if (error == 0)
     78 	break;
     79     }
     80   }
     81 
     82   /* this isn't fatal... */
     83   if (error) {
     84     printf("kernfs: no raw root device\n");
     85     rrootdevvp = 0;
     86   }
     87 }
     88 
     89 /*
     90  * Mount the kernel parameter filesystem
     91  */
     92 kernfs_mount(mp, path, data, ndp, p)
     93 	struct mount *mp;
     94 	char *path;
     95 	caddr_t data;
     96 	struct nameidata *ndp;
     97 	struct proc *p;
     98 {
     99 	int error = 0;
    100 	u_int size;
    101 	struct kernfs_mount *fmp;
    102 	struct vnode *rvp;
    103 
    104 #ifdef KERNFS_DIAGNOSTIC
    105 	printf("kernfs_mount(mp = %x)\n", mp);
    106 #endif
    107 
    108 	/*
    109 	 * Update is a no-op
    110 	 */
    111 	if (mp->mnt_flag & MNT_UPDATE)
    112 		return (EOPNOTSUPP);
    113 
    114 	error = getnewvnode(VT_KERNFS, mp, &kernfs_vnodeops, &rvp);
    115 	if (error)
    116 		return (error);
    117 
    118 	fmp = (struct kernfs_mount *) malloc(sizeof(struct kernfs_mount),
    119 				 M_MISCFSMNT, M_WAITOK);
    120 	rvp->v_type = VDIR;
    121 	rvp->v_flag |= VROOT;
    122 	VTOKERN(rvp)->kf_kt = &kernfs_targets[KERNFS_TARGET_ROOT];
    123 #ifdef KERNFS_DIAGNOSTIC
    124 	printf("kernfs_mount: root vp = %x\n", rvp);
    125 #endif
    126 	fmp->kf_root = rvp;
    127 	mp->mnt_flag |= MNT_LOCAL;
    128 	mp->mnt_data = (qaddr_t) fmp;
    129 	getnewfsid(mp, MOUNT_KERNFS);
    130 
    131 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
    132 	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
    133 	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
    134 	bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
    135 #ifdef KERNFS_DIAGNOSTIC
    136 	printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
    137 #endif
    138 	return (0);
    139 }
    140 
    141 kernfs_start(mp, flags, p)
    142 	struct mount *mp;
    143 	int flags;
    144 	struct proc *p;
    145 {
    146 	return (0);
    147 }
    148 
    149 kernfs_unmount(mp, mntflags, p)
    150 	struct mount *mp;
    151 	int mntflags;
    152 	struct proc *p;
    153 {
    154 	int error;
    155 	int flags = 0;
    156 	extern int doforce;
    157 	struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
    158 
    159 #ifdef KERNFS_DIAGNOSTIC
    160 	printf("kernfs_unmount(mp = %x)\n", mp);
    161 #endif
    162 
    163 	if (mntflags & MNT_FORCE) {
    164 		/* kernfs can never be rootfs so don't check for it */
    165 		if (!doforce)
    166 			return (EINVAL);
    167 		flags |= FORCECLOSE;
    168 	}
    169 
    170 	/*
    171 	 * Clear out buffer cache.  I don't think we
    172 	 * ever get anything cached at this level at the
    173 	 * moment, but who knows...
    174 	 */
    175 #ifdef KERNFS_DIAGNOSTIC
    176 	printf("kernfs_unmount: calling mntflushbuf\n");
    177 #endif
    178 	mntflushbuf(mp, 0);
    179 #ifdef KERNFS_DIAGNOSTIC
    180 	printf("kernfs_unmount: calling mntinvalbuf\n");
    181 #endif
    182 	if (mntinvalbuf(mp, 1))
    183 		return (EBUSY);
    184 	if (rootvp->v_usecount > 1)
    185 		return (EBUSY);
    186 #ifdef KERNFS_DIAGNOSTIC
    187 	printf("kernfs_unmount: calling vflush\n");
    188 #endif
    189 	if (error = vflush(mp, rootvp, flags))
    190 		return (error);
    191 
    192 #ifdef KERNFS_DIAGNOSTIC
    193 	vprint("kernfs root", rootvp);
    194 #endif
    195 	/*
    196 	 * Release reference on underlying root vnode
    197 	 */
    198 	vrele(rootvp);
    199 	/*
    200 	 * And blow it away for future re-use
    201 	 */
    202 	vgone(rootvp);
    203 	/*
    204 	 * Finally, throw away the kernfs_mount structure
    205 	 */
    206 	free(mp->mnt_data, M_MISCFSMNT);
    207 	mp->mnt_data = 0;
    208 	return 0;
    209 }
    210 
    211 kernfs_root(mp, vpp)
    212 	struct mount *mp;
    213 	struct vnode **vpp;
    214 {
    215 	struct vnode *vp;
    216 	int error;
    217 
    218 #ifdef KERNFS_DIAGNOSTIC
    219 	printf("kernfs_root(mp = %x)\n", mp);
    220 #endif
    221 
    222 	/*
    223 	 * Return locked reference to root.
    224 	 */
    225 	vp = VFSTOKERNFS(mp)->kf_root;
    226 	VREF(vp);
    227 	VOP_LOCK(vp);
    228 	*vpp = vp;
    229 	return (0);
    230 }
    231 
    232 kernfs_quotactl(mp, cmd, uid, arg, p)
    233 	struct mount *mp;
    234 	int cmd;
    235 	uid_t uid;
    236 	caddr_t arg;
    237 	struct proc *p;
    238 {
    239 	return (EOPNOTSUPP);
    240 }
    241 
    242 kernfs_statfs(mp, sbp, p)
    243 	struct mount *mp;
    244 	struct statfs *sbp;
    245 	struct proc *p;
    246 {
    247 	struct filedesc *fdp;
    248 	int lim;
    249 	int i;
    250 	int last;
    251 	int freefd;
    252 
    253 #ifdef KERNFS_DIAGNOSTIC
    254 	printf("kernfs_statfs(mp = %x)\n", mp);
    255 #endif
    256 
    257 	sbp->f_type = MOUNT_KERNFS;
    258 	sbp->f_flags = 0;
    259 	sbp->f_fsize = DEV_BSIZE;
    260 	sbp->f_bsize = DEV_BSIZE;
    261 	sbp->f_blocks = 2;		/* 1K to keep df happy */
    262 	sbp->f_bfree = 0;
    263 	sbp->f_bavail = 0;
    264 	sbp->f_files = 0;		/* Allow for "." */
    265 	sbp->f_ffree = 0;		/* See comments above */
    266 	if (sbp != &mp->mnt_stat) {
    267 		bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
    268 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
    269 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
    270 	}
    271 	return (0);
    272 }
    273 
    274 kernfs_sync(mp, waitfor)
    275 	struct mount *mp;
    276 	int waitfor;
    277 {
    278 	return (0);
    279 }
    280 
    281 kernfs_fhtovp(mp, fhp, vpp)
    282 	struct mount *mp;
    283 	struct fid *fhp;
    284 	struct vnode **vpp;
    285 {
    286 	return (EOPNOTSUPP);
    287 }
    288 
    289 kernfs_vptofh(vp, fhp)
    290 	struct vnode *vp;
    291 	struct fid *fhp;
    292 {
    293 	return (EOPNOTSUPP);
    294 }
    295 
    296 struct vfsops kernfs_vfsops = {
    297 	kernfs_mount,
    298 	kernfs_start,
    299 	kernfs_unmount,
    300 	kernfs_root,
    301 	kernfs_quotactl,
    302 	kernfs_statfs,
    303 	kernfs_sync,
    304 	kernfs_fhtovp,
    305 	kernfs_vptofh,
    306 	kernfs_init,
    307 };
    308