155344Spendry /*
255344Spendry  * Copyright (c) 1992 The Regents of the University of California
355344Spendry  * Copyright (c) 1990, 1992 Jan-Simon Pendry
455344Spendry  * All rights reserved.
555344Spendry  *
655344Spendry  * This code is derived from software donated to Berkeley by
755344Spendry  * Jan-Simon Pendry.
855344Spendry  *
955344Spendry  * %sccs.include.redist.c%
1055344Spendry  *
11*55351Spendry  *	@(#)kernfs_vfsops.c	7.2 (Berkeley) 07/18/92
1255344Spendry  */
1355344Spendry 
1455344Spendry /*
1555344Spendry  * Kernel params Filesystem
1655344Spendry  */
1755344Spendry 
1855344Spendry #include <sys/param.h>
1955344Spendry #include <sys/systm.h>
2055344Spendry #include <sys/time.h>
2155344Spendry #include <sys/types.h>
2255344Spendry #include <sys/proc.h>
2355344Spendry #include <sys/vnode.h>
2455344Spendry #include <sys/mount.h>
2555344Spendry #include <sys/namei.h>
2655344Spendry #include <sys/malloc.h>
2755344Spendry #include <miscfs/kernfs/kernfs.h>
2855344Spendry 
2955344Spendry kernfs_init()
3055344Spendry {
3155344Spendry #ifdef KERNFS_DIAGNOSTIC
3255344Spendry 	printf("kernfs_init\n");		/* printed during system boot */
3355344Spendry #endif
3455344Spendry }
3555344Spendry 
3655344Spendry /*
3755344Spendry  * Mount the Kernel params filesystem
3855344Spendry  */
3955344Spendry kernfs_mount(mp, path, data, ndp, p)
4055344Spendry 	struct mount *mp;
4155344Spendry 	char *path;
4255344Spendry 	caddr_t data;
4355344Spendry 	struct nameidata *ndp;
4455344Spendry 	struct proc *p;
4555344Spendry {
4655344Spendry 	int error = 0;
4755344Spendry 	u_int size;
4855344Spendry 	struct kernfs_mount *fmp;
4955344Spendry 	struct vnode *rvp;
5055344Spendry 
5155344Spendry #ifdef KERNFS_DIAGNOSTIC
5255344Spendry 	printf("kernfs_mount(mp = %x)\n", mp);
5355344Spendry #endif
5455344Spendry 
5555344Spendry 	/*
5655344Spendry 	 * Update is a no-op
5755344Spendry 	 */
5855344Spendry 	if (mp->mnt_flag & MNT_UPDATE)
5955344Spendry 		return (EOPNOTSUPP);
6055344Spendry 
6155344Spendry 	error = getnewvnode(VT_UFS, mp, kernfs_vnodeop_p, &rvp);	/* XXX */
6255344Spendry 	if (error)
6355344Spendry 		return (error);
6455344Spendry 
6555344Spendry 	MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount),
6655344Spendry 				M_UFSMNT, M_WAITOK);	/* XXX */
6755344Spendry 	rvp->v_type = VDIR;
6855344Spendry 	rvp->v_flag |= VROOT;
6955344Spendry #ifdef KERNFS_DIAGNOSTIC
7055344Spendry 	printf("kernfs_mount: root vp = %x\n", rvp);
7155344Spendry #endif
7255344Spendry 	fmp->kf_root = rvp;
7355344Spendry 	mp->mnt_flag |= MNT_LOCAL;
7455344Spendry 	mp->mnt_data = (qaddr_t) fmp;
7555344Spendry 	getnewfsid(mp, MOUNT_KERNFS);
7655344Spendry 
7755344Spendry 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
7855344Spendry 	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
7955344Spendry 	bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
8055344Spendry 	bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
8155344Spendry #ifdef KERNFS_DIAGNOSTIC
8255344Spendry 	printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
8355344Spendry #endif
8455344Spendry 	return (0);
8555344Spendry }
8655344Spendry 
8755344Spendry kernfs_start(mp, flags, p)
8855344Spendry 	struct mount *mp;
8955344Spendry 	int flags;
9055344Spendry 	struct proc *p;
9155344Spendry {
9255344Spendry 	return (0);
9355344Spendry }
9455344Spendry 
9555344Spendry kernfs_unmount(mp, mntflags, p)
9655344Spendry 	struct mount *mp;
9755344Spendry 	int mntflags;
9855344Spendry 	struct proc *p;
9955344Spendry {
10055344Spendry 	int error;
10155344Spendry 	int flags = 0;
10255344Spendry 	extern int doforce;
10355344Spendry 	struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
10455344Spendry 
10555344Spendry #ifdef KERNFS_DIAGNOSTIC
10655344Spendry 	printf("kernfs_unmount(mp = %x)\n", mp);
10755344Spendry #endif
10855344Spendry 
10955344Spendry 	if (mntflags & MNT_FORCE) {
11055344Spendry 		/* kernfs can never be rootfs so don't check for it */
11155344Spendry 		if (!doforce)
11255344Spendry 			return (EINVAL);
11355344Spendry 		flags |= FORCECLOSE;
11455344Spendry 	}
11555344Spendry 
11655344Spendry 	/*
11755344Spendry 	 * Clear out buffer cache.  I don't think we
11855344Spendry 	 * ever get anything cached at this level at the
11955344Spendry 	 * moment, but who knows...
12055344Spendry 	 */
12155344Spendry #if 0
12255344Spendry #ifdef KERNFS_DIAGNOSTIC
12355344Spendry 	printf("kernfs_unmount: calling mntflushbuf\n");
12455344Spendry #endif
125*55351Spendry 	mntflushbuf(mp, 0);
12655344Spendry #ifdef KERNFS_DIAGNOSTIC
12755344Spendry 	printf("kernfs_unmount: calling mntinvalbuf\n");
12855344Spendry #endif
12955344Spendry 	if (mntinvalbuf(mp, 1))
13055344Spendry 		return (EBUSY);
13155344Spendry #endif
13255344Spendry 	if (rootvp->v_usecount > 1)
13355344Spendry 		return (EBUSY);
13455344Spendry #ifdef KERNFS_DIAGNOSTIC
13555344Spendry 	printf("kernfs_unmount: calling vflush\n");
13655344Spendry #endif
13755344Spendry 	if (error = vflush(mp, rootvp, flags))
13855344Spendry 		return (error);
13955344Spendry 
14055344Spendry #ifdef KERNFS_DIAGNOSTIC
14155344Spendry 	vprint("kernfs root", rootvp);
142*55351Spendry #endif
14355344Spendry 	/*
14455344Spendry 	 * Release reference on underlying root vnode
14555344Spendry 	 */
14655344Spendry 	vrele(rootvp);
14755344Spendry 	/*
14855344Spendry 	 * And blow it away for future re-use
14955344Spendry 	 */
15055344Spendry 	vgone(rootvp);
15155344Spendry 	/*
15255344Spendry 	 * Finally, throw away the kernfs_mount structure
15355344Spendry 	 */
15455344Spendry 	free(mp->mnt_data, M_UFSMNT);	/* XXX */
15555344Spendry 	mp->mnt_data = 0;
15655344Spendry 	return 0;
15755344Spendry }
15855344Spendry 
15955344Spendry kernfs_root(mp, vpp)
16055344Spendry 	struct mount *mp;
16155344Spendry 	struct vnode **vpp;
16255344Spendry {
16355344Spendry 	struct vnode *vp;
16455344Spendry 	int error;
16555344Spendry 
16655344Spendry #ifdef KERNFS_DIAGNOSTIC
16755344Spendry 	printf("kernfs_root(mp = %x)\n", mp);
16855344Spendry #endif
16955344Spendry 
17055344Spendry 	/*
17155344Spendry 	 * Return locked reference to root.
17255344Spendry 	 */
17355344Spendry 	vp = VFSTOKERNFS(mp)->kf_root;
17455344Spendry 	VREF(vp);
17555344Spendry 	VOP_LOCK(vp);
17655344Spendry 	*vpp = vp;
17755344Spendry 	return (0);
17855344Spendry }
17955344Spendry 
18055344Spendry kernfs_quotactl(mp, cmd, uid, arg, p)
18155344Spendry 	struct mount *mp;
18255344Spendry 	int cmd;
18355344Spendry 	uid_t uid;
18455344Spendry 	caddr_t arg;
18555344Spendry 	struct proc *p;
18655344Spendry {
18755344Spendry 	return (EOPNOTSUPP);
18855344Spendry }
18955344Spendry 
19055344Spendry kernfs_statfs(mp, sbp, p)
19155344Spendry 	struct mount *mp;
19255344Spendry 	struct statfs *sbp;
19355344Spendry 	struct proc *p;
19455344Spendry {
19555344Spendry #ifdef KERNFS_DIAGNOSTIC
19655344Spendry 	printf("kernfs_statfs(mp = %x)\n", mp);
19755344Spendry #endif
19855344Spendry 
19955344Spendry 	sbp->f_type = MOUNT_KERNFS;
20055344Spendry 	sbp->f_flags = 0;
20155344Spendry 	sbp->f_bsize = DEV_BSIZE;
20255344Spendry 	sbp->f_iosize = DEV_BSIZE;
20355344Spendry 	sbp->f_blocks = 2;		/* 1K to keep df happy */
20455344Spendry 	sbp->f_bfree = 0;
20555344Spendry 	sbp->f_bavail = 0;
20655344Spendry 	sbp->f_files = 0;		/* Allow for "." */
20755344Spendry 	sbp->f_ffree = 0;		/* See comments above */
20855344Spendry 	if (sbp != &mp->mnt_stat) {
20955344Spendry 		bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
21055344Spendry 		bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
21155344Spendry 		bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
21255344Spendry 	}
21355344Spendry 	return (0);
21455344Spendry }
21555344Spendry 
21655344Spendry kernfs_sync(mp, waitfor)
21755344Spendry 	struct mount *mp;
21855344Spendry 	int waitfor;
21955344Spendry {
22055344Spendry 	return (0);
22155344Spendry }
22255344Spendry 
22355344Spendry /*
224*55351Spendry  * Kernfs flat namespace lookup.
22555344Spendry  * Currently unsupported.
22655344Spendry  */
22755344Spendry kernfs_vget(mp, ino, vpp)
22855344Spendry 	struct mount *mp;
22955344Spendry 	ino_t ino;
23055344Spendry 	struct vnode **vpp;
23155344Spendry {
23255344Spendry 
23355344Spendry 	return (EOPNOTSUPP);
23455344Spendry }
23555344Spendry 
23655344Spendry 
23755344Spendry kernfs_fhtovp(mp, fhp, setgen, vpp)
23855344Spendry 	struct mount *mp;
23955344Spendry 	struct fid *fhp;
24055344Spendry 	int setgen;
24155344Spendry 	struct vnode **vpp;
24255344Spendry {
24355344Spendry 	return (EOPNOTSUPP);
24455344Spendry }
24555344Spendry 
24655344Spendry kernfs_vptofh(vp, fhp)
24755344Spendry 	struct vnode *vp;
24855344Spendry 	struct fid *fhp;
24955344Spendry {
25055344Spendry 	return (EOPNOTSUPP);
25155344Spendry }
25255344Spendry 
25355344Spendry struct vfsops kernfs_vfsops = {
25455344Spendry 	kernfs_mount,
25555344Spendry 	kernfs_start,
25655344Spendry 	kernfs_unmount,
25755344Spendry 	kernfs_root,
25855344Spendry 	kernfs_quotactl,
25955344Spendry 	kernfs_statfs,
26055344Spendry 	kernfs_sync,
26155344Spendry 	kernfs_vget,
26255344Spendry 	kernfs_fhtovp,
26355344Spendry 	kernfs_vptofh,
26455344Spendry 	kernfs_init,
26555344Spendry };
266