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