kernfs_vfsops.c revision 1.1 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.redist.c%
10 *
11 * %W% (Berkeley) %G%
12 *
13 * $Id: kernfs_vfsops.c,v 1.1 1993/03/23 23:56:54 cgd Exp $
14 */
15
16 /*
17 * Kernel params Filesystem
18 */
19
20 #include "param.h"
21 #include "systm.h"
22 #include "time.h"
23 #include "types.h"
24 #include "proc.h"
25 #include "vnode.h"
26 #include "mount.h"
27 #include "namei.h"
28 #include "malloc.h"
29 #include "miscfs/kernfs/kernfs.h"
30
31 kernfs_init()
32 {
33 #ifdef KERNFS_DIAGNOSTIC
34 printf("kernfs_init\n"); /* printed during system boot */
35 #endif
36 }
37
38 /*
39 * Mount the kernel parameter filesystem
40 */
41 kernfs_mount(mp, path, data, ndp, p)
42 struct mount *mp;
43 char *path;
44 caddr_t data;
45 struct nameidata *ndp;
46 struct proc *p;
47 {
48 int error = 0;
49 u_int size;
50 struct kernfs_mount *fmp;
51 struct vnode *rvp;
52
53 #ifdef KERNFS_DIAGNOSTIC
54 printf("kernfs_mount(mp = %x)\n", mp);
55 #endif
56
57 /*
58 * Update is a no-op
59 */
60 if (mp->mnt_flag & MNT_UPDATE)
61 return (EOPNOTSUPP);
62
63 error = getnewvnode(VT_UFS, mp, &kernfs_vnodeops, &rvp); /* XXX */
64 if (error)
65 return (error);
66
67 fmp = (struct kernfs_mount *) malloc(sizeof(struct kernfs_mount),
68 M_UFSMNT, M_WAITOK); /* XXX */
69 rvp->v_type = VDIR;
70 rvp->v_flag |= VROOT;
71 #ifdef KERNFS_DIAGNOSTIC
72 printf("kernfs_mount: root vp = %x\n", rvp);
73 #endif
74 fmp->kf_root = rvp;
75 mp->mnt_flag |= MNT_LOCAL;
76 mp->mnt_data = (qaddr_t) fmp;
77 getnewfsid(mp, MOUNT_KERNFS);
78
79 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
80 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
81 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
82 bcopy("kernfs", mp->mnt_stat.f_mntfromname, sizeof("kernfs"));
83 #ifdef KERNFS_DIAGNOSTIC
84 printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
85 #endif
86 return (0);
87 }
88
89 kernfs_start(mp, flags, p)
90 struct mount *mp;
91 int flags;
92 struct proc *p;
93 {
94 return (0);
95 }
96
97 kernfs_unmount(mp, mntflags, p)
98 struct mount *mp;
99 int mntflags;
100 struct proc *p;
101 {
102 int error;
103 int flags = 0;
104 extern int doforce;
105 struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
106
107 #ifdef KERNFS_DIAGNOSTIC
108 printf("kernfs_unmount(mp = %x)\n", mp);
109 #endif
110
111 if (mntflags & MNT_FORCE) {
112 /* kernfs can never be rootfs so don't check for it */
113 if (!doforce)
114 return (EINVAL);
115 flags |= FORCECLOSE;
116 }
117
118 /*
119 * Clear out buffer cache. I don't think we
120 * ever get anything cached at this level at the
121 * moment, but who knows...
122 */
123 #ifdef KERNFS_DIAGNOSTIC
124 printf("kernfs_unmount: calling mntflushbuf\n");
125 #endif
126 mntflushbuf(mp, 0);
127 #ifdef KERNFS_DIAGNOSTIC
128 printf("kernfs_unmount: calling mntinvalbuf\n");
129 #endif
130 if (mntinvalbuf(mp, 1))
131 return (EBUSY);
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 struct filedesc *fdp;
196 int lim;
197 int i;
198 int last;
199 int freefd;
200
201 #ifdef KERNFS_DIAGNOSTIC
202 printf("kernfs_statfs(mp = %x)\n", mp);
203 #endif
204
205 sbp->f_type = MOUNT_KERNFS;
206 sbp->f_flags = 0;
207 sbp->f_fsize = DEV_BSIZE;
208 sbp->f_bsize = DEV_BSIZE;
209 sbp->f_blocks = 2; /* 1K to keep df happy */
210 sbp->f_bfree = 0;
211 sbp->f_bavail = 0;
212 sbp->f_files = 0; /* Allow for "." */
213 sbp->f_ffree = 0; /* See comments above */
214 if (sbp != &mp->mnt_stat) {
215 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
216 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
217 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
218 }
219 return (0);
220 }
221
222 kernfs_sync(mp, waitfor)
223 struct mount *mp;
224 int waitfor;
225 {
226 return (0);
227 }
228
229 kernfs_fhtovp(mp, fhp, vpp)
230 struct mount *mp;
231 struct fid *fhp;
232 struct vnode **vpp;
233 {
234 return (EOPNOTSUPP);
235 }
236
237 kernfs_vptofh(vp, fhp)
238 struct vnode *vp;
239 struct fid *fhp;
240 {
241 return (EOPNOTSUPP);
242 }
243
244 struct vfsops kernfs_vfsops = {
245 kernfs_mount,
246 kernfs_start,
247 kernfs_unmount,
248 kernfs_root,
249 kernfs_quotactl,
250 kernfs_statfs,
251 kernfs_sync,
252 kernfs_fhtovp,
253 kernfs_vptofh,
254 kernfs_init,
255 };
256