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