xref: /csrg-svn/sys/miscfs/nullfs/null_vnops.c (revision 54766)
154753Sjohnh /*
254753Sjohnh  * Copyright (c) 1992 The Regents of the University of California
354753Sjohnh  * All rights reserved.
454753Sjohnh  *
5*54766Sjohnh  * This code is derived from the null layer of
6*54766Sjohnh  * John Heidemann of the UCLA Ficus project and
7*54766Sjohnh  * the Jan-Simon Pendry's loopback file system.
854753Sjohnh  *
954753Sjohnh  * %sccs.include.redist.c%
1054753Sjohnh  *
11*54766Sjohnh  *	@(#)null_vnops.c	1.3 (Berkeley) 07/07/92
12*54766Sjohnh  *
13*54766Sjohnh  * Ancestors:
1454753Sjohnh  *	@(#)lofs_vnops.c	1.2 (Berkeley) 6/18/92
15*54766Sjohnh  *	$Id: lofs_vnops.c,v 1.11 1992/05/30 10:05:43 jsp Exp jsp $
16*54766Sjohnh  *	...and...
17*54766Sjohnh  *	@(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
1854753Sjohnh  */
1954753Sjohnh 
2054753Sjohnh /*
21*54766Sjohnh  * Null Layer
22*54766Sjohnh  *
23*54766Sjohnh  * The null layer duplicates a portion of the file system
24*54766Sjohnh  * name space under a new name.  In this respect, it is
25*54766Sjohnh  * similar to the loopback file system.  It differs from
26*54766Sjohnh  * the loopback fs in two respects:  it is implemented using
27*54766Sjohnh  * a bypass operation, and it's "null-nodes" stack above
28*54766Sjohnh  * all lower-layer vnodes, not just over directory vnodes.
29*54766Sjohnh  *
30*54766Sjohnh  * The null layer is the minimum file system layer,
31*54766Sjohnh  * simply bypassing all possible operations to the lower layer
32*54766Sjohnh  * for processing there.  All but vop_getattr, _inactive, _reclaim,
33*54766Sjohnh  * and _print are bypassed.
34*54766Sjohnh  *
35*54766Sjohnh  * Vop_getattr is not bypassed so that we can change the fsid being
36*54766Sjohnh  * returned.  Vop_{inactive,reclaim} are bypassed so that
37*54766Sjohnh  * they can handle freeing null-layer specific data.
38*54766Sjohnh  * Vop_print is not bypassed for debugging.
39*54766Sjohnh  *
40*54766Sjohnh  * NEEDSWORK: Describe methods to invoke operations on the lower layer
41*54766Sjohnh  * (bypass vs. VOP).
4254753Sjohnh  */
4354753Sjohnh 
4454753Sjohnh #include <sys/param.h>
4554753Sjohnh #include <sys/systm.h>
4654753Sjohnh #include <sys/proc.h>
4754753Sjohnh #include <sys/time.h>
4854753Sjohnh #include <sys/types.h>
4954753Sjohnh #include <sys/vnode.h>
5054753Sjohnh #include <sys/mount.h>
5154753Sjohnh #include <sys/namei.h>
5254753Sjohnh #include <sys/malloc.h>
5354753Sjohnh #include <sys/buf.h>
5454753Sjohnh #include <lofs/lofs.h>
5554753Sjohnh 
5654753Sjohnh 
57*54766Sjohnh int null_bug_bypass = 0;   /* for debugging: enables bypass printf'ing */
5854753Sjohnh 
5954753Sjohnh /*
60*54766Sjohnh  * This is the 10-Apr-92 bypass routine.
61*54766Sjohnh  *    This version has been optimized for speed, throwing away some
62*54766Sjohnh  * safety checks.  It should still always work, but it's not as
63*54766Sjohnh  * robust to programmer errors.
64*54766Sjohnh  *    Define SAFETY to include some error checking code.
65*54766Sjohnh  *
66*54766Sjohnh  * In general, we map all vnodes going down and unmap them on the way back.
67*54766Sjohnh  * As an exception to this, vnodes can be marked "unmapped" by setting
68*54766Sjohnh  * the Nth bit in operation's vdesc_flags.
69*54766Sjohnh  *
70*54766Sjohnh  * Also, some BSD vnode operations have the side effect of vrele'ing
71*54766Sjohnh  * their arguments.  With stacking, the reference counts are held
72*54766Sjohnh  * by the upper node, not the lower one, so we must handle these
73*54766Sjohnh  * side-effects here.  This is not of concern in Sun-derived systems
74*54766Sjohnh  * since there are no such side-effects.
75*54766Sjohnh  *
76*54766Sjohnh  * This makes the following assumptions:
77*54766Sjohnh  * - only one returned vpp
78*54766Sjohnh  * - no INOUT vpp's (Sun's vop_open has one of these)
79*54766Sjohnh  * - the vnode operation vector of the first vnode should be used
80*54766Sjohnh  *   to determine what implementation of the op should be invoked
81*54766Sjohnh  * - all mapped vnodes are of our vnode-type (NEEDSWORK:
82*54766Sjohnh  *   problems on rmdir'ing mount points and renaming?)
83*54766Sjohnh  */
84*54766Sjohnh int
85*54766Sjohnh null_bypass(ap)
86*54766Sjohnh 	struct nvop_generic_args *ap;
8754753Sjohnh {
88*54766Sjohnh 	register int this_vp_p;
8954753Sjohnh 	int error;
90*54766Sjohnh 	struct vnode *old_vps[VDESC_MAX_VPS];
91*54766Sjohnh 	struct vnode **vps_p[VDESC_MAX_VPS];
92*54766Sjohnh 	struct vnode ***vppp;
93*54766Sjohnh 	struct vnodeop_desc *descp = ap->a_desc;
94*54766Sjohnh 	int maps, reles, i;
9554753Sjohnh 
96*54766Sjohnh 	if (null_bug_bypass)
97*54766Sjohnh 		printf ("null_bypass: %s\n", descp->vdesc_name);
9854753Sjohnh 
99*54766Sjohnh #ifdef SAFETY
10054753Sjohnh 	/*
101*54766Sjohnh 	 * We require at least one vp.
10254753Sjohnh 	 */
103*54766Sjohnh 	if (descp->vdesc_vp_offsets==NULL ||
104*54766Sjohnh 	    descp->vdesc_vp_offsets[0]==VDESC_NO_OFFSET)
105*54766Sjohnh 		panic ("null_bypass: no vp's in map.\n");
10654753Sjohnh #endif
10754753Sjohnh 
10854753Sjohnh 	/*
109*54766Sjohnh 	 * Map the vnodes going in.
110*54766Sjohnh 	 * Later, we'll invoke the operation based on
111*54766Sjohnh 	 * the first mapped vnode's operation vector.
11254753Sjohnh 	 */
113*54766Sjohnh 	maps = descp->vdesc_flags;
114*54766Sjohnh 	reles = descp->vdesc_rele_flags;
115*54766Sjohnh 	for (i=0; i<VDESC_MAX_VPS; maps>>=1, reles>>=1, i++) {
116*54766Sjohnh 		if (descp->vdesc_vp_offsets[i]==VDESC_NO_OFFSET)
117*54766Sjohnh 			break;   /* bail out at end of list */
118*54766Sjohnh 		if (maps & 1)   /* skip vps that aren't to be mapped */
119*54766Sjohnh 			continue;
120*54766Sjohnh 		vps_p[i] = this_vp_p =
121*54766Sjohnh 			VOPARG_OFFSETTO(struct vnode**,descp->vdesc_vp_offsets[i],ap);
122*54766Sjohnh 		old_vps[i] = *this_vp_p;
123*54766Sjohnh 		*(vps_p[i]) = NULLTOLOWERVP(VTONULLNODE(*this_vp_p));
124*54766Sjohnh 		if (reles & 1)
125*54766Sjohnh 			VREF(*this_vp_p);
126*54766Sjohnh 
127*54766Sjohnh 	};
12854753Sjohnh 
12954753Sjohnh 	/*
130*54766Sjohnh 	 * Call the operation on the lower layer
131*54766Sjohnh 	 * with the modified argument structure.
13254753Sjohnh 	 */
133*54766Sjohnh 	error = VCALL(*(vps_p[0]), descp->vdesc_offset, ap);
13454753Sjohnh 
13554753Sjohnh 	/*
136*54766Sjohnh 	 * Maintain the illusion of call-by-value
137*54766Sjohnh 	 * by restoring vnodes in the argument structure
138*54766Sjohnh 	 * to their original value.
13954753Sjohnh 	 */
140*54766Sjohnh 	maps = descp->vdesc_flags;
141*54766Sjohnh 	reles = descp->vdesc_rele_flags;
142*54766Sjohnh 	for (i=0; i<VDESC_MAX_VPS; maps>>=1, i++) {
143*54766Sjohnh 		if (descp->vdesc_vp_offsets[i]==VDESC_NO_OFFSET)
144*54766Sjohnh 			break;   /* bail out at end of list */
145*54766Sjohnh 		if (maps & 1)   /* skip vps that aren't to be mapped */
146*54766Sjohnh 			continue;
147*54766Sjohnh 		*(vps_p[i]) = old_vps[i];
148*54766Sjohnh 		if (reles & 1)
149*54766Sjohnh 			vrele(*(vps_p[i]));
150*54766Sjohnh 	};
151*54766Sjohnh 
15254753Sjohnh 	/*
153*54766Sjohnh 	 * Map the possible out-going vpp.
15454753Sjohnh 	 */
155*54766Sjohnh 	if (descp->vdesc_vpp_offset != VDESC_NO_OFFSET &&
156*54766Sjohnh 	    !(descp->vdesc_flags & VDESC_NOMAP_VPP) &&
157*54766Sjohnh 	    !error) {
158*54766Sjohnh 		vppp=VOPARG_OFFSETTO(struct vnode***,
159*54766Sjohnh 				 descp->vdesc_vpp_offset,ap);
160*54766Sjohnh 		error = make_null_node(old_vps[0]->v_mount, **vppp, *vppp);
161*54766Sjohnh 	};
16254753Sjohnh 
163*54766Sjohnh 	return (error);
16454753Sjohnh }
16554753Sjohnh 
16654753Sjohnh 
16754753Sjohnh /*
168*54766Sjohnh  *  We handle getattr to change the fsid.
16954753Sjohnh  */
170*54766Sjohnh int
171*54766Sjohnh null_getattr(ap)
172*54766Sjohnh 	struct nvop_getattr_args *ap;
17354753Sjohnh {
17454753Sjohnh 	int error;
175*54766Sjohnh 	if (error=null_bypass(ap))
176*54766Sjohnh 		return error;
177*54766Sjohnh 	/* Requires that arguments be restored. */
178*54766Sjohnh 	ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
179*54766Sjohnh 	return 0;
180*54766Sjohnh }
18154753Sjohnh 
18254753Sjohnh 
183*54766Sjohnh #if 0
18454754Sjohnh null_rename (ap)
18554753Sjohnh 	struct vop_rename_args *ap;
18654753Sjohnh {
18754753Sjohnh 	USES_VOP_RENAME;
18854753Sjohnh 	struct vnode *fvp, *tvp;
18954753Sjohnh 	struct vnode *tdvp;
19054753Sjohnh #if 0
19154753Sjohnh 	struct vnode *fsvp, *tsvp;
19254753Sjohnh #endif
19354753Sjohnh 	int error;
19454753Sjohnh 
19554754Sjohnh #ifdef NULLFS_DIAGNOSTIC
19654754Sjohnh 	printf("null_rename(fdvp = %x->%x)\n", ap->a_fdvp, NULLTOLOWERVP(ap->a_fdvp));
19754754Sjohnh 	/*printf("null_rename(tdvp = %x->%x)\n", tndp->ni_dvp, NULLTOLOWERVP(tndp->ni_dvp));*/
19854753Sjohnh #endif
19954753Sjohnh 
20054754Sjohnh #ifdef NULLFS_DIAGNOSTIC
20154754Sjohnh 	printf("null_rename - switch source dvp\n");
20254753Sjohnh #endif
20354753Sjohnh 	/*
20454753Sjohnh 	 * Switch source directory to point to lofsed vnode
20554753Sjohnh 	 */
20654753Sjohnh 	PUSHREF(fdvp, ap->a_fdvp);
20754753Sjohnh 	VREF(ap->a_fdvp);
20854753Sjohnh 
20954754Sjohnh #ifdef NULLFS_DIAGNOSTIC
21054754Sjohnh 	printf("null_rename - switch source vp\n");
21154753Sjohnh #endif
21254753Sjohnh 	/*
21354753Sjohnh 	 * And source object if it is lofsed...
21454753Sjohnh 	 */
21554753Sjohnh 	fvp = ap->a_fvp;
21654754Sjohnh 	if (fvp && fvp->v_op == null_vnodeop_p) {
21754754Sjohnh 		ap->a_fvp = NULLTOLOWERVP(fvp);
21854753Sjohnh 		VREF(ap->a_fvp);
21954753Sjohnh 	} else {
22054753Sjohnh 		fvp = 0;
22154753Sjohnh 	}
22254753Sjohnh 
22354753Sjohnh #if 0
22454754Sjohnh #ifdef NULLFS_DIAGNOSTIC
22554754Sjohnh 	printf("null_rename - switch source start vp\n");
22654753Sjohnh #endif
22754753Sjohnh 	/*
22854753Sjohnh 	 * And source startdir object if it is lofsed...
22954753Sjohnh 	 */
23054753Sjohnh 	fsvp = fndp->ni_startdir;
23154754Sjohnh 	if (fsvp && fsvp->v_op == null_vnodeop_p) {
23254754Sjohnh 		fndp->ni_startdir = NULLTOLOWERVP(fsvp);
23354753Sjohnh 		VREF(fndp->ni_startdir);
23454753Sjohnh 	} else {
23554753Sjohnh 		fsvp = 0;
23654753Sjohnh 	}
23754753Sjohnh #endif
23854753Sjohnh 
23954754Sjohnh #ifdef NULLFS_DIAGNOSTIC
24054754Sjohnh 	printf("null_rename - switch target dvp\n");
24154753Sjohnh #endif
24254753Sjohnh 	/*
24354753Sjohnh  	 * Switch target directory to point to lofsed vnode
24454753Sjohnh 	 */
24554753Sjohnh 	tdvp = ap->a_tdvp;
24654754Sjohnh 	if (tdvp && tdvp->v_op == null_vnodeop_p) {
24754754Sjohnh 		ap->a_tdvp = NULLTOLOWERVP(tdvp);
24854753Sjohnh 		VREF(ap->a_tdvp);
24954753Sjohnh 	} else {
25054753Sjohnh 		tdvp = 0;
25154753Sjohnh 	}
25254753Sjohnh 
25354754Sjohnh #ifdef NULLFS_DIAGNOSTIC
25454754Sjohnh 	printf("null_rename - switch target vp\n");
25554753Sjohnh #endif
25654753Sjohnh 	/*
25754753Sjohnh 	 * And target object if it is lofsed...
25854753Sjohnh 	 */
25954753Sjohnh 	tvp = ap->a_tvp;
26054754Sjohnh 	if (tvp && tvp->v_op == null_vnodeop_p) {
26154754Sjohnh 		ap->a_tvp = NULLTOLOWERVP(tvp);
26254753Sjohnh 		VREF(ap->a_tvp);
26354753Sjohnh 	} else {
26454753Sjohnh 		tvp = 0;
26554753Sjohnh 	}
26654753Sjohnh 
26754753Sjohnh #if 0
26854754Sjohnh #ifdef NULLFS_DIAGNOSTIC
26954754Sjohnh 	printf("null_rename - switch target start vp\n");
27054753Sjohnh #endif
27154753Sjohnh 	/*
27254753Sjohnh 	 * And target startdir object if it is lofsed...
27354753Sjohnh 	 */
27454753Sjohnh 	tsvp = tndp->ni_startdir;
27554754Sjohnh 	if (tsvp && tsvp->v_op == null_vnodeop_p) {
27654754Sjohnh 		tndp->ni_startdir = NULLTOLOWERVP(fsvp);
27754753Sjohnh 		VREF(tndp->ni_startdir);
27854753Sjohnh 	} else {
27954753Sjohnh 		tsvp = 0;
28054753Sjohnh 	}
28154753Sjohnh #endif
28254753Sjohnh 
28354754Sjohnh #ifdef NULLFS_DIAGNOSTIC
28454754Sjohnh 	printf("null_rename - VOP_RENAME(%x, %x, %x, %x)\n",
28554753Sjohnh 		ap->a_fdvp, ap->a_fvp, ap->a_tdvp, ap->a_tvp);
28654753Sjohnh 	vprint("ap->a_fdvp", ap->a_fdvp);
28754753Sjohnh 	vprint("ap->a_fvp", ap->a_fvp);
28854753Sjohnh 	vprint("ap->a_tdvp", ap->a_tdvp);
28954753Sjohnh 	if (ap->a_tvp) vprint("ap->a_tvp", ap->a_tvp);
29054753Sjohnh 	DELAY(16000000);
29154753Sjohnh #endif
29254753Sjohnh 
29354753Sjohnh 	error = VOP_RENAME(ap->a_fdvp, ap->a_fvp, ap->a_fcnp, ap->a_tdvp, ap->a_tvp, ap->a_tcnp);
29454753Sjohnh 
29554753Sjohnh 	/*
29654753Sjohnh 	 * Put everything back...
29754753Sjohnh 	 */
29854753Sjohnh 
29954753Sjohnh #if 0
30054754Sjohnh #ifdef NULLFS_DIAGNOSTIC
30154754Sjohnh 	printf("null_rename - restore target startdir\n");
30254753Sjohnh #endif
30354753Sjohnh 
30454753Sjohnh 	if (tsvp) {
30554753Sjohnh 		if (tndp->ni_startdir)
30654753Sjohnh 			vrele(tndp->ni_startdir);
30754753Sjohnh 		tndp->ni_startdir = tsvp;
30854753Sjohnh 	}
30954753Sjohnh #endif
31054753Sjohnh 
31154754Sjohnh #ifdef NULLFS_DIAGNOSTIC
31254754Sjohnh 	printf("null_rename - restore target vp\n");
31354753Sjohnh #endif
31454753Sjohnh 
31554753Sjohnh 	if (tvp) {
31654753Sjohnh 		ap->a_tvp = tvp;
31754753Sjohnh 		vrele(ap->a_tvp);
31854753Sjohnh 	}
31954753Sjohnh 
32054754Sjohnh #ifdef NULLFS_DIAGNOSTIC
32154754Sjohnh 	printf("null_rename - restore target dvp\n");
32254753Sjohnh #endif
32354753Sjohnh 
32454753Sjohnh 	if (tdvp) {
32554753Sjohnh 		ap->a_tdvp = tdvp;
32654753Sjohnh 		vrele(ap->a_tdvp);
32754753Sjohnh 	}
32854753Sjohnh 
32954753Sjohnh #if 0
33054754Sjohnh #ifdef NULLFS_DIAGNOSTIC
33154754Sjohnh 	printf("null_rename - restore source startdir\n");
33254753Sjohnh #endif
33354753Sjohnh 
33454753Sjohnh 	if (fsvp) {
33554753Sjohnh 		if (fndp->ni_startdir)
33654753Sjohnh 			vrele(fndp->ni_startdir);
33754753Sjohnh 		fndp->ni_startdir = fsvp;
33854753Sjohnh 	}
33954753Sjohnh #endif
34054753Sjohnh 
34154754Sjohnh #ifdef NULLFS_DIAGNOSTIC
34254754Sjohnh 	printf("null_rename - restore source vp\n");
34354753Sjohnh #endif
34454753Sjohnh 
34554753Sjohnh 
34654753Sjohnh 	if (fvp) {
34754753Sjohnh 		ap->a_fvp = fvp;
34854753Sjohnh 		vrele(ap->a_fvp);
34954753Sjohnh 	}
35054753Sjohnh 
35154754Sjohnh #ifdef NULLFS_DIAGNOSTIC
35254754Sjohnh 	printf("null_rename - restore source dvp\n");
35354753Sjohnh #endif
35454753Sjohnh 
35554753Sjohnh 	POP(fdvp, ap->a_fdvp);
35654753Sjohnh 	vrele(ap->a_fdvp);
35754753Sjohnh 
35854753Sjohnh 	return (error);
35954753Sjohnh }
36054753Sjohnh #endif
36154753Sjohnh 
36254753Sjohnh 
363*54766Sjohnh int
36454754Sjohnh null_inactive (ap)
36554753Sjohnh 	struct vop_inactive_args *ap;
36654753Sjohnh {
36754754Sjohnh #ifdef NULLFS_DIAGNOSTIC
368*54766Sjohnh 	printf("null_inactive(ap->a_vp = %x->%x)\n", ap->a_vp, NULLTOLOWERVP(ap->a_vp));
36954753Sjohnh #endif
370*54766Sjohnh 	/*
371*54766Sjohnh 	 * Do nothing (and _don't_ bypass).
372*54766Sjohnh 	 * Wait to vrele lowervp until reclaim,
373*54766Sjohnh 	 * so that until then our null_node is in the
374*54766Sjohnh 	 * cache and reusable.
375*54766Sjohnh 	 *
376*54766Sjohnh 	 * NEEDSWORK: Someday, consider inactive'ing
377*54766Sjohnh 	 * the lowervp and then trying to reactivate it
378*54766Sjohnh 	 * like they do in the name lookup cache code.
379*54766Sjohnh 	 * That's too much work for now.
380*54766Sjohnh 	 */
381*54766Sjohnh 	return 0;
38254753Sjohnh }
38354753Sjohnh 
38454754Sjohnh null_reclaim (ap)
38554753Sjohnh 	struct vop_reclaim_args *ap;
38654753Sjohnh {
38754753Sjohnh 	USES_VOP_RECLAIM;
38854753Sjohnh 	struct vnode *targetvp;
38954754Sjohnh #ifdef NULLFS_DIAGNOSTIC
39054754Sjohnh 	printf("null_reclaim(ap->a_vp = %x->%x)\n", ap->a_vp, NULLTOLOWERVP(ap->a_vp));
39154753Sjohnh #endif
392*54766Sjohnh 	remque(VTONULLNODE(ap->a_vp));   /* NEEDSWORK: What? */
393*54766Sjohnh 	vrele (NULLTOLOWERVP(ap->a_vp));   /* release lower layer */
39454753Sjohnh 	FREE(ap->a_vp->v_data, M_TEMP);
39554753Sjohnh 	ap->a_vp->v_data = 0;
39654753Sjohnh 	return (0);
39754753Sjohnh }
39854753Sjohnh 
39954754Sjohnh null_bmap (ap)
40054753Sjohnh 	struct vop_bmap_args *ap;
40154753Sjohnh {
40254753Sjohnh 	USES_VOP_BMAP;
40354754Sjohnh #ifdef NULLFS_DIAGNOSTIC
40454754Sjohnh 	printf("null_bmap(ap->a_vp = %x->%x)\n", ap->a_vp, NULLTOLOWERVP(ap->a_vp));
40554753Sjohnh #endif
40654753Sjohnh 
40754754Sjohnh 	return VOP_BMAP(NULLTOLOWERVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp);
40854753Sjohnh }
40954753Sjohnh 
41054754Sjohnh null_strategy (ap)
41154753Sjohnh 	struct vop_strategy_args *ap;
41254753Sjohnh {
41354753Sjohnh 	USES_VOP_STRATEGY;
41454753Sjohnh 	int error;
415*54766Sjohnh 	struct vnode *savedvp;
41654753Sjohnh 
41754754Sjohnh #ifdef NULLFS_DIAGNOSTIC
41854754Sjohnh 	printf("null_strategy(vp = %x->%x)\n", ap->a_bp->b_vp, NULLTOLOWERVP(ap->a_bp->b_vp));
41954753Sjohnh #endif
42054753Sjohnh 
421*54766Sjohnh 	savedvp = ap->a_bp->b_vp;
42254753Sjohnh 
42354753Sjohnh 	error = VOP_STRATEGY(ap->a_bp);
42454753Sjohnh 
425*54766Sjohnh 	ap->a_bp->b_vp = savedvp;
42654753Sjohnh 
427*54766Sjohnh 	return error;
42854753Sjohnh }
42954753Sjohnh 
430*54766Sjohnh 
431*54766Sjohnh int
43254754Sjohnh null_print (ap)
43354753Sjohnh 	struct vop_print_args *ap;
43454753Sjohnh {
435*54766Sjohnh 	register struct vnode *vp = ap->a_vp;
436*54766Sjohnh 	printf ("tag VT_NULLFS, vp=%x, lowervp=%x\n", vp, NULLTOLOWERVP(vp));
437*54766Sjohnh 	return 0;
43854753Sjohnh }
43954753Sjohnh 
44054753Sjohnh 
44154753Sjohnh /*
442*54766Sjohnh  * Global vfs data structures
44354753Sjohnh  */
44454753Sjohnh /*
445*54766Sjohnh  * NEEDSWORK: strategy,bmap are hand coded currently.  They should
446*54766Sjohnh  * go away with a merged buffer/block cache.
447*54766Sjohnh  *
44854753Sjohnh  */
449*54766Sjohnh int (**null_vnodeop_p)();
450*54766Sjohnh struct vnodeopv_entry_desc lofs_vnodeop_entries[] = {
451*54766Sjohnh 	{ &vop_default_desc, null_bypass },
45254753Sjohnh 
453*54766Sjohnh 	{ &vop_getattr_desc, null_getattr },
454*54766Sjohnh 	{ &vop_inactive_desc, null_inactive },
455*54766Sjohnh 	{ &vop_reclaim_desc, null_reclaim },
456*54766Sjohnh 	{ &vop_print_desc, null_print },
45754753Sjohnh 
458*54766Sjohnh 	{ &vop_bmap_desc, null_bmap },
459*54766Sjohnh 	{ &vop_strategy_desc, null_strategy },
46054753Sjohnh 
46154753Sjohnh 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
46254753Sjohnh };
46354753Sjohnh struct vnodeopv_desc lofs_vnodeop_opv_desc =
46454754Sjohnh 	{ &null_vnodeop_p, lofs_vnodeop_entries };
465