Deleted Added
full compact
null_vfsops.c (1541) null_vfsops.c (2946)
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software donated 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 * @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
37 *
38 * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software donated 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 * @(#)null_vfsops.c 8.2 (Berkeley) 1/21/94
37 *
38 * @(#)lofs_vfsops.c 1.2 (Berkeley) 6/18/92
39 * $Id: lofs_vfsops.c,v 1.9 1992/05/30 10:26:24 jsp Exp jsp $
39 * $Id: null_vfsops.c,v 1.1.1.1 1994/05/24 10:05:03 rgrimes Exp $
40 */
41
42/*
43 * Null Layer
44 * (See null_vnops.c for a description of what this does.)
45 */
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/time.h>
50#include <sys/types.h>
51#include <sys/vnode.h>
52#include <sys/mount.h>
53#include <sys/namei.h>
54#include <sys/malloc.h>
55#include <miscfs/nullfs/null.h>
56
57/*
58 * Mount null layer
59 */
60int
61nullfs_mount(mp, path, data, ndp, p)
62 struct mount *mp;
63 char *path;
64 caddr_t data;
65 struct nameidata *ndp;
66 struct proc *p;
67{
68 int error = 0;
69 struct null_args args;
70 struct vnode *lowerrootvp, *vp;
71 struct vnode *nullm_rootvp;
72 struct null_mount *xmp;
73 u_int size;
74
75#ifdef NULLFS_DIAGNOSTIC
76 printf("nullfs_mount(mp = %x)\n", mp);
77#endif
78
79 /*
80 * Update is a no-op
81 */
82 if (mp->mnt_flag & MNT_UPDATE) {
83 return (EOPNOTSUPP);
84 /* return VFS_MOUNT(MOUNTTONULLMOUNT(mp)->nullm_vfs, path, data, ndp, p);*/
85 }
86
87 /*
88 * Get argument
89 */
90 if (error = copyin(data, (caddr_t)&args, sizeof(struct null_args)))
91 return (error);
92
93 /*
94 * Find lower node
95 */
96 NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
97 UIO_USERSPACE, args.target, p);
98 if (error = namei(ndp))
99 return (error);
100
101 /*
102 * Sanity check on lower vnode
103 */
104 lowerrootvp = ndp->ni_vp;
105
106 vrele(ndp->ni_dvp);
107 ndp->ni_dvp = NULL;
108
109 xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
110 M_UFSMNT, M_WAITOK); /* XXX */
111
112 /*
113 * Save reference to underlying FS
114 */
115 xmp->nullm_vfs = lowerrootvp->v_mount;
116
117 /*
118 * Save reference. Each mount also holds
119 * a reference on the root vnode.
120 */
121 error = null_node_create(mp, lowerrootvp, &vp);
122 /*
123 * Unlock the node (either the lower or the alias)
124 */
125 VOP_UNLOCK(vp);
126 /*
127 * Make sure the node alias worked
128 */
129 if (error) {
130 vrele(lowerrootvp);
131 free(xmp, M_UFSMNT); /* XXX */
132 return (error);
133 }
134
135 /*
136 * Keep a held reference to the root vnode.
137 * It is vrele'd in nullfs_unmount.
138 */
139 nullm_rootvp = vp;
140 nullm_rootvp->v_flag |= VROOT;
141 xmp->nullm_rootvp = nullm_rootvp;
142 if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
143 mp->mnt_flag |= MNT_LOCAL;
144 mp->mnt_data = (qaddr_t) xmp;
145 getnewfsid(mp, MOUNT_LOFS);
146
147 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
148 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
149 (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
150 &size);
151 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
152#ifdef NULLFS_DIAGNOSTIC
153 printf("nullfs_mount: lower %s, alias at %s\n",
154 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
155#endif
156 return (0);
157}
158
159/*
160 * VFS start. Nothing needed here - the start routine
161 * on the underlying filesystem will have been called
162 * when that filesystem was mounted.
163 */
164int
165nullfs_start(mp, flags, p)
166 struct mount *mp;
167 int flags;
168 struct proc *p;
169{
170 return (0);
171 /* return VFS_START(MOUNTTONULLMOUNT(mp)->nullm_vfs, flags, p); */
172}
173
174/*
175 * Free reference to null layer
176 */
177int
178nullfs_unmount(mp, mntflags, p)
179 struct mount *mp;
180 int mntflags;
181 struct proc *p;
182{
183 struct vnode *nullm_rootvp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
184 int error;
185 int flags = 0;
186 extern int doforce;
187
188#ifdef NULLFS_DIAGNOSTIC
189 printf("nullfs_unmount(mp = %x)\n", mp);
190#endif
191
192 if (mntflags & MNT_FORCE) {
193 /* lofs can never be rootfs so don't check for it */
194 if (!doforce)
195 return (EINVAL);
196 flags |= FORCECLOSE;
197 }
198
199 /*
200 * Clear out buffer cache. I don't think we
201 * ever get anything cached at this level at the
202 * moment, but who knows...
203 */
204#if 0
205 mntflushbuf(mp, 0);
206 if (mntinvalbuf(mp, 1))
207 return (EBUSY);
208#endif
209 if (nullm_rootvp->v_usecount > 1)
210 return (EBUSY);
211 if (error = vflush(mp, nullm_rootvp, flags))
212 return (error);
213
214#ifdef NULLFS_DIAGNOSTIC
215 vprint("alias root of lower", nullm_rootvp);
216#endif
217 /*
218 * Release reference on underlying root vnode
219 */
220 vrele(nullm_rootvp);
221 /*
222 * And blow it away for future re-use
223 */
224 vgone(nullm_rootvp);
225 /*
226 * Finally, throw away the null_mount structure
227 */
228 free(mp->mnt_data, M_UFSMNT); /* XXX */
229 mp->mnt_data = 0;
230 return 0;
231}
232
233int
234nullfs_root(mp, vpp)
235 struct mount *mp;
236 struct vnode **vpp;
237{
238 struct vnode *vp;
239
240#ifdef NULLFS_DIAGNOSTIC
241 printf("nullfs_root(mp = %x, vp = %x->%x)\n", mp,
242 MOUNTTONULLMOUNT(mp)->nullm_rootvp,
243 NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp)
244 );
245#endif
246
247 /*
248 * Return locked reference to root.
249 */
250 vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
251 VREF(vp);
252 VOP_LOCK(vp);
253 *vpp = vp;
254 return 0;
255}
256
257int
258nullfs_quotactl(mp, cmd, uid, arg, p)
259 struct mount *mp;
260 int cmd;
261 uid_t uid;
262 caddr_t arg;
263 struct proc *p;
264{
265 return VFS_QUOTACTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, uid, arg, p);
266}
267
268int
269nullfs_statfs(mp, sbp, p)
270 struct mount *mp;
271 struct statfs *sbp;
272 struct proc *p;
273{
274 int error;
275 struct statfs mstat;
276
277#ifdef NULLFS_DIAGNOSTIC
278 printf("nullfs_statfs(mp = %x, vp = %x->%x)\n", mp,
279 MOUNTTONULLMOUNT(mp)->nullm_rootvp,
280 NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp)
281 );
282#endif
283
284 bzero(&mstat, sizeof(mstat));
285
286 error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat, p);
287 if (error)
288 return (error);
289
290 /* now copy across the "interesting" information and fake the rest */
291 sbp->f_type = mstat.f_type;
292 sbp->f_flags = mstat.f_flags;
293 sbp->f_bsize = mstat.f_bsize;
294 sbp->f_iosize = mstat.f_iosize;
295 sbp->f_blocks = mstat.f_blocks;
296 sbp->f_bfree = mstat.f_bfree;
297 sbp->f_bavail = mstat.f_bavail;
298 sbp->f_files = mstat.f_files;
299 sbp->f_ffree = mstat.f_ffree;
300 if (sbp != &mp->mnt_stat) {
301 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
302 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
303 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
304 }
305 return (0);
306}
307
308int
309nullfs_sync(mp, waitfor, cred, p)
310 struct mount *mp;
311 int waitfor;
312 struct ucred *cred;
313 struct proc *p;
314{
315 /*
316 * XXX - Assumes no data cached at null layer.
317 */
318 return (0);
319}
320
321int
322nullfs_vget(mp, ino, vpp)
323 struct mount *mp;
324 ino_t ino;
325 struct vnode **vpp;
326{
327
328 return VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, vpp);
329}
330
331int
332nullfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
333 struct mount *mp;
334 struct fid *fidp;
335 struct mbuf *nam;
336 struct vnode **vpp;
337 int *exflagsp;
338 struct ucred**credanonp;
339{
340
341 return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, nam, vpp, exflagsp,credanonp);
342}
343
344int
345nullfs_vptofh(vp, fhp)
346 struct vnode *vp;
347 struct fid *fhp;
348{
349 return VFS_VPTOFH(NULLVPTOLOWERVP(vp), fhp);
350}
351
352int nullfs_init __P((void));
353
354struct vfsops null_vfsops = {
355 nullfs_mount,
356 nullfs_start,
357 nullfs_unmount,
358 nullfs_root,
359 nullfs_quotactl,
360 nullfs_statfs,
361 nullfs_sync,
362 nullfs_vget,
363 nullfs_fhtovp,
364 nullfs_vptofh,
365 nullfs_init,
366};
40 */
41
42/*
43 * Null Layer
44 * (See null_vnops.c for a description of what this does.)
45 */
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/time.h>
50#include <sys/types.h>
51#include <sys/vnode.h>
52#include <sys/mount.h>
53#include <sys/namei.h>
54#include <sys/malloc.h>
55#include <miscfs/nullfs/null.h>
56
57/*
58 * Mount null layer
59 */
60int
61nullfs_mount(mp, path, data, ndp, p)
62 struct mount *mp;
63 char *path;
64 caddr_t data;
65 struct nameidata *ndp;
66 struct proc *p;
67{
68 int error = 0;
69 struct null_args args;
70 struct vnode *lowerrootvp, *vp;
71 struct vnode *nullm_rootvp;
72 struct null_mount *xmp;
73 u_int size;
74
75#ifdef NULLFS_DIAGNOSTIC
76 printf("nullfs_mount(mp = %x)\n", mp);
77#endif
78
79 /*
80 * Update is a no-op
81 */
82 if (mp->mnt_flag & MNT_UPDATE) {
83 return (EOPNOTSUPP);
84 /* return VFS_MOUNT(MOUNTTONULLMOUNT(mp)->nullm_vfs, path, data, ndp, p);*/
85 }
86
87 /*
88 * Get argument
89 */
90 if (error = copyin(data, (caddr_t)&args, sizeof(struct null_args)))
91 return (error);
92
93 /*
94 * Find lower node
95 */
96 NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
97 UIO_USERSPACE, args.target, p);
98 if (error = namei(ndp))
99 return (error);
100
101 /*
102 * Sanity check on lower vnode
103 */
104 lowerrootvp = ndp->ni_vp;
105
106 vrele(ndp->ni_dvp);
107 ndp->ni_dvp = NULL;
108
109 xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
110 M_UFSMNT, M_WAITOK); /* XXX */
111
112 /*
113 * Save reference to underlying FS
114 */
115 xmp->nullm_vfs = lowerrootvp->v_mount;
116
117 /*
118 * Save reference. Each mount also holds
119 * a reference on the root vnode.
120 */
121 error = null_node_create(mp, lowerrootvp, &vp);
122 /*
123 * Unlock the node (either the lower or the alias)
124 */
125 VOP_UNLOCK(vp);
126 /*
127 * Make sure the node alias worked
128 */
129 if (error) {
130 vrele(lowerrootvp);
131 free(xmp, M_UFSMNT); /* XXX */
132 return (error);
133 }
134
135 /*
136 * Keep a held reference to the root vnode.
137 * It is vrele'd in nullfs_unmount.
138 */
139 nullm_rootvp = vp;
140 nullm_rootvp->v_flag |= VROOT;
141 xmp->nullm_rootvp = nullm_rootvp;
142 if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
143 mp->mnt_flag |= MNT_LOCAL;
144 mp->mnt_data = (qaddr_t) xmp;
145 getnewfsid(mp, MOUNT_LOFS);
146
147 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
148 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
149 (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
150 &size);
151 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
152#ifdef NULLFS_DIAGNOSTIC
153 printf("nullfs_mount: lower %s, alias at %s\n",
154 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
155#endif
156 return (0);
157}
158
159/*
160 * VFS start. Nothing needed here - the start routine
161 * on the underlying filesystem will have been called
162 * when that filesystem was mounted.
163 */
164int
165nullfs_start(mp, flags, p)
166 struct mount *mp;
167 int flags;
168 struct proc *p;
169{
170 return (0);
171 /* return VFS_START(MOUNTTONULLMOUNT(mp)->nullm_vfs, flags, p); */
172}
173
174/*
175 * Free reference to null layer
176 */
177int
178nullfs_unmount(mp, mntflags, p)
179 struct mount *mp;
180 int mntflags;
181 struct proc *p;
182{
183 struct vnode *nullm_rootvp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
184 int error;
185 int flags = 0;
186 extern int doforce;
187
188#ifdef NULLFS_DIAGNOSTIC
189 printf("nullfs_unmount(mp = %x)\n", mp);
190#endif
191
192 if (mntflags & MNT_FORCE) {
193 /* lofs can never be rootfs so don't check for it */
194 if (!doforce)
195 return (EINVAL);
196 flags |= FORCECLOSE;
197 }
198
199 /*
200 * Clear out buffer cache. I don't think we
201 * ever get anything cached at this level at the
202 * moment, but who knows...
203 */
204#if 0
205 mntflushbuf(mp, 0);
206 if (mntinvalbuf(mp, 1))
207 return (EBUSY);
208#endif
209 if (nullm_rootvp->v_usecount > 1)
210 return (EBUSY);
211 if (error = vflush(mp, nullm_rootvp, flags))
212 return (error);
213
214#ifdef NULLFS_DIAGNOSTIC
215 vprint("alias root of lower", nullm_rootvp);
216#endif
217 /*
218 * Release reference on underlying root vnode
219 */
220 vrele(nullm_rootvp);
221 /*
222 * And blow it away for future re-use
223 */
224 vgone(nullm_rootvp);
225 /*
226 * Finally, throw away the null_mount structure
227 */
228 free(mp->mnt_data, M_UFSMNT); /* XXX */
229 mp->mnt_data = 0;
230 return 0;
231}
232
233int
234nullfs_root(mp, vpp)
235 struct mount *mp;
236 struct vnode **vpp;
237{
238 struct vnode *vp;
239
240#ifdef NULLFS_DIAGNOSTIC
241 printf("nullfs_root(mp = %x, vp = %x->%x)\n", mp,
242 MOUNTTONULLMOUNT(mp)->nullm_rootvp,
243 NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp)
244 );
245#endif
246
247 /*
248 * Return locked reference to root.
249 */
250 vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
251 VREF(vp);
252 VOP_LOCK(vp);
253 *vpp = vp;
254 return 0;
255}
256
257int
258nullfs_quotactl(mp, cmd, uid, arg, p)
259 struct mount *mp;
260 int cmd;
261 uid_t uid;
262 caddr_t arg;
263 struct proc *p;
264{
265 return VFS_QUOTACTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, uid, arg, p);
266}
267
268int
269nullfs_statfs(mp, sbp, p)
270 struct mount *mp;
271 struct statfs *sbp;
272 struct proc *p;
273{
274 int error;
275 struct statfs mstat;
276
277#ifdef NULLFS_DIAGNOSTIC
278 printf("nullfs_statfs(mp = %x, vp = %x->%x)\n", mp,
279 MOUNTTONULLMOUNT(mp)->nullm_rootvp,
280 NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp)
281 );
282#endif
283
284 bzero(&mstat, sizeof(mstat));
285
286 error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat, p);
287 if (error)
288 return (error);
289
290 /* now copy across the "interesting" information and fake the rest */
291 sbp->f_type = mstat.f_type;
292 sbp->f_flags = mstat.f_flags;
293 sbp->f_bsize = mstat.f_bsize;
294 sbp->f_iosize = mstat.f_iosize;
295 sbp->f_blocks = mstat.f_blocks;
296 sbp->f_bfree = mstat.f_bfree;
297 sbp->f_bavail = mstat.f_bavail;
298 sbp->f_files = mstat.f_files;
299 sbp->f_ffree = mstat.f_ffree;
300 if (sbp != &mp->mnt_stat) {
301 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
302 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
303 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
304 }
305 return (0);
306}
307
308int
309nullfs_sync(mp, waitfor, cred, p)
310 struct mount *mp;
311 int waitfor;
312 struct ucred *cred;
313 struct proc *p;
314{
315 /*
316 * XXX - Assumes no data cached at null layer.
317 */
318 return (0);
319}
320
321int
322nullfs_vget(mp, ino, vpp)
323 struct mount *mp;
324 ino_t ino;
325 struct vnode **vpp;
326{
327
328 return VFS_VGET(MOUNTTONULLMOUNT(mp)->nullm_vfs, ino, vpp);
329}
330
331int
332nullfs_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
333 struct mount *mp;
334 struct fid *fidp;
335 struct mbuf *nam;
336 struct vnode **vpp;
337 int *exflagsp;
338 struct ucred**credanonp;
339{
340
341 return VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, nam, vpp, exflagsp,credanonp);
342}
343
344int
345nullfs_vptofh(vp, fhp)
346 struct vnode *vp;
347 struct fid *fhp;
348{
349 return VFS_VPTOFH(NULLVPTOLOWERVP(vp), fhp);
350}
351
352int nullfs_init __P((void));
353
354struct vfsops null_vfsops = {
355 nullfs_mount,
356 nullfs_start,
357 nullfs_unmount,
358 nullfs_root,
359 nullfs_quotactl,
360 nullfs_statfs,
361 nullfs_sync,
362 nullfs_vget,
363 nullfs_fhtovp,
364 nullfs_vptofh,
365 nullfs_init,
366};
367
368VFS_SET(null_vfsops, null, MOUNT_NULL, 0);