1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/atomic.h>
28 #include <sys/kmem.h>
29 #include <sys/mutex.h>
30 #include <sys/errno.h>
31 #include <sys/param.h>
32 #include <sys/sysmacros.h>
33 #include <sys/systm.h>
34 #include <sys/cmn_err.h>
35 #include <sys/debug.h>
36
37 #include <sys/fem.h>
38 #include <sys/vfs.h>
39 #include <sys/vnode.h>
40 #include <sys/vfs_opreg.h>
41
42 #define NNODES_DEFAULT 8 /* Default number of nodes in a fem_list */
43 /*
44 * fl_ntob(n) - Fem_list: number of nodes to bytes
45 * Given the number of nodes in a fem_list return the size, in bytes,
46 * of the fem_list structure.
47 */
48 #define fl_ntob(n) (sizeof (struct fem_list) + \
49 ((n) - 1) * sizeof (struct fem_node))
50
51 typedef enum {
52 FEMTYPE_NULL, /* Uninitialized */
53 FEMTYPE_VNODE,
54 FEMTYPE_VFS,
55 FEMTYPE_NTYPES
56 } femtype_t;
57
58 #define FEM_HEAD(_t) femtype[(_t)].head.fn_op.anon
59 #define FEM_GUARD(_t) femtype[(_t)].guard
60
61 static struct fem_type_info {
62 struct fem_node head;
63 struct fem_node guard;
64 femop_t *errf;
65 } femtype[FEMTYPE_NTYPES];
66
67
68 /*
69 * For each type, two tables - the translation offset definition, which
70 * is used by fs_build_vector to layout the operation(s) vector; and the
71 * guard_operation_vector which protects from stack under-run.
72 */
73
74 int fem_err();
75 int fsem_err();
76
77
78 #define _FEMOPDEF(name, member) \
79 { VOPNAME_##name, offsetof(fem_t, femop_##member), NULL, fem_err }
80
81 static fs_operation_trans_def_t fem_opdef[] = {
82 _FEMOPDEF(OPEN, open),
83 _FEMOPDEF(CLOSE, close),
84 _FEMOPDEF(READ, read),
85 _FEMOPDEF(WRITE, write),
86 _FEMOPDEF(IOCTL, ioctl),
87 _FEMOPDEF(SETFL, setfl),
88 _FEMOPDEF(GETATTR, getattr),
89 _FEMOPDEF(SETATTR, setattr),
90 _FEMOPDEF(ACCESS, access),
91 _FEMOPDEF(LOOKUP, lookup),
92 _FEMOPDEF(CREATE, create),
93 _FEMOPDEF(REMOVE, remove),
94 _FEMOPDEF(LINK, link),
95 _FEMOPDEF(RENAME, rename),
96 _FEMOPDEF(MKDIR, mkdir),
97 _FEMOPDEF(RMDIR, rmdir),
98 _FEMOPDEF(READDIR, readdir),
99 _FEMOPDEF(SYMLINK, symlink),
100 _FEMOPDEF(READLINK, readlink),
101 _FEMOPDEF(FSYNC, fsync),
102 _FEMOPDEF(INACTIVE, inactive),
103 _FEMOPDEF(FID, fid),
104 _FEMOPDEF(RWLOCK, rwlock),
105 _FEMOPDEF(RWUNLOCK, rwunlock),
106 _FEMOPDEF(SEEK, seek),
107 _FEMOPDEF(CMP, cmp),
108 _FEMOPDEF(FRLOCK, frlock),
109 _FEMOPDEF(SPACE, space),
110 _FEMOPDEF(REALVP, realvp),
111 _FEMOPDEF(GETPAGE, getpage),
112 _FEMOPDEF(PUTPAGE, putpage),
113 _FEMOPDEF(MAP, map),
114 _FEMOPDEF(ADDMAP, addmap),
115 _FEMOPDEF(DELMAP, delmap),
116 _FEMOPDEF(POLL, poll),
117 _FEMOPDEF(DUMP, dump),
118 _FEMOPDEF(PATHCONF, pathconf),
119 _FEMOPDEF(PAGEIO, pageio),
120 _FEMOPDEF(DUMPCTL, dumpctl),
121 _FEMOPDEF(DISPOSE, dispose),
122 _FEMOPDEF(SETSECATTR, setsecattr),
123 _FEMOPDEF(GETSECATTR, getsecattr),
124 _FEMOPDEF(SHRLOCK, shrlock),
125 _FEMOPDEF(VNEVENT, vnevent),
126 _FEMOPDEF(REQZCBUF, reqzcbuf),
127 _FEMOPDEF(RETZCBUF, retzcbuf),
128 { NULL, 0, NULL, NULL }
129 };
130
131
132 #define _FEMGUARD(name, ignore) \
133 { VOPNAME_##name, (femop_t *)fem_err }
134
135 static struct fs_operation_def fem_guard_ops[] = {
136 _FEMGUARD(OPEN, open),
137 _FEMGUARD(CLOSE, close),
138 _FEMGUARD(READ, read),
139 _FEMGUARD(WRITE, write),
140 _FEMGUARD(IOCTL, ioctl),
141 _FEMGUARD(SETFL, setfl),
142 _FEMGUARD(GETATTR, getattr),
143 _FEMGUARD(SETATTR, setattr),
144 _FEMGUARD(ACCESS, access),
145 _FEMGUARD(LOOKUP, lookup),
146 _FEMGUARD(CREATE, create),
147 _FEMGUARD(REMOVE, remove),
148 _FEMGUARD(LINK, link),
149 _FEMGUARD(RENAME, rename),
150 _FEMGUARD(MKDIR, mkdir),
151 _FEMGUARD(RMDIR, rmdir),
152 _FEMGUARD(READDIR, readdir),
153 _FEMGUARD(SYMLINK, symlink),
154 _FEMGUARD(READLINK, readlink),
155 _FEMGUARD(FSYNC, fsync),
156 _FEMGUARD(INACTIVE, inactive),
157 _FEMGUARD(FID, fid),
158 _FEMGUARD(RWLOCK, rwlock),
159 _FEMGUARD(RWUNLOCK, rwunlock),
160 _FEMGUARD(SEEK, seek),
161 _FEMGUARD(CMP, cmp),
162 _FEMGUARD(FRLOCK, frlock),
163 _FEMGUARD(SPACE, space),
164 _FEMGUARD(REALVP, realvp),
165 _FEMGUARD(GETPAGE, getpage),
166 _FEMGUARD(PUTPAGE, putpage),
167 _FEMGUARD(MAP, map),
168 _FEMGUARD(ADDMAP, addmap),
169 _FEMGUARD(DELMAP, delmap),
170 _FEMGUARD(POLL, poll),
171 _FEMGUARD(DUMP, dump),
172 _FEMGUARD(PATHCONF, pathconf),
173 _FEMGUARD(PAGEIO, pageio),
174 _FEMGUARD(DUMPCTL, dumpctl),
175 _FEMGUARD(DISPOSE, dispose),
176 _FEMGUARD(SETSECATTR, setsecattr),
177 _FEMGUARD(GETSECATTR, getsecattr),
178 _FEMGUARD(SHRLOCK, shrlock),
179 _FEMGUARD(VNEVENT, vnevent),
180 _FEMGUARD(REQZCBUF, reqzcbuf),
181 _FEMGUARD(RETZCBUF, retzcbuf),
182 { NULL, NULL }
183 };
184
185
186 #define _FSEMOPDEF(name, member) \
187 { VFSNAME_##name, offsetof(fsem_t, fsemop_##member), NULL, fsem_err }
188
189 static fs_operation_trans_def_t fsem_opdef[] = {
190 _FSEMOPDEF(MOUNT, mount),
191 _FSEMOPDEF(UNMOUNT, unmount),
192 _FSEMOPDEF(ROOT, root),
193 _FSEMOPDEF(STATVFS, statvfs),
194 _FSEMOPDEF(SYNC, sync),
195 _FSEMOPDEF(VGET, vget),
196 _FSEMOPDEF(MOUNTROOT, mountroot),
197 _FSEMOPDEF(FREEVFS, freevfs),
198 _FSEMOPDEF(VNSTATE, vnstate),
199 { NULL, 0, NULL, NULL }
200 };
201
202 #define _FSEMGUARD(name, ignore) \
203 { VFSNAME_##name, (femop_t *)fsem_err }
204
205 static struct fs_operation_def fsem_guard_ops[] = {
206 _FSEMGUARD(MOUNT, mount),
207 _FSEMGUARD(UNMOUNT, unmount),
208 _FSEMGUARD(ROOT, root),
209 _FSEMGUARD(STATVFS, statvfs),
210 _FSEMGUARD(SYNC, sync),
211 _FSEMGUARD(VGET, vget),
212 _FSEMGUARD(MOUNTROOT, mountroot),
213 _FSEMGUARD(FREEVFS, freevfs),
214 _FSEMGUARD(VNSTATE, vnstate),
215 { NULL, NULL}
216 };
217
218
219 /*
220 * vsop_find, vfsop_find -
221 *
222 * These macros descend the stack until they find either a basic
223 * vnode/vfs operation [ indicated by a null fn_available ] or a
224 * stacked item where this method is non-null [_vsop].
225 *
226 * The DEBUG one is written with a single function which manually applies
227 * the structure offsets. It can have additional debugging support.
228 */
229
230 #ifndef DEBUG
231
232 #define vsop_find(ap, func, funct, arg0, _vop, _vsop) \
233 for (;;) { \
234 if ((ap)->fa_fnode->fn_available == NULL) { \
235 *(func) = (funct (*)())((ap)->fa_fnode->fn_op.vnode->_vop); \
236 *(arg0) = (void *)(ap)->fa_vnode.vp; \
237 break; \
238 } else if ((*(func) = (funct (*)())((ap)->fa_fnode->fn_op.fem->_vsop))\
239 != NULL) { \
240 *(arg0) = (void *) (ap); \
241 break; \
242 } else { \
243 (ap)->fa_fnode--; \
244 } \
245 } \
246
247 #define vfsop_find(ap, func, funct, arg0, _vop, _vsop) \
248 for (;;) { \
249 if ((ap)->fa_fnode->fn_available == NULL) { \
250 *(func) = (funct (*)())((ap)->fa_fnode->fn_op.vfs->_vop); \
251 *(arg0) = (void *)(ap)->fa_vnode.vp; \
252 break; \
253 } else if ((*(func) = (funct (*)())((ap)->fa_fnode->fn_op.fsem->_vsop))\
254 != NULL) { \
255 *(arg0) = (void *) (ap); \
256 break; \
257 } else { \
258 (ap)->fa_fnode--; \
259 } \
260 } \
261
262 #else
263
264 #define vsop_find(ap, func, funct, arg0, _vop, _vsop) \
265 *(arg0) = _op_find((ap), (void **)(func), \
266 offsetof(vnodeops_t, _vop), offsetof(fem_t, _vsop))
267
268 #define vfsop_find(ap, func, funct, arg0, _fop, _fsop) \
269 *(arg0) = _op_find((ap), (void **)(func), \
270 offsetof(vfsops_t, _fop), offsetof(fsem_t, _fsop))
271
272 static void *
_op_find(femarg_t * ap,void ** fp,int offs0,int offs1)273 _op_find(femarg_t *ap, void **fp, int offs0, int offs1)
274 {
275 void *ptr;
276 for (;;) {
277 struct fem_node *fnod = ap->fa_fnode;
278 if (fnod->fn_available == NULL) {
279 *fp = *(void **)((char *)fnod->fn_op.anon + offs0);
280 ptr = (void *)(ap->fa_vnode.anon);
281 break;
282 } else if ((*fp = *(void **)((char *)fnod->fn_op.anon+offs1))
283 != NULL) {
284 ptr = (void *)(ap);
285 break;
286 } else {
287 ap->fa_fnode--;
288 }
289 }
290 return (ptr);
291 }
292 #endif
293
294 static fem_t *
fem_alloc()295 fem_alloc()
296 {
297 fem_t *p;
298
299 p = (fem_t *)kmem_alloc(sizeof (*p), KM_SLEEP);
300 return (p);
301 }
302
303 void
fem_free(fem_t * p)304 fem_free(fem_t *p)
305 {
306 kmem_free(p, sizeof (*p));
307 }
308
309 static fsem_t *
fsem_alloc()310 fsem_alloc()
311 {
312 fsem_t *p;
313
314 p = (fsem_t *)kmem_alloc(sizeof (*p), KM_SLEEP);
315 return (p);
316 }
317
318 void
fsem_free(fsem_t * p)319 fsem_free(fsem_t *p)
320 {
321 kmem_free(p, sizeof (*p));
322 }
323
324
325 /*
326 * fem_get, fem_release - manage reference counts on the stack.
327 *
328 * The list of monitors can be updated while operations are in
329 * progress on the object.
330 *
331 * The reference count facilitates this by counting the number of
332 * current accessors, and deconstructing the list when it is exhausted.
333 *
334 * fem_lock() is required to:
335 * look at femh_list
336 * update what femh_list points to
337 * update femh_list
338 * increase femh_list->feml_refc.
339 *
340 * the feml_refc can decrement without holding the lock;
341 * when feml_refc becomes zero, the list is destroyed.
342 *
343 */
344
345 static struct fem_list *
fem_lock(struct fem_head * fp)346 fem_lock(struct fem_head *fp)
347 {
348 struct fem_list *sp = NULL;
349
350 ASSERT(fp != NULL);
351 mutex_enter(&fp->femh_lock);
352 sp = fp->femh_list;
353 return (sp);
354 }
355
356 static void
fem_unlock(struct fem_head * fp)357 fem_unlock(struct fem_head *fp)
358 {
359 ASSERT(fp != NULL);
360 mutex_exit(&fp->femh_lock);
361 }
362
363 /*
364 * Addref can only be called while its head->lock is held.
365 */
366
367 static void
fem_addref(struct fem_list * sp)368 fem_addref(struct fem_list *sp)
369 {
370 atomic_inc_32(&sp->feml_refc);
371 }
372
373 static uint32_t
fem_delref(struct fem_list * sp)374 fem_delref(struct fem_list *sp)
375 {
376 return (atomic_dec_32_nv(&sp->feml_refc));
377 }
378
379 static struct fem_list *
fem_get(struct fem_head * fp)380 fem_get(struct fem_head *fp)
381 {
382 struct fem_list *sp = NULL;
383
384 if (fp != NULL) {
385 if ((sp = fem_lock(fp)) != NULL) {
386 fem_addref(sp);
387 }
388 fem_unlock(fp);
389 }
390 return (sp);
391 }
392
393 static void
fem_release(struct fem_list * sp)394 fem_release(struct fem_list *sp)
395 {
396 int i;
397
398 ASSERT(sp->feml_refc != 0);
399 if (fem_delref(sp) == 0) {
400 /*
401 * Before freeing the list, we need to release the
402 * caller-provided data.
403 */
404 for (i = sp->feml_tos; i > 0; i--) {
405 struct fem_node *fnp = &sp->feml_nodes[i];
406
407 if (fnp->fn_av_rele)
408 (*(fnp->fn_av_rele))(fnp->fn_available);
409 }
410 kmem_free(sp, fl_ntob(sp->feml_ssize));
411 }
412 }
413
414
415 /*
416 * These are the 'head' operations which perform the interposition.
417 *
418 * This set must be 1:1, onto with the (vnodeops, vfsos).
419 *
420 * If there is a desire to globally disable interposition for a particular
421 * method, the corresponding 'head' routine should unearth the base method
422 * and invoke it directly rather than bypassing the function.
423 *
424 * All the functions are virtually the same, save for names, types & args.
425 * 1. get a reference to the monitor stack for this object.
426 * 2. store the top of stack into the femarg structure.
427 * 3. store the basic object (vnode *, vnode **, vfs *) in the femarg struc.
428 * 4. invoke the "top" method for this object.
429 * 5. release the reference to the monitor stack.
430 *
431 */
432
433 static int
vhead_open(vnode_t ** vpp,int mode,cred_t * cr,caller_context_t * ct)434 vhead_open(vnode_t **vpp, int mode, cred_t *cr, caller_context_t *ct)
435 {
436 femarg_t farg;
437 struct fem_list *femsp;
438 int (*func)();
439 void *arg0;
440 int errc;
441
442 if ((femsp = fem_lock((*vpp)->v_femhead)) == NULL) {
443 func = (int (*)()) ((*vpp)->v_op->vop_open);
444 arg0 = (void *)vpp;
445 fem_unlock((*vpp)->v_femhead);
446 errc = (*func)(arg0, mode, cr, ct);
447 } else {
448 fem_addref(femsp);
449 fem_unlock((*vpp)->v_femhead);
450 farg.fa_vnode.vpp = vpp;
451 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
452 vsop_find(&farg, &func, int, &arg0, vop_open, femop_open);
453 errc = (*func)(arg0, mode, cr, ct);
454 fem_release(femsp);
455 }
456 return (errc);
457 }
458
459 static int
vhead_close(vnode_t * vp,int flag,int count,offset_t offset,cred_t * cr,caller_context_t * ct)460 vhead_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
461 caller_context_t *ct)
462 {
463 femarg_t farg;
464 struct fem_list *femsp;
465 int (*func)();
466 void *arg0;
467 int errc;
468
469 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
470 func = (int (*)()) (vp->v_op->vop_close);
471 arg0 = vp;
472 fem_unlock(vp->v_femhead);
473 errc = (*func)(arg0, flag, count, offset, cr, ct);
474 } else {
475 fem_addref(femsp);
476 fem_unlock(vp->v_femhead);
477 farg.fa_vnode.vp = vp;
478 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
479 vsop_find(&farg, &func, int, &arg0, vop_close, femop_close);
480 errc = (*func)(arg0, flag, count, offset, cr, ct);
481 fem_release(femsp);
482 }
483 return (errc);
484 }
485
486 static int
vhead_read(vnode_t * vp,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)487 vhead_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
488 caller_context_t *ct)
489 {
490 femarg_t farg;
491 struct fem_list *femsp;
492 int (*func)();
493 void *arg0;
494 int errc;
495
496 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
497 func = (int (*)()) (vp->v_op->vop_read);
498 arg0 = vp;
499 fem_unlock(vp->v_femhead);
500 errc = (*func)(arg0, uiop, ioflag, cr, ct);
501 } else {
502 fem_addref(femsp);
503 fem_unlock(vp->v_femhead);
504 farg.fa_vnode.vp = vp;
505 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
506 vsop_find(&farg, &func, int, &arg0, vop_read, femop_read);
507 errc = (*func)(arg0, uiop, ioflag, cr, ct);
508 fem_release(femsp);
509 }
510 return (errc);
511 }
512
513 static int
vhead_write(vnode_t * vp,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)514 vhead_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
515 caller_context_t *ct)
516 {
517 femarg_t farg;
518 struct fem_list *femsp;
519 int (*func)();
520 void *arg0;
521 int errc;
522
523 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
524 func = (int (*)()) (vp->v_op->vop_write);
525 arg0 = vp;
526 fem_unlock(vp->v_femhead);
527 errc = (*func)(arg0, uiop, ioflag, cr, ct);
528 } else {
529 fem_addref(femsp);
530 fem_unlock(vp->v_femhead);
531 farg.fa_vnode.vp = vp;
532 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
533 vsop_find(&farg, &func, int, &arg0, vop_write, femop_write);
534 errc = (*func)(arg0, uiop, ioflag, cr, ct);
535 fem_release(femsp);
536 }
537 return (errc);
538 }
539
540 static int
vhead_ioctl(vnode_t * vp,int cmd,intptr_t arg,int flag,cred_t * cr,int * rvalp,caller_context_t * ct)541 vhead_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr,
542 int *rvalp, caller_context_t *ct)
543 {
544 femarg_t farg;
545 struct fem_list *femsp;
546 int (*func)();
547 void *arg0;
548 int errc;
549
550 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
551 func = (int (*)()) (vp->v_op->vop_ioctl);
552 arg0 = vp;
553 fem_unlock(vp->v_femhead);
554 errc = (*func)(arg0, cmd, arg, flag, cr, rvalp, ct);
555 } else {
556 fem_addref(femsp);
557 fem_unlock(vp->v_femhead);
558 farg.fa_vnode.vp = vp;
559 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
560 vsop_find(&farg, &func, int, &arg0, vop_ioctl, femop_ioctl);
561 errc = (*func)(arg0, cmd, arg, flag, cr, rvalp, ct);
562 fem_release(femsp);
563 }
564 return (errc);
565 }
566
567 static int
vhead_setfl(vnode_t * vp,int oflags,int nflags,cred_t * cr,caller_context_t * ct)568 vhead_setfl(vnode_t *vp, int oflags, int nflags, cred_t *cr,
569 caller_context_t *ct)
570 {
571 femarg_t farg;
572 struct fem_list *femsp;
573 int (*func)();
574 void *arg0;
575 int errc;
576
577 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
578 func = (int (*)()) (vp->v_op->vop_setfl);
579 arg0 = vp;
580 fem_unlock(vp->v_femhead);
581 errc = (*func)(arg0, oflags, nflags, cr, ct);
582 } else {
583 fem_addref(femsp);
584 fem_unlock(vp->v_femhead);
585 farg.fa_vnode.vp = vp;
586 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
587 vsop_find(&farg, &func, int, &arg0, vop_setfl, femop_setfl);
588 errc = (*func)(arg0, oflags, nflags, cr, ct);
589 fem_release(femsp);
590 }
591 return (errc);
592 }
593
594 static int
vhead_getattr(vnode_t * vp,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)595 vhead_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
596 caller_context_t *ct)
597 {
598 femarg_t farg;
599 struct fem_list *femsp;
600 int (*func)();
601 void *arg0;
602 int errc;
603
604 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
605 func = (int (*)()) (vp->v_op->vop_getattr);
606 arg0 = vp;
607 fem_unlock(vp->v_femhead);
608 errc = (*func)(arg0, vap, flags, cr, ct);
609 } else {
610 fem_addref(femsp);
611 fem_unlock(vp->v_femhead);
612 farg.fa_vnode.vp = vp;
613 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
614 vsop_find(&farg, &func, int, &arg0, vop_getattr,
615 femop_getattr);
616 errc = (*func)(arg0, vap, flags, cr, ct);
617 fem_release(femsp);
618 }
619 return (errc);
620 }
621
622 static int
vhead_setattr(vnode_t * vp,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)623 vhead_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
624 caller_context_t *ct)
625 {
626 femarg_t farg;
627 struct fem_list *femsp;
628 int (*func)();
629 void *arg0;
630 int errc;
631
632 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
633 func = (int (*)()) (vp->v_op->vop_setattr);
634 arg0 = vp;
635 fem_unlock(vp->v_femhead);
636 errc = (*func)(arg0, vap, flags, cr, ct);
637 } else {
638 fem_addref(femsp);
639 fem_unlock(vp->v_femhead);
640 farg.fa_vnode.vp = vp;
641 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
642 vsop_find(&farg, &func, int, &arg0, vop_setattr,
643 femop_setattr);
644 errc = (*func)(arg0, vap, flags, cr, ct);
645 fem_release(femsp);
646 }
647 return (errc);
648 }
649
650 static int
vhead_access(vnode_t * vp,int mode,int flags,cred_t * cr,caller_context_t * ct)651 vhead_access(vnode_t *vp, int mode, int flags, cred_t *cr,
652 caller_context_t *ct)
653 {
654 femarg_t farg;
655 struct fem_list *femsp;
656 int (*func)();
657 void *arg0;
658 int errc;
659
660 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
661 func = (int (*)()) (vp->v_op->vop_access);
662 arg0 = vp;
663 fem_unlock(vp->v_femhead);
664 errc = (*func)(arg0, mode, flags, cr, ct);
665 } else {
666 fem_addref(femsp);
667 fem_unlock(vp->v_femhead);
668 farg.fa_vnode.vp = vp;
669 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
670 vsop_find(&farg, &func, int, &arg0, vop_access,
671 femop_access);
672 errc = (*func)(arg0, mode, flags, cr, ct);
673 fem_release(femsp);
674 }
675 return (errc);
676 }
677
678 static int
vhead_lookup(vnode_t * dvp,char * nm,vnode_t ** vpp,pathname_t * pnp,int flags,vnode_t * rdir,cred_t * cr,caller_context_t * ct,int * direntflags,pathname_t * realpnp)679 vhead_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp,
680 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
681 int *direntflags, pathname_t *realpnp)
682 {
683 femarg_t farg;
684 struct fem_list *femsp;
685 int (*func)();
686 void *arg0;
687 int errc;
688
689 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
690 func = (int (*)()) (dvp->v_op->vop_lookup);
691 arg0 = dvp;
692 fem_unlock(dvp->v_femhead);
693 errc = (*func)(arg0, nm, vpp, pnp, flags, rdir, cr, ct,
694 direntflags, realpnp);
695 } else {
696 fem_addref(femsp);
697 fem_unlock(dvp->v_femhead);
698 farg.fa_vnode.vp = dvp;
699 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
700 vsop_find(&farg, &func, int, &arg0, vop_lookup,
701 femop_lookup);
702 errc = (*func)(arg0, nm, vpp, pnp, flags, rdir, cr, ct,
703 direntflags, realpnp);
704 fem_release(femsp);
705 }
706 return (errc);
707 }
708
709 static int
vhead_create(vnode_t * dvp,char * name,vattr_t * vap,vcexcl_t excl,int mode,vnode_t ** vpp,cred_t * cr,int flag,caller_context_t * ct,vsecattr_t * vsecp)710 vhead_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl,
711 int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
712 vsecattr_t *vsecp)
713 {
714 femarg_t farg;
715 struct fem_list *femsp;
716 int (*func)();
717 void *arg0;
718 int errc;
719
720 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
721 func = (int (*)()) (dvp->v_op->vop_create);
722 arg0 = dvp;
723 fem_unlock(dvp->v_femhead);
724 errc = (*func)(arg0, name, vap, excl, mode, vpp, cr, flag,
725 ct, vsecp);
726 } else {
727 fem_addref(femsp);
728 fem_unlock(dvp->v_femhead);
729 farg.fa_vnode.vp = dvp;
730 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
731 vsop_find(&farg, &func, int, &arg0, vop_create,
732 femop_create);
733 errc = (*func)(arg0, name, vap, excl, mode, vpp, cr, flag,
734 ct, vsecp);
735 fem_release(femsp);
736 }
737 return (errc);
738 }
739
740 static int
vhead_remove(vnode_t * dvp,char * nm,cred_t * cr,caller_context_t * ct,int flags)741 vhead_remove(vnode_t *dvp, char *nm, cred_t *cr, caller_context_t *ct,
742 int flags)
743 {
744 femarg_t farg;
745 struct fem_list *femsp;
746 int (*func)();
747 void *arg0;
748 int errc;
749
750 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
751 func = (int (*)()) (dvp->v_op->vop_remove);
752 arg0 = dvp;
753 fem_unlock(dvp->v_femhead);
754 errc = (*func)(arg0, nm, cr, ct, flags);
755 } else {
756 fem_addref(femsp);
757 fem_unlock(dvp->v_femhead);
758 farg.fa_vnode.vp = dvp;
759 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
760 vsop_find(&farg, &func, int, &arg0, vop_remove,
761 femop_remove);
762 errc = (*func)(arg0, nm, cr, ct, flags);
763 fem_release(femsp);
764 }
765 return (errc);
766 }
767
768 static int
vhead_link(vnode_t * tdvp,vnode_t * svp,char * tnm,cred_t * cr,caller_context_t * ct,int flags)769 vhead_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr,
770 caller_context_t *ct, int flags)
771 {
772 femarg_t farg;
773 struct fem_list *femsp;
774 int (*func)();
775 void *arg0;
776 int errc;
777
778 if ((femsp = fem_lock(tdvp->v_femhead)) == NULL) {
779 func = (int (*)()) (tdvp->v_op->vop_link);
780 arg0 = tdvp;
781 fem_unlock(tdvp->v_femhead);
782 errc = (*func)(arg0, svp, tnm, cr, ct, flags);
783 } else {
784 fem_addref(femsp);
785 fem_unlock(tdvp->v_femhead);
786 farg.fa_vnode.vp = tdvp;
787 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
788 vsop_find(&farg, &func, int, &arg0, vop_link, femop_link);
789 errc = (*func)(arg0, svp, tnm, cr, ct, flags);
790 fem_release(femsp);
791 }
792 return (errc);
793 }
794
795 static int
vhead_rename(vnode_t * sdvp,char * snm,vnode_t * tdvp,char * tnm,cred_t * cr,caller_context_t * ct,int flags)796 vhead_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
797 cred_t *cr, caller_context_t *ct, int flags)
798 {
799 femarg_t farg;
800 struct fem_list *femsp;
801 int (*func)();
802 void *arg0;
803 int errc;
804
805 if ((femsp = fem_lock(sdvp->v_femhead)) == NULL) {
806 func = (int (*)()) (sdvp->v_op->vop_rename);
807 arg0 = sdvp;
808 fem_unlock(sdvp->v_femhead);
809 errc = (*func)(arg0, snm, tdvp, tnm, cr, ct, flags);
810 } else {
811 fem_addref(femsp);
812 fem_unlock(sdvp->v_femhead);
813 farg.fa_vnode.vp = sdvp;
814 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
815 vsop_find(&farg, &func, int, &arg0, vop_rename,
816 femop_rename);
817 errc = (*func)(arg0, snm, tdvp, tnm, cr, ct, flags);
818 fem_release(femsp);
819 }
820 return (errc);
821 }
822
823 static int
vhead_mkdir(vnode_t * dvp,char * dirname,vattr_t * vap,vnode_t ** vpp,cred_t * cr,caller_context_t * ct,int flags,vsecattr_t * vsecp)824 vhead_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp,
825 cred_t *cr, caller_context_t *ct, int flags, vsecattr_t *vsecp)
826 {
827 femarg_t farg;
828 struct fem_list *femsp;
829 int (*func)();
830 void *arg0;
831 int errc;
832
833 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
834 func = (int (*)()) (dvp->v_op->vop_mkdir);
835 arg0 = dvp;
836 fem_unlock(dvp->v_femhead);
837 errc = (*func)(arg0, dirname, vap, vpp, cr, ct, flags, vsecp);
838 } else {
839 fem_addref(femsp);
840 fem_unlock(dvp->v_femhead);
841 farg.fa_vnode.vp = dvp;
842 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
843 vsop_find(&farg, &func, int, &arg0, vop_mkdir, femop_mkdir);
844 errc = (*func)(arg0, dirname, vap, vpp, cr, ct, flags, vsecp);
845 fem_release(femsp);
846 }
847 return (errc);
848 }
849
850 static int
vhead_rmdir(vnode_t * dvp,char * nm,vnode_t * cdir,cred_t * cr,caller_context_t * ct,int flags)851 vhead_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr,
852 caller_context_t *ct, int flags)
853 {
854 femarg_t farg;
855 struct fem_list *femsp;
856 int (*func)();
857 void *arg0;
858 int errc;
859
860 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
861 func = (int (*)()) (dvp->v_op->vop_rmdir);
862 arg0 = dvp;
863 fem_unlock(dvp->v_femhead);
864 errc = (*func)(arg0, nm, cdir, cr, ct, flags);
865 } else {
866 fem_addref(femsp);
867 fem_unlock(dvp->v_femhead);
868 farg.fa_vnode.vp = dvp;
869 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
870 vsop_find(&farg, &func, int, &arg0, vop_rmdir, femop_rmdir);
871 errc = (*func)(arg0, nm, cdir, cr, ct, flags);
872 fem_release(femsp);
873 }
874 return (errc);
875 }
876
877 static int
vhead_readdir(vnode_t * vp,uio_t * uiop,cred_t * cr,int * eofp,caller_context_t * ct,int flags)878 vhead_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp,
879 caller_context_t *ct, int flags)
880 {
881 femarg_t farg;
882 struct fem_list *femsp;
883 int (*func)();
884 void *arg0;
885 int errc;
886
887 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
888 func = (int (*)()) (vp->v_op->vop_readdir);
889 arg0 = vp;
890 fem_unlock(vp->v_femhead);
891 errc = (*func)(arg0, uiop, cr, eofp, ct, flags);
892 } else {
893 fem_addref(femsp);
894 fem_unlock(vp->v_femhead);
895 farg.fa_vnode.vp = vp;
896 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
897 vsop_find(&farg, &func, int, &arg0, vop_readdir,
898 femop_readdir);
899 errc = (*func)(arg0, uiop, cr, eofp, ct, flags);
900 fem_release(femsp);
901 }
902 return (errc);
903 }
904
905 static int
vhead_symlink(vnode_t * dvp,char * linkname,vattr_t * vap,char * target,cred_t * cr,caller_context_t * ct,int flags)906 vhead_symlink(vnode_t *dvp, char *linkname, vattr_t *vap, char *target,
907 cred_t *cr, caller_context_t *ct, int flags)
908 {
909 femarg_t farg;
910 struct fem_list *femsp;
911 int (*func)();
912 void *arg0;
913 int errc;
914
915 if ((femsp = fem_lock(dvp->v_femhead)) == NULL) {
916 func = (int (*)()) (dvp->v_op->vop_symlink);
917 arg0 = dvp;
918 fem_unlock(dvp->v_femhead);
919 errc = (*func)(arg0, linkname, vap, target, cr, ct, flags);
920 } else {
921 fem_addref(femsp);
922 fem_unlock(dvp->v_femhead);
923 farg.fa_vnode.vp = dvp;
924 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
925 vsop_find(&farg, &func, int, &arg0, vop_symlink,
926 femop_symlink);
927 errc = (*func)(arg0, linkname, vap, target, cr, ct, flags);
928 fem_release(femsp);
929 }
930 return (errc);
931 }
932
933 static int
vhead_readlink(vnode_t * vp,uio_t * uiop,cred_t * cr,caller_context_t * ct)934 vhead_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
935 {
936 femarg_t farg;
937 struct fem_list *femsp;
938 int (*func)();
939 void *arg0;
940 int errc;
941
942 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
943 func = (int (*)()) (vp->v_op->vop_readlink);
944 arg0 = vp;
945 fem_unlock(vp->v_femhead);
946 errc = (*func)(arg0, uiop, cr, ct);
947 } else {
948 fem_addref(femsp);
949 fem_unlock(vp->v_femhead);
950 farg.fa_vnode.vp = vp;
951 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
952 vsop_find(&farg, &func, int, &arg0, vop_readlink,
953 femop_readlink);
954 errc = (*func)(arg0, uiop, cr, ct);
955 fem_release(femsp);
956 }
957 return (errc);
958 }
959
960 static int
vhead_fsync(vnode_t * vp,int syncflag,cred_t * cr,caller_context_t * ct)961 vhead_fsync(vnode_t *vp, int syncflag, cred_t *cr, caller_context_t *ct)
962 {
963 femarg_t farg;
964 struct fem_list *femsp;
965 int (*func)();
966 void *arg0;
967 int errc;
968
969 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
970 func = (int (*)()) (vp->v_op->vop_fsync);
971 arg0 = vp;
972 fem_unlock(vp->v_femhead);
973 errc = (*func)(arg0, syncflag, cr, ct);
974 } else {
975 fem_addref(femsp);
976 fem_unlock(vp->v_femhead);
977 farg.fa_vnode.vp = vp;
978 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
979 vsop_find(&farg, &func, int, &arg0, vop_fsync, femop_fsync);
980 errc = (*func)(arg0, syncflag, cr, ct);
981 fem_release(femsp);
982 }
983 return (errc);
984 }
985
986 static int
vhead_inactive(vnode_t * vp,cred_t * cr,caller_context_t * ct)987 vhead_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct)
988 {
989 femarg_t farg;
990 struct fem_list *femsp;
991 void (*func)();
992 void *arg0;
993
994 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
995 func = (void (*)()) (vp->v_op->vop_inactive);
996 arg0 = vp;
997 fem_unlock(vp->v_femhead);
998 (*func)(arg0, cr, ct);
999 } else {
1000 fem_addref(femsp);
1001 fem_unlock(vp->v_femhead);
1002 farg.fa_vnode.vp = vp;
1003 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1004 vsop_find(&farg, &func, void, &arg0, vop_inactive,
1005 femop_inactive);
1006 (*func)(arg0, cr, ct);
1007 fem_release(femsp);
1008 }
1009 return (0);
1010 }
1011
1012 static int
vhead_fid(vnode_t * vp,fid_t * fidp,caller_context_t * ct)1013 vhead_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
1014 {
1015 femarg_t farg;
1016 struct fem_list *femsp;
1017 int (*func)();
1018 void *arg0;
1019 int errc;
1020
1021 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1022 func = (int (*)()) (vp->v_op->vop_fid);
1023 arg0 = vp;
1024 fem_unlock(vp->v_femhead);
1025 errc = (*func)(arg0, fidp, ct);
1026 } else {
1027 fem_addref(femsp);
1028 fem_unlock(vp->v_femhead);
1029 farg.fa_vnode.vp = vp;
1030 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1031 vsop_find(&farg, &func, int, &arg0, vop_fid, femop_fid);
1032 errc = (*func)(arg0, fidp, ct);
1033 fem_release(femsp);
1034 }
1035 return (errc);
1036 }
1037
1038 static int
vhead_rwlock(vnode_t * vp,int write_lock,caller_context_t * ct)1039 vhead_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct)
1040 {
1041 femarg_t farg;
1042 struct fem_list *femsp;
1043 int (*func)();
1044 void *arg0;
1045 int errc;
1046
1047 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1048 func = (int (*)()) (vp->v_op->vop_rwlock);
1049 arg0 = vp;
1050 fem_unlock(vp->v_femhead);
1051 errc = (*func)(arg0, write_lock, ct);
1052 } else {
1053 fem_addref(femsp);
1054 fem_unlock(vp->v_femhead);
1055 farg.fa_vnode.vp = vp;
1056 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1057 vsop_find(&farg, &func, int, &arg0, vop_rwlock,
1058 femop_rwlock);
1059 errc = (*func)(arg0, write_lock, ct);
1060 fem_release(femsp);
1061 }
1062 return (errc);
1063 }
1064
1065 static int
vhead_rwunlock(vnode_t * vp,int write_lock,caller_context_t * ct)1066 vhead_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct)
1067 {
1068 femarg_t farg;
1069 struct fem_list *femsp;
1070 void (*func)();
1071 void *arg0;
1072
1073 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1074 func = (void (*)()) (vp->v_op->vop_rwunlock);
1075 arg0 = vp;
1076 fem_unlock(vp->v_femhead);
1077 (*func)(arg0, write_lock, ct);
1078 } else {
1079 fem_addref(femsp);
1080 fem_unlock(vp->v_femhead);
1081 farg.fa_vnode.vp = vp;
1082 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1083 vsop_find(&farg, &func, void, &arg0, vop_rwunlock,
1084 femop_rwunlock);
1085 (*func)(arg0, write_lock, ct);
1086 fem_release(femsp);
1087 }
1088 return (0);
1089 }
1090
1091 static int
vhead_seek(vnode_t * vp,offset_t ooff,offset_t * noffp,caller_context_t * ct)1092 vhead_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, caller_context_t *ct)
1093 {
1094 femarg_t farg;
1095 struct fem_list *femsp;
1096 int (*func)();
1097 void *arg0;
1098 int errc;
1099
1100 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1101 func = (int (*)()) (vp->v_op->vop_seek);
1102 arg0 = vp;
1103 fem_unlock(vp->v_femhead);
1104 errc = (*func)(arg0, ooff, noffp, ct);
1105 } else {
1106 fem_addref(femsp);
1107 fem_unlock(vp->v_femhead);
1108 farg.fa_vnode.vp = vp;
1109 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1110 vsop_find(&farg, &func, int, &arg0, vop_seek, femop_seek);
1111 errc = (*func)(arg0, ooff, noffp, ct);
1112 fem_release(femsp);
1113 }
1114 return (errc);
1115 }
1116
1117 static int
vhead_cmp(vnode_t * vp1,vnode_t * vp2,caller_context_t * ct)1118 vhead_cmp(vnode_t *vp1, vnode_t *vp2, caller_context_t *ct)
1119 {
1120 femarg_t farg;
1121 struct fem_list *femsp;
1122 int (*func)();
1123 void *arg0;
1124 int errc;
1125
1126 if ((femsp = fem_lock(vp1->v_femhead)) == NULL) {
1127 func = (int (*)()) (vp1->v_op->vop_cmp);
1128 arg0 = vp1;
1129 fem_unlock(vp1->v_femhead);
1130 errc = (*func)(arg0, vp2, ct);
1131 } else {
1132 fem_addref(femsp);
1133 fem_unlock(vp1->v_femhead);
1134 farg.fa_vnode.vp = vp1;
1135 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1136 vsop_find(&farg, &func, int, &arg0, vop_cmp, femop_cmp);
1137 errc = (*func)(arg0, vp2, ct);
1138 fem_release(femsp);
1139 }
1140 return (errc);
1141 }
1142
1143 static int
vhead_frlock(vnode_t * vp,int cmd,struct flock64 * bfp,int flag,offset_t offset,struct flk_callback * flk_cbp,cred_t * cr,caller_context_t * ct)1144 vhead_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
1145 offset_t offset, struct flk_callback *flk_cbp, cred_t *cr,
1146 caller_context_t *ct)
1147 {
1148 femarg_t farg;
1149 struct fem_list *femsp;
1150 int (*func)();
1151 void *arg0;
1152 int errc;
1153
1154 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1155 func = (int (*)()) (vp->v_op->vop_frlock);
1156 arg0 = vp;
1157 fem_unlock(vp->v_femhead);
1158 errc = (*func)(arg0, cmd, bfp, flag, offset, flk_cbp, cr, ct);
1159 } else {
1160 fem_addref(femsp);
1161 fem_unlock(vp->v_femhead);
1162 farg.fa_vnode.vp = vp;
1163 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1164 vsop_find(&farg, &func, int, &arg0, vop_frlock,
1165 femop_frlock);
1166 errc = (*func)(arg0, cmd, bfp, flag, offset, flk_cbp, cr, ct);
1167 fem_release(femsp);
1168 }
1169 return (errc);
1170 }
1171
1172 static int
vhead_space(vnode_t * vp,int cmd,struct flock64 * bfp,int flag,offset_t offset,cred_t * cr,caller_context_t * ct)1173 vhead_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
1174 offset_t offset, cred_t *cr, caller_context_t *ct)
1175 {
1176 femarg_t farg;
1177 struct fem_list *femsp;
1178 int (*func)();
1179 void *arg0;
1180 int errc;
1181
1182 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1183 func = (int (*)()) (vp->v_op->vop_space);
1184 arg0 = vp;
1185 fem_unlock(vp->v_femhead);
1186 errc = (*func)(arg0, cmd, bfp, flag, offset, cr, ct);
1187 } else {
1188 fem_addref(femsp);
1189 fem_unlock(vp->v_femhead);
1190 farg.fa_vnode.vp = vp;
1191 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1192 vsop_find(&farg, &func, int, &arg0, vop_space, femop_space);
1193 errc = (*func)(arg0, cmd, bfp, flag, offset, cr, ct);
1194 fem_release(femsp);
1195 }
1196 return (errc);
1197 }
1198
1199 static int
vhead_realvp(vnode_t * vp,vnode_t ** vpp,caller_context_t * ct)1200 vhead_realvp(vnode_t *vp, vnode_t **vpp, caller_context_t *ct)
1201 {
1202 femarg_t farg;
1203 struct fem_list *femsp;
1204 int (*func)();
1205 void *arg0;
1206 int errc;
1207
1208 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1209 func = (int (*)()) (vp->v_op->vop_realvp);
1210 arg0 = vp;
1211 fem_unlock(vp->v_femhead);
1212 errc = (*func)(arg0, vpp, ct);
1213 } else {
1214 fem_addref(femsp);
1215 fem_unlock(vp->v_femhead);
1216 farg.fa_vnode.vp = vp;
1217 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1218 vsop_find(&farg, &func, int, &arg0, vop_realvp,
1219 femop_realvp);
1220 errc = (*func)(arg0, vpp, ct);
1221 fem_release(femsp);
1222 }
1223 return (errc);
1224 }
1225
1226 static int
vhead_getpage(vnode_t * vp,offset_t off,size_t len,uint_t * protp,struct page ** plarr,size_t plsz,struct seg * seg,caddr_t addr,enum seg_rw rw,cred_t * cr,caller_context_t * ct)1227 vhead_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
1228 struct page **plarr, size_t plsz, struct seg *seg, caddr_t addr,
1229 enum seg_rw rw, cred_t *cr, caller_context_t *ct)
1230 {
1231 femarg_t farg;
1232 struct fem_list *femsp;
1233 int (*func)();
1234 void *arg0;
1235 int errc;
1236
1237 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1238 func = (int (*)()) (vp->v_op->vop_getpage);
1239 arg0 = vp;
1240 fem_unlock(vp->v_femhead);
1241 errc = (*func)(arg0, off, len, protp, plarr, plsz, seg,
1242 addr, rw, cr, ct);
1243 } else {
1244 fem_addref(femsp);
1245 fem_unlock(vp->v_femhead);
1246 farg.fa_vnode.vp = vp;
1247 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1248 vsop_find(&farg, &func, int, &arg0, vop_getpage,
1249 femop_getpage);
1250 errc = (*func)(arg0, off, len, protp, plarr, plsz, seg,
1251 addr, rw, cr, ct);
1252 fem_release(femsp);
1253 }
1254 return (errc);
1255 }
1256
1257 static int
vhead_putpage(vnode_t * vp,offset_t off,size_t len,int flags,cred_t * cr,caller_context_t * ct)1258 vhead_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr,
1259 caller_context_t *ct)
1260 {
1261 femarg_t farg;
1262 struct fem_list *femsp;
1263 int (*func)();
1264 void *arg0;
1265 int errc;
1266
1267 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1268 func = (int (*)()) (vp->v_op->vop_putpage);
1269 arg0 = vp;
1270 fem_unlock(vp->v_femhead);
1271 errc = (*func)(arg0, off, len, flags, cr, ct);
1272 } else {
1273 fem_addref(femsp);
1274 fem_unlock(vp->v_femhead);
1275 farg.fa_vnode.vp = vp;
1276 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1277 vsop_find(&farg, &func, int, &arg0, vop_putpage,
1278 femop_putpage);
1279 errc = (*func)(arg0, off, len, flags, cr, ct);
1280 fem_release(femsp);
1281 }
1282 return (errc);
1283 }
1284
1285 static int
vhead_map(vnode_t * vp,offset_t off,struct as * as,caddr_t * addrp,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)1286 vhead_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
1287 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
1288 cred_t *cr, caller_context_t *ct)
1289 {
1290 femarg_t farg;
1291 struct fem_list *femsp;
1292 int (*func)();
1293 void *arg0;
1294 int errc;
1295
1296 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1297 func = (int (*)()) (vp->v_op->vop_map);
1298 arg0 = vp;
1299 fem_unlock(vp->v_femhead);
1300 errc = (*func)(arg0, off, as, addrp, len, prot, maxprot,
1301 flags, cr, ct);
1302 } else {
1303 fem_addref(femsp);
1304 fem_unlock(vp->v_femhead);
1305 farg.fa_vnode.vp = vp;
1306 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1307 vsop_find(&farg, &func, int, &arg0, vop_map, femop_map);
1308 errc = (*func)(arg0, off, as, addrp, len, prot, maxprot,
1309 flags, cr, ct);
1310 fem_release(femsp);
1311 }
1312 return (errc);
1313 }
1314
1315 static int
vhead_addmap(vnode_t * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)1316 vhead_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
1317 size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
1318 cred_t *cr, caller_context_t *ct)
1319 {
1320 femarg_t farg;
1321 struct fem_list *femsp;
1322 int (*func)();
1323 void *arg0;
1324 int errc;
1325
1326 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1327 func = (int (*)()) (vp->v_op->vop_addmap);
1328 arg0 = vp;
1329 fem_unlock(vp->v_femhead);
1330 errc = (*func)(arg0, off, as, addr, len, prot, maxprot,
1331 flags, cr, ct);
1332 } else {
1333 fem_addref(femsp);
1334 fem_unlock(vp->v_femhead);
1335 farg.fa_vnode.vp = vp;
1336 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1337 vsop_find(&farg, &func, int, &arg0, vop_addmap,
1338 femop_addmap);
1339 errc = (*func)(arg0, off, as, addr, len, prot, maxprot,
1340 flags, cr, ct);
1341 fem_release(femsp);
1342 }
1343 return (errc);
1344 }
1345
1346 static int
vhead_delmap(vnode_t * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uint_t prot,uint_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)1347 vhead_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
1348 size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr,
1349 caller_context_t *ct)
1350 {
1351 femarg_t farg;
1352 struct fem_list *femsp;
1353 int (*func)();
1354 void *arg0;
1355 int errc;
1356
1357 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1358 func = (int (*)()) (vp->v_op->vop_delmap);
1359 arg0 = vp;
1360 fem_unlock(vp->v_femhead);
1361 errc = (*func)(arg0, off, as, addr, len, prot, maxprot,
1362 flags, cr, ct);
1363 } else {
1364 fem_addref(femsp);
1365 fem_unlock(vp->v_femhead);
1366 farg.fa_vnode.vp = vp;
1367 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1368 vsop_find(&farg, &func, int, &arg0, vop_delmap,
1369 femop_delmap);
1370 errc = (*func)(arg0, off, as, addr, len, prot, maxprot,
1371 flags, cr, ct);
1372 fem_release(femsp);
1373 }
1374 return (errc);
1375 }
1376
1377 static int
vhead_poll(vnode_t * vp,short events,int anyyet,short * reventsp,struct pollhead ** phpp,caller_context_t * ct)1378 vhead_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
1379 struct pollhead **phpp, caller_context_t *ct)
1380 {
1381 femarg_t farg;
1382 struct fem_list *femsp;
1383 int (*func)();
1384 void *arg0;
1385 int errc;
1386
1387 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1388 func = (int (*)()) (vp->v_op->vop_poll);
1389 arg0 = vp;
1390 fem_unlock(vp->v_femhead);
1391 errc = (*func)(arg0, events, anyyet, reventsp, phpp, ct);
1392 } else {
1393 fem_addref(femsp);
1394 fem_unlock(vp->v_femhead);
1395 farg.fa_vnode.vp = vp;
1396 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1397 vsop_find(&farg, &func, int, &arg0, vop_poll, femop_poll);
1398 errc = (*func)(arg0, events, anyyet, reventsp, phpp, ct);
1399 fem_release(femsp);
1400 }
1401 return (errc);
1402 }
1403
1404 static int
vhead_dump(vnode_t * vp,caddr_t addr,offset_t lbdn,offset_t dblks,caller_context_t * ct)1405 vhead_dump(vnode_t *vp, caddr_t addr, offset_t lbdn, offset_t dblks,
1406 caller_context_t *ct)
1407 {
1408 femarg_t farg;
1409 struct fem_list *femsp;
1410 int (*func)();
1411 void *arg0;
1412 int errc;
1413
1414 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1415 func = (int (*)()) (vp->v_op->vop_dump);
1416 arg0 = vp;
1417 fem_unlock(vp->v_femhead);
1418 errc = (*func)(arg0, addr, lbdn, dblks, ct);
1419 } else {
1420 fem_addref(femsp);
1421 fem_unlock(vp->v_femhead);
1422 farg.fa_vnode.vp = vp;
1423 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1424 vsop_find(&farg, &func, int, &arg0, vop_dump, femop_dump);
1425 errc = (*func)(arg0, addr, lbdn, dblks, ct);
1426 fem_release(femsp);
1427 }
1428 return (errc);
1429 }
1430
1431 static int
vhead_pathconf(vnode_t * vp,int cmd,ulong_t * valp,cred_t * cr,caller_context_t * ct)1432 vhead_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
1433 caller_context_t *ct)
1434 {
1435 femarg_t farg;
1436 struct fem_list *femsp;
1437 int (*func)();
1438 void *arg0;
1439 int errc;
1440
1441 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1442 func = (int (*)()) (vp->v_op->vop_pathconf);
1443 arg0 = vp;
1444 fem_unlock(vp->v_femhead);
1445 errc = (*func)(arg0, cmd, valp, cr, ct);
1446 } else {
1447 fem_addref(femsp);
1448 fem_unlock(vp->v_femhead);
1449 farg.fa_vnode.vp = vp;
1450 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1451 vsop_find(&farg, &func, int, &arg0, vop_pathconf,
1452 femop_pathconf);
1453 errc = (*func)(arg0, cmd, valp, cr, ct);
1454 fem_release(femsp);
1455 }
1456 return (errc);
1457 }
1458
1459 static int
vhead_pageio(vnode_t * vp,struct page * pp,u_offset_t io_off,size_t io_len,int flags,cred_t * cr,caller_context_t * ct)1460 vhead_pageio(vnode_t *vp, struct page *pp, u_offset_t io_off,
1461 size_t io_len, int flags, cred_t *cr, caller_context_t *ct)
1462 {
1463 femarg_t farg;
1464 struct fem_list *femsp;
1465 int (*func)();
1466 void *arg0;
1467 int errc;
1468
1469 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1470 func = (int (*)()) (vp->v_op->vop_pageio);
1471 arg0 = vp;
1472 fem_unlock(vp->v_femhead);
1473 errc = (*func)(arg0, pp, io_off, io_len, flags, cr, ct);
1474 } else {
1475 fem_addref(femsp);
1476 fem_unlock(vp->v_femhead);
1477 farg.fa_vnode.vp = vp;
1478 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1479 vsop_find(&farg, &func, int, &arg0, vop_pageio,
1480 femop_pageio);
1481 errc = (*func)(arg0, pp, io_off, io_len, flags, cr, ct);
1482 fem_release(femsp);
1483 }
1484 return (errc);
1485 }
1486
1487 static int
vhead_dumpctl(vnode_t * vp,int action,offset_t * blkp,caller_context_t * ct)1488 vhead_dumpctl(vnode_t *vp, int action, offset_t *blkp, caller_context_t *ct)
1489 {
1490 femarg_t farg;
1491 struct fem_list *femsp;
1492 int (*func)();
1493 void *arg0;
1494 int errc;
1495
1496 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1497 func = (int (*)()) (vp->v_op->vop_dumpctl);
1498 arg0 = vp;
1499 fem_unlock(vp->v_femhead);
1500 errc = (*func)(arg0, action, blkp, ct);
1501 } else {
1502 fem_addref(femsp);
1503 fem_unlock(vp->v_femhead);
1504 farg.fa_vnode.vp = vp;
1505 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1506 vsop_find(&farg, &func, int, &arg0, vop_dumpctl,
1507 femop_dumpctl);
1508 errc = (*func)(arg0, action, blkp, ct);
1509 fem_release(femsp);
1510 }
1511 return (errc);
1512 }
1513
1514 static int
vhead_dispose(vnode_t * vp,struct page * pp,int flag,int dn,cred_t * cr,caller_context_t * ct)1515 vhead_dispose(vnode_t *vp, struct page *pp, int flag, int dn, cred_t *cr,
1516 caller_context_t *ct)
1517 {
1518 femarg_t farg;
1519 struct fem_list *femsp;
1520 void (*func)();
1521 void *arg0;
1522
1523 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1524 func = (void (*)()) (vp->v_op->vop_dispose);
1525 arg0 = vp;
1526 fem_unlock(vp->v_femhead);
1527 (*func)(arg0, pp, flag, dn, cr, ct);
1528 } else {
1529 fem_addref(femsp);
1530 fem_unlock(vp->v_femhead);
1531 farg.fa_vnode.vp = vp;
1532 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1533 vsop_find(&farg, &func, void, &arg0, vop_dispose,
1534 femop_dispose);
1535 (*func)(arg0, pp, flag, dn, cr, ct);
1536 fem_release(femsp);
1537 }
1538 return (0);
1539 }
1540
1541 static int
vhead_setsecattr(vnode_t * vp,vsecattr_t * vsap,int flag,cred_t * cr,caller_context_t * ct)1542 vhead_setsecattr(vnode_t *vp, vsecattr_t *vsap, int flag, cred_t *cr,
1543 caller_context_t *ct)
1544 {
1545 femarg_t farg;
1546 struct fem_list *femsp;
1547 int (*func)();
1548 void *arg0;
1549 int errc;
1550
1551 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1552 func = (int (*)()) (vp->v_op->vop_setsecattr);
1553 arg0 = vp;
1554 fem_unlock(vp->v_femhead);
1555 errc = (*func)(arg0, vsap, flag, cr, ct);
1556 } else {
1557 fem_addref(femsp);
1558 fem_unlock(vp->v_femhead);
1559 farg.fa_vnode.vp = vp;
1560 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1561 vsop_find(&farg, &func, int, &arg0, vop_setsecattr,
1562 femop_setsecattr);
1563 errc = (*func)(arg0, vsap, flag, cr, ct);
1564 fem_release(femsp);
1565 }
1566 return (errc);
1567 }
1568
1569 static int
vhead_getsecattr(vnode_t * vp,vsecattr_t * vsap,int flag,cred_t * cr,caller_context_t * ct)1570 vhead_getsecattr(vnode_t *vp, vsecattr_t *vsap, int flag, cred_t *cr,
1571 caller_context_t *ct)
1572 {
1573 femarg_t farg;
1574 struct fem_list *femsp;
1575 int (*func)();
1576 void *arg0;
1577 int errc;
1578
1579 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1580 func = (int (*)()) (vp->v_op->vop_getsecattr);
1581 arg0 = vp;
1582 fem_unlock(vp->v_femhead);
1583 errc = (*func)(arg0, vsap, flag, cr, ct);
1584 } else {
1585 fem_addref(femsp);
1586 fem_unlock(vp->v_femhead);
1587 farg.fa_vnode.vp = vp;
1588 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1589 vsop_find(&farg, &func, int, &arg0, vop_getsecattr,
1590 femop_getsecattr);
1591 errc = (*func)(arg0, vsap, flag, cr, ct);
1592 fem_release(femsp);
1593 }
1594 return (errc);
1595 }
1596
1597 static int
vhead_shrlock(vnode_t * vp,int cmd,struct shrlock * shr,int flag,cred_t * cr,caller_context_t * ct)1598 vhead_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag,
1599 cred_t *cr, caller_context_t *ct)
1600 {
1601 femarg_t farg;
1602 struct fem_list *femsp;
1603 int (*func)();
1604 void *arg0;
1605 int errc;
1606
1607 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1608 func = (int (*)()) (vp->v_op->vop_shrlock);
1609 arg0 = vp;
1610 fem_unlock(vp->v_femhead);
1611 errc = (*func)(arg0, cmd, shr, flag, cr, ct);
1612 } else {
1613 fem_addref(femsp);
1614 fem_unlock(vp->v_femhead);
1615 farg.fa_vnode.vp = vp;
1616 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1617 vsop_find(&farg, &func, int, &arg0, vop_shrlock,
1618 femop_shrlock);
1619 errc = (*func)(arg0, cmd, shr, flag, cr, ct);
1620 fem_release(femsp);
1621 }
1622 return (errc);
1623 }
1624
1625 static int
vhead_vnevent(vnode_t * vp,vnevent_t vnevent,vnode_t * dvp,char * cname,caller_context_t * ct)1626 vhead_vnevent(vnode_t *vp, vnevent_t vnevent, vnode_t *dvp, char *cname,
1627 caller_context_t *ct)
1628 {
1629 femarg_t farg;
1630 struct fem_list *femsp;
1631 int (*func)();
1632 void *arg0;
1633 int errc;
1634
1635 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1636 func = (int (*)()) (vp->v_op->vop_vnevent);
1637 arg0 = vp;
1638 fem_unlock(vp->v_femhead);
1639 errc = (*func)(arg0, vnevent, dvp, cname, ct);
1640 } else {
1641 fem_addref(femsp);
1642 fem_unlock(vp->v_femhead);
1643 farg.fa_vnode.vp = vp;
1644 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1645 vsop_find(&farg, &func, int, &arg0, vop_vnevent,
1646 femop_vnevent);
1647 errc = (*func)(arg0, vnevent, dvp, cname, ct);
1648 fem_release(femsp);
1649 }
1650 return (errc);
1651 }
1652
1653 static int
vhead_reqzcbuf(vnode_t * vp,enum uio_rw ioflag,xuio_t * xuiop,cred_t * cr,caller_context_t * ct)1654 vhead_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *xuiop, cred_t *cr,
1655 caller_context_t *ct)
1656 {
1657 femarg_t farg;
1658 struct fem_list *femsp;
1659 int (*func)();
1660 void *arg0;
1661 int errc;
1662
1663 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1664 func = (int (*)()) (vp->v_op->vop_reqzcbuf);
1665 arg0 = vp;
1666 fem_unlock(vp->v_femhead);
1667 errc = (*func)(arg0, ioflag, xuiop, cr, ct);
1668 } else {
1669 fem_addref(femsp);
1670 fem_unlock(vp->v_femhead);
1671 farg.fa_vnode.vp = vp;
1672 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1673 vsop_find(&farg, &func, int, &arg0, vop_reqzcbuf,
1674 femop_reqzcbuf);
1675 errc = (*func)(arg0, ioflag, xuiop, cr, ct);
1676 fem_release(femsp);
1677 }
1678 return (errc);
1679 }
1680
1681 static int
vhead_retzcbuf(vnode_t * vp,xuio_t * xuiop,cred_t * cr,caller_context_t * ct)1682 vhead_retzcbuf(vnode_t *vp, xuio_t *xuiop, cred_t *cr, caller_context_t *ct)
1683 {
1684 femarg_t farg;
1685 struct fem_list *femsp;
1686 int (*func)();
1687 void *arg0;
1688 int errc;
1689
1690 if ((femsp = fem_lock(vp->v_femhead)) == NULL) {
1691 func = (int (*)()) (vp->v_op->vop_retzcbuf);
1692 arg0 = vp;
1693 fem_unlock(vp->v_femhead);
1694 errc = (*func)(arg0, xuiop, cr, ct);
1695 } else {
1696 fem_addref(femsp);
1697 fem_unlock(vp->v_femhead);
1698 farg.fa_vnode.vp = vp;
1699 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1700 vsop_find(&farg, &func, int, &arg0, vop_retzcbuf,
1701 femop_retzcbuf);
1702 errc = (*func)(arg0, xuiop, cr, ct);
1703 fem_release(femsp);
1704 }
1705 return (errc);
1706 }
1707
1708 static int
fshead_mount(vfs_t * vfsp,vnode_t * mvp,struct mounta * uap,cred_t * cr)1709 fshead_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
1710 {
1711 fsemarg_t farg;
1712 struct fem_list *femsp;
1713 int (*func)();
1714 void *arg0;
1715 int errc;
1716
1717 ASSERT(vfsp->vfs_implp);
1718
1719 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1720 func = (int (*)()) vfsp->vfs_op->vfs_mount;
1721 fem_unlock(vfsp->vfs_femhead);
1722 errc = (*func)(vfsp, mvp, uap, cr);
1723 } else {
1724 fem_addref(femsp);
1725 fem_unlock(vfsp->vfs_femhead);
1726 farg.fa_vnode.vfsp = vfsp;
1727 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1728 vfsop_find(&farg, &func, int, &arg0, vfs_mount,
1729 fsemop_mount);
1730 errc = (*func)(arg0, mvp, uap, cr);
1731 fem_release(femsp);
1732 }
1733 return (errc);
1734 }
1735
1736 static int
fshead_unmount(vfs_t * vfsp,int flag,cred_t * cr)1737 fshead_unmount(vfs_t *vfsp, int flag, cred_t *cr)
1738 {
1739 fsemarg_t farg;
1740 struct fem_list *femsp;
1741 int (*func)();
1742 void *arg0;
1743 int errc;
1744
1745 ASSERT(vfsp->vfs_implp);
1746
1747 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1748 func = (int (*)()) vfsp->vfs_op->vfs_unmount;
1749 fem_unlock(vfsp->vfs_femhead);
1750 errc = (*func)(vfsp, flag, cr);
1751 } else {
1752 fem_addref(femsp);
1753 fem_unlock(vfsp->vfs_femhead);
1754 farg.fa_vnode.vfsp = vfsp;
1755 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1756 vfsop_find(&farg, &func, int, &arg0, vfs_unmount,
1757 fsemop_unmount);
1758 errc = (*func)(arg0, flag, cr);
1759 fem_release(femsp);
1760 }
1761 return (errc);
1762 }
1763
1764 static int
fshead_root(vfs_t * vfsp,vnode_t ** vpp)1765 fshead_root(vfs_t *vfsp, vnode_t **vpp)
1766 {
1767 fsemarg_t farg;
1768 struct fem_list *femsp;
1769 int (*func)();
1770 void *arg0;
1771 int errc;
1772
1773 ASSERT(vfsp->vfs_implp);
1774
1775 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1776 func = (int (*)()) vfsp->vfs_op->vfs_root;
1777 fem_unlock(vfsp->vfs_femhead);
1778 errc = (*func)(vfsp, vpp);
1779 } else {
1780 fem_addref(femsp);
1781 fem_unlock(vfsp->vfs_femhead);
1782 farg.fa_vnode.vfsp = vfsp;
1783 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1784 vfsop_find(&farg, &func, int, &arg0, vfs_root, fsemop_root);
1785 errc = (*func)(arg0, vpp);
1786 fem_release(femsp);
1787 }
1788 return (errc);
1789 }
1790
1791 static int
fshead_statvfs(vfs_t * vfsp,statvfs64_t * sp)1792 fshead_statvfs(vfs_t *vfsp, statvfs64_t *sp)
1793 {
1794 fsemarg_t farg;
1795 struct fem_list *femsp;
1796 int (*func)();
1797 void *arg0;
1798 int errc;
1799
1800 ASSERT(vfsp->vfs_implp);
1801
1802 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1803 func = (int (*)()) vfsp->vfs_op->vfs_statvfs;
1804 fem_unlock(vfsp->vfs_femhead);
1805 errc = (*func)(vfsp, sp);
1806 } else {
1807 fem_addref(femsp);
1808 fem_unlock(vfsp->vfs_femhead);
1809 farg.fa_vnode.vfsp = vfsp;
1810 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1811 vfsop_find(&farg, &func, int, &arg0, vfs_statvfs,
1812 fsemop_statvfs);
1813 errc = (*func)(arg0, sp);
1814 fem_release(femsp);
1815 }
1816 return (errc);
1817 }
1818
1819 static int
fshead_sync(vfs_t * vfsp,short flag,cred_t * cr)1820 fshead_sync(vfs_t *vfsp, short flag, cred_t *cr)
1821 {
1822 fsemarg_t farg;
1823 struct fem_list *femsp;
1824 int (*func)();
1825 void *arg0;
1826 int errc;
1827
1828 ASSERT(vfsp->vfs_implp);
1829
1830 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1831 func = (int (*)()) vfsp->vfs_op->vfs_sync;
1832 fem_unlock(vfsp->vfs_femhead);
1833 errc = (*func)(vfsp, flag, cr);
1834 } else {
1835 fem_addref(femsp);
1836 fem_unlock(vfsp->vfs_femhead);
1837 farg.fa_vnode.vfsp = vfsp;
1838 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1839 vfsop_find(&farg, &func, int, &arg0, vfs_sync, fsemop_sync);
1840 errc = (*func)(arg0, flag, cr);
1841 fem_release(femsp);
1842 }
1843 return (errc);
1844 }
1845
1846 static int
fshead_vget(vfs_t * vfsp,vnode_t ** vpp,fid_t * fidp)1847 fshead_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
1848 {
1849 fsemarg_t farg;
1850 struct fem_list *femsp;
1851 int (*func)();
1852 void *arg0;
1853 int errc;
1854
1855 ASSERT(vfsp->vfs_implp);
1856
1857 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1858 func = (int (*)()) vfsp->vfs_op->vfs_vget;
1859 fem_unlock(vfsp->vfs_femhead);
1860 errc = (*func)(vfsp, vpp, fidp);
1861 } else {
1862 fem_addref(femsp);
1863 fem_unlock(vfsp->vfs_femhead);
1864 farg.fa_vnode.vfsp = vfsp;
1865 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1866 vfsop_find(&farg, &func, int, &arg0, vfs_vget, fsemop_vget);
1867 errc = (*func)(arg0, vpp, fidp);
1868 fem_release(femsp);
1869 }
1870 return (errc);
1871 }
1872
1873 static int
fshead_mountroot(vfs_t * vfsp,enum whymountroot reason)1874 fshead_mountroot(vfs_t *vfsp, enum whymountroot reason)
1875 {
1876 fsemarg_t farg;
1877 struct fem_list *femsp;
1878 int (*func)();
1879 void *arg0;
1880 int errc;
1881
1882 ASSERT(vfsp->vfs_implp);
1883
1884 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1885 func = (int (*)()) vfsp->vfs_op->vfs_mountroot;
1886 fem_unlock(vfsp->vfs_femhead);
1887 errc = (*func)(vfsp, reason);
1888 } else {
1889 fem_addref(femsp);
1890 fem_unlock(vfsp->vfs_femhead);
1891 farg.fa_vnode.vfsp = vfsp;
1892 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1893 vfsop_find(&farg, &func, int, &arg0, vfs_mountroot,
1894 fsemop_mountroot);
1895 errc = (*func)(arg0, reason);
1896 fem_release(femsp);
1897 }
1898 return (errc);
1899 }
1900
1901 static int
fshead_freevfs(vfs_t * vfsp)1902 fshead_freevfs(vfs_t *vfsp)
1903 {
1904 fsemarg_t farg;
1905 struct fem_list *femsp;
1906 void (*func)();
1907 void *arg0;
1908
1909 ASSERT(vfsp->vfs_implp);
1910
1911 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1912 func = (void (*)()) vfsp->vfs_op->vfs_freevfs;
1913 fem_unlock(vfsp->vfs_femhead);
1914 (*func)(vfsp);
1915 } else {
1916 fem_addref(femsp);
1917 fem_unlock(vfsp->vfs_femhead);
1918 farg.fa_vnode.vfsp = vfsp;
1919 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1920 vfsop_find(&farg, &func, void, &arg0, vfs_freevfs,
1921 fsemop_freevfs);
1922 (*func)(arg0);
1923 fem_release(femsp);
1924 }
1925 return (0);
1926 }
1927
1928 static int
fshead_vnstate(vfs_t * vfsp,vnode_t * vp,vntrans_t nstate)1929 fshead_vnstate(vfs_t *vfsp, vnode_t *vp, vntrans_t nstate)
1930 {
1931 fsemarg_t farg;
1932 struct fem_list *femsp;
1933 int (*func)();
1934 void *arg0;
1935 int errc;
1936
1937 ASSERT(vfsp->vfs_implp);
1938
1939 if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) {
1940 func = (int (*)()) vfsp->vfs_op->vfs_vnstate;
1941 fem_unlock(vfsp->vfs_femhead);
1942 errc = (*func)(vfsp, vp, nstate);
1943 } else {
1944 fem_addref(femsp);
1945 fem_unlock(vfsp->vfs_femhead);
1946 farg.fa_vnode.vfsp = vfsp;
1947 farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos;
1948 vfsop_find(&farg, &func, int, &arg0, vfs_vnstate,
1949 fsemop_vnstate);
1950 errc = (*func)(arg0, vp, nstate);
1951 fem_release(femsp);
1952 }
1953 return (errc);
1954 }
1955
1956
1957 /*
1958 * specification table for the vhead vnode operations.
1959 * It is an error for any operations to be missing.
1960 */
1961
1962 static struct fs_operation_def fhead_vn_spec[] = {
1963 { VOPNAME_OPEN, (femop_t *)vhead_open },
1964 { VOPNAME_CLOSE, (femop_t *)vhead_close },
1965 { VOPNAME_READ, (femop_t *)vhead_read },
1966 { VOPNAME_WRITE, (femop_t *)vhead_write },
1967 { VOPNAME_IOCTL, (femop_t *)vhead_ioctl },
1968 { VOPNAME_SETFL, (femop_t *)vhead_setfl },
1969 { VOPNAME_GETATTR, (femop_t *)vhead_getattr },
1970 { VOPNAME_SETATTR, (femop_t *)vhead_setattr },
1971 { VOPNAME_ACCESS, (femop_t *)vhead_access },
1972 { VOPNAME_LOOKUP, (femop_t *)vhead_lookup },
1973 { VOPNAME_CREATE, (femop_t *)vhead_create },
1974 { VOPNAME_REMOVE, (femop_t *)vhead_remove },
1975 { VOPNAME_LINK, (femop_t *)vhead_link },
1976 { VOPNAME_RENAME, (femop_t *)vhead_rename },
1977 { VOPNAME_MKDIR, (femop_t *)vhead_mkdir },
1978 { VOPNAME_RMDIR, (femop_t *)vhead_rmdir },
1979 { VOPNAME_READDIR, (femop_t *)vhead_readdir },
1980 { VOPNAME_SYMLINK, (femop_t *)vhead_symlink },
1981 { VOPNAME_READLINK, (femop_t *)vhead_readlink },
1982 { VOPNAME_FSYNC, (femop_t *)vhead_fsync },
1983 { VOPNAME_INACTIVE, (femop_t *)vhead_inactive },
1984 { VOPNAME_FID, (femop_t *)vhead_fid },
1985 { VOPNAME_RWLOCK, (femop_t *)vhead_rwlock },
1986 { VOPNAME_RWUNLOCK, (femop_t *)vhead_rwunlock },
1987 { VOPNAME_SEEK, (femop_t *)vhead_seek },
1988 { VOPNAME_CMP, (femop_t *)vhead_cmp },
1989 { VOPNAME_FRLOCK, (femop_t *)vhead_frlock },
1990 { VOPNAME_SPACE, (femop_t *)vhead_space },
1991 { VOPNAME_REALVP, (femop_t *)vhead_realvp },
1992 { VOPNAME_GETPAGE, (femop_t *)vhead_getpage },
1993 { VOPNAME_PUTPAGE, (femop_t *)vhead_putpage },
1994 { VOPNAME_MAP, (femop_t *)vhead_map },
1995 { VOPNAME_ADDMAP, (femop_t *)vhead_addmap },
1996 { VOPNAME_DELMAP, (femop_t *)vhead_delmap },
1997 { VOPNAME_POLL, (femop_t *)vhead_poll },
1998 { VOPNAME_DUMP, (femop_t *)vhead_dump },
1999 { VOPNAME_PATHCONF, (femop_t *)vhead_pathconf },
2000 { VOPNAME_PAGEIO, (femop_t *)vhead_pageio },
2001 { VOPNAME_DUMPCTL, (femop_t *)vhead_dumpctl },
2002 { VOPNAME_DISPOSE, (femop_t *)vhead_dispose },
2003 { VOPNAME_SETSECATTR, (femop_t *)vhead_setsecattr },
2004 { VOPNAME_GETSECATTR, (femop_t *)vhead_getsecattr },
2005 { VOPNAME_SHRLOCK, (femop_t *)vhead_shrlock },
2006 { VOPNAME_VNEVENT, (femop_t *)vhead_vnevent },
2007 { VOPNAME_REQZCBUF, (femop_t *)vhead_reqzcbuf },
2008 { VOPNAME_RETZCBUF, (femop_t *)vhead_retzcbuf },
2009 { NULL, NULL }
2010 };
2011
2012 /*
2013 * specification table for the vfshead vnode operations.
2014 * It is an error for any operations to be missing.
2015 */
2016
2017 static struct fs_operation_def fshead_vfs_spec[] = {
2018 { VFSNAME_MOUNT, (femop_t *)fshead_mount },
2019 { VFSNAME_UNMOUNT, (femop_t *)fshead_unmount },
2020 { VFSNAME_ROOT, (femop_t *)fshead_root },
2021 { VFSNAME_STATVFS, (femop_t *)fshead_statvfs },
2022 { VFSNAME_SYNC, (femop_t *)fshead_sync },
2023 { VFSNAME_VGET, (femop_t *)fshead_vget },
2024 { VFSNAME_MOUNTROOT, (femop_t *)fshead_mountroot },
2025 { VFSNAME_FREEVFS, (femop_t *)fshead_freevfs },
2026 { VFSNAME_VNSTATE, (femop_t *)fshead_vnstate },
2027 { NULL, NULL }
2028 };
2029
2030 /*
2031 * This set of routines transfer control to the next stacked monitor.
2032 *
2033 * Each routine is identical except for naming, types and arguments.
2034 *
2035 * The basic steps are:
2036 * 1. Decrease the stack pointer by one.
2037 * 2. If the current item is a base operation (vnode, vfs), goto 5.
2038 * 3. If the current item does not have a corresponding operation, goto 1
2039 * 4. Return by invoking the current item with the argument handle.
2040 * 5. Return by invoking the base operation with the base object.
2041 *
2042 * for each classification, there needs to be at least one "next" operation
2043 * for each "head"operation.
2044 *
2045 */
2046
2047 int
vnext_open(femarg_t * vf,int mode,cred_t * cr,caller_context_t * ct)2048 vnext_open(femarg_t *vf, int mode, cred_t *cr, caller_context_t *ct)
2049 {
2050 int (*func)() = NULL;
2051 void *arg0 = NULL;
2052
2053 ASSERT(vf != NULL);
2054 vf->fa_fnode--;
2055 vsop_find(vf, &func, int, &arg0, vop_open, femop_open);
2056 ASSERT(func != NULL);
2057 ASSERT(arg0 != NULL);
2058 return ((*func)(arg0, mode, cr, ct));
2059 }
2060
2061 int
vnext_close(femarg_t * vf,int flag,int count,offset_t offset,cred_t * cr,caller_context_t * ct)2062 vnext_close(femarg_t *vf, int flag, int count, offset_t offset, cred_t *cr,
2063 caller_context_t *ct)
2064 {
2065 int (*func)() = NULL;
2066 void *arg0 = NULL;
2067
2068 ASSERT(vf != NULL);
2069 vf->fa_fnode--;
2070 vsop_find(vf, &func, int, &arg0, vop_close, femop_close);
2071 ASSERT(func != NULL);
2072 ASSERT(arg0 != NULL);
2073 return ((*func)(arg0, flag, count, offset, cr, ct));
2074 }
2075
2076 int
vnext_read(femarg_t * vf,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)2077 vnext_read(femarg_t *vf, uio_t *uiop, int ioflag, cred_t *cr,
2078 caller_context_t *ct)
2079 {
2080 int (*func)() = NULL;
2081 void *arg0 = NULL;
2082
2083 ASSERT(vf != NULL);
2084 vf->fa_fnode--;
2085 vsop_find(vf, &func, int, &arg0, vop_read, femop_read);
2086 ASSERT(func != NULL);
2087 ASSERT(arg0 != NULL);
2088 return ((*func)(arg0, uiop, ioflag, cr, ct));
2089 }
2090
2091 int
vnext_write(femarg_t * vf,uio_t * uiop,int ioflag,cred_t * cr,caller_context_t * ct)2092 vnext_write(femarg_t *vf, uio_t *uiop, int ioflag, cred_t *cr,
2093 caller_context_t *ct)
2094 {
2095 int (*func)() = NULL;
2096 void *arg0 = NULL;
2097
2098 ASSERT(vf != NULL);
2099 vf->fa_fnode--;
2100 vsop_find(vf, &func, int, &arg0, vop_write, femop_write);
2101 ASSERT(func != NULL);
2102 ASSERT(arg0 != NULL);
2103 return ((*func)(arg0, uiop, ioflag, cr, ct));
2104 }
2105
2106 int
vnext_ioctl(femarg_t * vf,int cmd,intptr_t arg,int flag,cred_t * cr,int * rvalp,caller_context_t * ct)2107 vnext_ioctl(femarg_t *vf, int cmd, intptr_t arg, int flag, cred_t *cr,
2108 int *rvalp, caller_context_t *ct)
2109 {
2110 int (*func)() = NULL;
2111 void *arg0 = NULL;
2112
2113 ASSERT(vf != NULL);
2114 vf->fa_fnode--;
2115 vsop_find(vf, &func, int, &arg0, vop_ioctl, femop_ioctl);
2116 ASSERT(func != NULL);
2117 ASSERT(arg0 != NULL);
2118 return ((*func)(arg0, cmd, arg, flag, cr, rvalp, ct));
2119 }
2120
2121 int
vnext_setfl(femarg_t * vf,int oflags,int nflags,cred_t * cr,caller_context_t * ct)2122 vnext_setfl(femarg_t *vf, int oflags, int nflags, cred_t *cr,
2123 caller_context_t *ct)
2124 {
2125 int (*func)() = NULL;
2126 void *arg0 = NULL;
2127
2128 ASSERT(vf != NULL);
2129 vf->fa_fnode--;
2130 vsop_find(vf, &func, int, &arg0, vop_setfl, femop_setfl);
2131 ASSERT(func != NULL);
2132 ASSERT(arg0 != NULL);
2133 return ((*func)(arg0, oflags, nflags, cr, ct));
2134 }
2135
2136 int
vnext_getattr(femarg_t * vf,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)2137 vnext_getattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr,
2138 caller_context_t *ct)
2139 {
2140 int (*func)() = NULL;
2141 void *arg0 = NULL;
2142
2143 ASSERT(vf != NULL);
2144 vf->fa_fnode--;
2145 vsop_find(vf, &func, int, &arg0, vop_getattr, femop_getattr);
2146 ASSERT(func != NULL);
2147 ASSERT(arg0 != NULL);
2148 return ((*func)(arg0, vap, flags, cr, ct));
2149 }
2150
2151 int
vnext_setattr(femarg_t * vf,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)2152 vnext_setattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr,
2153 caller_context_t *ct)
2154 {
2155 int (*func)() = NULL;
2156 void *arg0 = NULL;
2157
2158 ASSERT(vf != NULL);
2159 vf->fa_fnode--;
2160 vsop_find(vf, &func, int, &arg0, vop_setattr, femop_setattr);
2161 ASSERT(func != NULL);
2162 ASSERT(arg0 != NULL);
2163 return ((*func)(arg0, vap, flags, cr, ct));
2164 }
2165
2166 int
vnext_access(femarg_t * vf,int mode,int flags,cred_t * cr,caller_context_t * ct)2167 vnext_access(femarg_t *vf, int mode, int flags, cred_t *cr,
2168 caller_context_t *ct)
2169 {
2170 int (*func)() = NULL;
2171 void *arg0 = NULL;
2172
2173 ASSERT(vf != NULL);
2174 vf->fa_fnode--;
2175 vsop_find(vf, &func, int, &arg0, vop_access, femop_access);
2176 ASSERT(func != NULL);
2177 ASSERT(arg0 != NULL);
2178 return ((*func)(arg0, mode, flags, cr, ct));
2179 }
2180
2181 int
vnext_lookup(femarg_t * vf,char * nm,vnode_t ** vpp,pathname_t * pnp,int flags,vnode_t * rdir,cred_t * cr,caller_context_t * ct,int * direntflags,pathname_t * realpnp)2182 vnext_lookup(femarg_t *vf, char *nm, vnode_t **vpp, pathname_t *pnp,
2183 int flags, vnode_t *rdir, cred_t *cr, caller_context_t *ct,
2184 int *direntflags, pathname_t *realpnp)
2185 {
2186 int (*func)() = NULL;
2187 void *arg0 = NULL;
2188
2189 ASSERT(vf != NULL);
2190 vf->fa_fnode--;
2191 vsop_find(vf, &func, int, &arg0, vop_lookup, femop_lookup);
2192 ASSERT(func != NULL);
2193 ASSERT(arg0 != NULL);
2194 return ((*func)(arg0, nm, vpp, pnp, flags, rdir, cr, ct,
2195 direntflags, realpnp));
2196 }
2197
2198 int
vnext_create(femarg_t * vf,char * name,vattr_t * vap,vcexcl_t excl,int mode,vnode_t ** vpp,cred_t * cr,int flag,caller_context_t * ct,vsecattr_t * vsecp)2199 vnext_create(femarg_t *vf, char *name, vattr_t *vap, vcexcl_t excl,
2200 int mode, vnode_t **vpp, cred_t *cr, int flag, caller_context_t *ct,
2201 vsecattr_t *vsecp)
2202 {
2203 int (*func)() = NULL;
2204 void *arg0 = NULL;
2205
2206 ASSERT(vf != NULL);
2207 vf->fa_fnode--;
2208 vsop_find(vf, &func, int, &arg0, vop_create, femop_create);
2209 ASSERT(func != NULL);
2210 ASSERT(arg0 != NULL);
2211 return ((*func)(arg0, name, vap, excl, mode, vpp, cr, flag, ct, vsecp));
2212 }
2213
2214 int
vnext_remove(femarg_t * vf,char * nm,cred_t * cr,caller_context_t * ct,int flags)2215 vnext_remove(femarg_t *vf, char *nm, cred_t *cr, caller_context_t *ct,
2216 int flags)
2217 {
2218 int (*func)() = NULL;
2219 void *arg0 = NULL;
2220
2221 ASSERT(vf != NULL);
2222 vf->fa_fnode--;
2223 vsop_find(vf, &func, int, &arg0, vop_remove, femop_remove);
2224 ASSERT(func != NULL);
2225 ASSERT(arg0 != NULL);
2226 return ((*func)(arg0, nm, cr, ct, flags));
2227 }
2228
2229 int
vnext_link(femarg_t * vf,vnode_t * svp,char * tnm,cred_t * cr,caller_context_t * ct,int flags)2230 vnext_link(femarg_t *vf, vnode_t *svp, char *tnm, cred_t *cr,
2231 caller_context_t *ct, int flags)
2232 {
2233 int (*func)() = NULL;
2234 void *arg0 = NULL;
2235
2236 ASSERT(vf != NULL);
2237 vf->fa_fnode--;
2238 vsop_find(vf, &func, int, &arg0, vop_link, femop_link);
2239 ASSERT(func != NULL);
2240 ASSERT(arg0 != NULL);
2241 return ((*func)(arg0, svp, tnm, cr, ct, flags));
2242 }
2243
2244 int
vnext_rename(femarg_t * vf,char * snm,vnode_t * tdvp,char * tnm,cred_t * cr,caller_context_t * ct,int flags)2245 vnext_rename(femarg_t *vf, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr,
2246 caller_context_t *ct, int flags)
2247 {
2248 int (*func)() = NULL;
2249 void *arg0 = NULL;
2250
2251 ASSERT(vf != NULL);
2252 vf->fa_fnode--;
2253 vsop_find(vf, &func, int, &arg0, vop_rename, femop_rename);
2254 ASSERT(func != NULL);
2255 ASSERT(arg0 != NULL);
2256 return ((*func)(arg0, snm, tdvp, tnm, cr, ct, flags));
2257 }
2258
2259 int
vnext_mkdir(femarg_t * vf,char * dirname,vattr_t * vap,vnode_t ** vpp,cred_t * cr,caller_context_t * ct,int flags,vsecattr_t * vsecp)2260 vnext_mkdir(femarg_t *vf, char *dirname, vattr_t *vap, vnode_t **vpp,
2261 cred_t *cr, caller_context_t *ct, int flags, vsecattr_t *vsecp)
2262 {
2263 int (*func)() = NULL;
2264 void *arg0 = NULL;
2265
2266 ASSERT(vf != NULL);
2267 vf->fa_fnode--;
2268 vsop_find(vf, &func, int, &arg0, vop_mkdir, femop_mkdir);
2269 ASSERT(func != NULL);
2270 ASSERT(arg0 != NULL);
2271 return ((*func)(arg0, dirname, vap, vpp, cr, ct, flags, vsecp));
2272 }
2273
2274 int
vnext_rmdir(femarg_t * vf,char * nm,vnode_t * cdir,cred_t * cr,caller_context_t * ct,int flags)2275 vnext_rmdir(femarg_t *vf, char *nm, vnode_t *cdir, cred_t *cr,
2276 caller_context_t *ct, int flags)
2277 {
2278 int (*func)() = NULL;
2279 void *arg0 = NULL;
2280
2281 ASSERT(vf != NULL);
2282 vf->fa_fnode--;
2283 vsop_find(vf, &func, int, &arg0, vop_rmdir, femop_rmdir);
2284 ASSERT(func != NULL);
2285 ASSERT(arg0 != NULL);
2286 return ((*func)(arg0, nm, cdir, cr, ct, flags));
2287 }
2288
2289 int
vnext_readdir(femarg_t * vf,uio_t * uiop,cred_t * cr,int * eofp,caller_context_t * ct,int flags)2290 vnext_readdir(femarg_t *vf, uio_t *uiop, cred_t *cr, int *eofp,
2291 caller_context_t *ct, int flags)
2292 {
2293 int (*func)() = NULL;
2294 void *arg0 = NULL;
2295
2296 ASSERT(vf != NULL);
2297 vf->fa_fnode--;
2298 vsop_find(vf, &func, int, &arg0, vop_readdir, femop_readdir);
2299 ASSERT(func != NULL);
2300 ASSERT(arg0 != NULL);
2301 return ((*func)(arg0, uiop, cr, eofp, ct, flags));
2302 }
2303
2304 int
vnext_symlink(femarg_t * vf,char * linkname,vattr_t * vap,char * target,cred_t * cr,caller_context_t * ct,int flags)2305 vnext_symlink(femarg_t *vf, char *linkname, vattr_t *vap, char *target,
2306 cred_t *cr, caller_context_t *ct, int flags)
2307 {
2308 int (*func)() = NULL;
2309 void *arg0 = NULL;
2310
2311 ASSERT(vf != NULL);
2312 vf->fa_fnode--;
2313 vsop_find(vf, &func, int, &arg0, vop_symlink, femop_symlink);
2314 ASSERT(func != NULL);
2315 ASSERT(arg0 != NULL);
2316 return ((*func)(arg0, linkname, vap, target, cr, ct, flags));
2317 }
2318
2319 int
vnext_readlink(femarg_t * vf,uio_t * uiop,cred_t * cr,caller_context_t * ct)2320 vnext_readlink(femarg_t *vf, uio_t *uiop, cred_t *cr, caller_context_t *ct)
2321 {
2322 int (*func)() = NULL;
2323 void *arg0 = NULL;
2324
2325 ASSERT(vf != NULL);
2326 vf->fa_fnode--;
2327 vsop_find(vf, &func, int, &arg0, vop_readlink, femop_readlink);
2328 ASSERT(func != NULL);
2329 ASSERT(arg0 != NULL);
2330 return ((*func)(arg0, uiop, cr, ct));
2331 }
2332
2333 int
vnext_fsync(femarg_t * vf,int syncflag,cred_t * cr,caller_context_t * ct)2334 vnext_fsync(femarg_t *vf, int syncflag, cred_t *cr, caller_context_t *ct)
2335 {
2336 int (*func)() = NULL;
2337 void *arg0 = NULL;
2338
2339 ASSERT(vf != NULL);
2340 vf->fa_fnode--;
2341 vsop_find(vf, &func, int, &arg0, vop_fsync, femop_fsync);
2342 ASSERT(func != NULL);
2343 ASSERT(arg0 != NULL);
2344 return ((*func)(arg0, syncflag, cr, ct));
2345 }
2346
2347 void
vnext_inactive(femarg_t * vf,cred_t * cr,caller_context_t * ct)2348 vnext_inactive(femarg_t *vf, cred_t *cr, caller_context_t *ct)
2349 {
2350 void (*func)() = NULL;
2351 void *arg0 = NULL;
2352
2353 ASSERT(vf != NULL);
2354 vf->fa_fnode--;
2355 vsop_find(vf, &func, void, &arg0, vop_inactive, femop_inactive);
2356 ASSERT(func != NULL);
2357 ASSERT(arg0 != NULL);
2358 (*func)(arg0, cr, ct);
2359 }
2360
2361 int
vnext_fid(femarg_t * vf,fid_t * fidp,caller_context_t * ct)2362 vnext_fid(femarg_t *vf, fid_t *fidp, caller_context_t *ct)
2363 {
2364 int (*func)() = NULL;
2365 void *arg0 = NULL;
2366
2367 ASSERT(vf != NULL);
2368 vf->fa_fnode--;
2369 vsop_find(vf, &func, int, &arg0, vop_fid, femop_fid);
2370 ASSERT(func != NULL);
2371 ASSERT(arg0 != NULL);
2372 return ((*func)(arg0, fidp, ct));
2373 }
2374
2375 int
vnext_rwlock(femarg_t * vf,int write_lock,caller_context_t * ct)2376 vnext_rwlock(femarg_t *vf, int write_lock, caller_context_t *ct)
2377 {
2378 int (*func)() = NULL;
2379 void *arg0 = NULL;
2380
2381 ASSERT(vf != NULL);
2382 vf->fa_fnode--;
2383 vsop_find(vf, &func, int, &arg0, vop_rwlock, femop_rwlock);
2384 ASSERT(func != NULL);
2385 ASSERT(arg0 != NULL);
2386 return ((*func)(arg0, write_lock, ct));
2387 }
2388
2389 void
vnext_rwunlock(femarg_t * vf,int write_lock,caller_context_t * ct)2390 vnext_rwunlock(femarg_t *vf, int write_lock, caller_context_t *ct)
2391 {
2392 void (*func)() = NULL;
2393 void *arg0 = NULL;
2394
2395 ASSERT(vf != NULL);
2396 vf->fa_fnode--;
2397 vsop_find(vf, &