1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 29*7c478bd9Sstevel@tonic-gate #include <sys/atomic.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/mutex.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include <sys/fem.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define NNODES_DEFAULT 8 /* Default number of nodes in a fem_list */ 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * fl_ntob(n) - Fem_list: number of nodes to bytes 47*7c478bd9Sstevel@tonic-gate * Given the number of nodes in a fem_list return the size, in bytes, 48*7c478bd9Sstevel@tonic-gate * of the fem_list structure. 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate #define fl_ntob(n) (sizeof (struct fem_list) + \ 51*7c478bd9Sstevel@tonic-gate ((n) - 1) * sizeof (struct fem_node)) 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate typedef enum { 54*7c478bd9Sstevel@tonic-gate FEMTYPE_NULL, /* Uninitialized */ 55*7c478bd9Sstevel@tonic-gate FEMTYPE_VNODE, 56*7c478bd9Sstevel@tonic-gate FEMTYPE_VFS, 57*7c478bd9Sstevel@tonic-gate FEMTYPE_NTYPES 58*7c478bd9Sstevel@tonic-gate } femtype_t; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #define FEM_HEAD(_t) femtype[(_t)].head.fn_op.anon 61*7c478bd9Sstevel@tonic-gate #define FEM_GUARD(_t) femtype[(_t)].guard 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate static struct fem_type_info { 64*7c478bd9Sstevel@tonic-gate struct fem_node head; 65*7c478bd9Sstevel@tonic-gate struct fem_node guard; 66*7c478bd9Sstevel@tonic-gate femop_t *errf; 67*7c478bd9Sstevel@tonic-gate } femtype[FEMTYPE_NTYPES]; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * For each type, two tables - the translation offset definition, which 72*7c478bd9Sstevel@tonic-gate * is used by fs_build_vector to layout the operation(s) vector; and the 73*7c478bd9Sstevel@tonic-gate * guard_operation_vector which protects from stack under-run. 74*7c478bd9Sstevel@tonic-gate */ 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate int fem_err(); 77*7c478bd9Sstevel@tonic-gate int fsem_err(); 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate #define _FEMOPDEF(name, member) \ 81*7c478bd9Sstevel@tonic-gate { VOPNAME_##name, offsetof(fem_t, vsop_##member), NULL, fem_err } 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate static fs_operation_trans_def_t fem_opdef[] = { 84*7c478bd9Sstevel@tonic-gate _FEMOPDEF(OPEN, open), 85*7c478bd9Sstevel@tonic-gate _FEMOPDEF(CLOSE, close), 86*7c478bd9Sstevel@tonic-gate _FEMOPDEF(READ, read), 87*7c478bd9Sstevel@tonic-gate _FEMOPDEF(WRITE, write), 88*7c478bd9Sstevel@tonic-gate _FEMOPDEF(IOCTL, ioctl), 89*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SETFL, setfl), 90*7c478bd9Sstevel@tonic-gate _FEMOPDEF(GETATTR, getattr), 91*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SETATTR, setattr), 92*7c478bd9Sstevel@tonic-gate _FEMOPDEF(ACCESS, access), 93*7c478bd9Sstevel@tonic-gate _FEMOPDEF(LOOKUP, lookup), 94*7c478bd9Sstevel@tonic-gate _FEMOPDEF(CREATE, create), 95*7c478bd9Sstevel@tonic-gate _FEMOPDEF(REMOVE, remove), 96*7c478bd9Sstevel@tonic-gate _FEMOPDEF(LINK, link), 97*7c478bd9Sstevel@tonic-gate _FEMOPDEF(RENAME, rename), 98*7c478bd9Sstevel@tonic-gate _FEMOPDEF(MKDIR, mkdir), 99*7c478bd9Sstevel@tonic-gate _FEMOPDEF(RMDIR, rmdir), 100*7c478bd9Sstevel@tonic-gate _FEMOPDEF(READDIR, readdir), 101*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SYMLINK, symlink), 102*7c478bd9Sstevel@tonic-gate _FEMOPDEF(READLINK, readlink), 103*7c478bd9Sstevel@tonic-gate _FEMOPDEF(FSYNC, fsync), 104*7c478bd9Sstevel@tonic-gate _FEMOPDEF(INACTIVE, inactive), 105*7c478bd9Sstevel@tonic-gate _FEMOPDEF(FID, fid), 106*7c478bd9Sstevel@tonic-gate _FEMOPDEF(RWLOCK, rwlock), 107*7c478bd9Sstevel@tonic-gate _FEMOPDEF(RWUNLOCK, rwunlock), 108*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SEEK, seek), 109*7c478bd9Sstevel@tonic-gate _FEMOPDEF(CMP, cmp), 110*7c478bd9Sstevel@tonic-gate _FEMOPDEF(FRLOCK, frlock), 111*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SPACE, space), 112*7c478bd9Sstevel@tonic-gate _FEMOPDEF(REALVP, realvp), 113*7c478bd9Sstevel@tonic-gate _FEMOPDEF(GETPAGE, getpage), 114*7c478bd9Sstevel@tonic-gate _FEMOPDEF(PUTPAGE, putpage), 115*7c478bd9Sstevel@tonic-gate _FEMOPDEF(MAP, map), 116*7c478bd9Sstevel@tonic-gate _FEMOPDEF(ADDMAP, addmap), 117*7c478bd9Sstevel@tonic-gate _FEMOPDEF(DELMAP, delmap), 118*7c478bd9Sstevel@tonic-gate _FEMOPDEF(POLL, poll), 119*7c478bd9Sstevel@tonic-gate _FEMOPDEF(DUMP, dump), 120*7c478bd9Sstevel@tonic-gate _FEMOPDEF(PATHCONF, pathconf), 121*7c478bd9Sstevel@tonic-gate _FEMOPDEF(PAGEIO, pageio), 122*7c478bd9Sstevel@tonic-gate _FEMOPDEF(DUMPCTL, dumpctl), 123*7c478bd9Sstevel@tonic-gate _FEMOPDEF(DISPOSE, dispose), 124*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SETSECATTR, setsecattr), 125*7c478bd9Sstevel@tonic-gate _FEMOPDEF(GETSECATTR, getsecattr), 126*7c478bd9Sstevel@tonic-gate _FEMOPDEF(SHRLOCK, shrlock), 127*7c478bd9Sstevel@tonic-gate _FEMOPDEF(VNEVENT, vnevent), 128*7c478bd9Sstevel@tonic-gate { NULL, 0, NULL, NULL } 129*7c478bd9Sstevel@tonic-gate }; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate #define _FEMGUARD(name, ignore) \ 133*7c478bd9Sstevel@tonic-gate { VOPNAME_##name, (femop_t *)fem_err } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate static struct fs_operation_def fem_guard_ops[] = { 136*7c478bd9Sstevel@tonic-gate _FEMGUARD(OPEN, open), 137*7c478bd9Sstevel@tonic-gate _FEMGUARD(CLOSE, close), 138*7c478bd9Sstevel@tonic-gate _FEMGUARD(READ, read), 139*7c478bd9Sstevel@tonic-gate _FEMGUARD(WRITE, write), 140*7c478bd9Sstevel@tonic-gate _FEMGUARD(IOCTL, ioctl), 141*7c478bd9Sstevel@tonic-gate _FEMGUARD(SETFL, setfl), 142*7c478bd9Sstevel@tonic-gate _FEMGUARD(GETATTR, getattr), 143*7c478bd9Sstevel@tonic-gate _FEMGUARD(SETATTR, setattr), 144*7c478bd9Sstevel@tonic-gate _FEMGUARD(ACCESS, access), 145*7c478bd9Sstevel@tonic-gate _FEMGUARD(LOOKUP, lookup), 146*7c478bd9Sstevel@tonic-gate _FEMGUARD(CREATE, create), 147*7c478bd9Sstevel@tonic-gate _FEMGUARD(REMOVE, remove), 148*7c478bd9Sstevel@tonic-gate _FEMGUARD(LINK, link), 149*7c478bd9Sstevel@tonic-gate _FEMGUARD(RENAME, rename), 150*7c478bd9Sstevel@tonic-gate _FEMGUARD(MKDIR, mkdir), 151*7c478bd9Sstevel@tonic-gate _FEMGUARD(RMDIR, rmdir), 152*7c478bd9Sstevel@tonic-gate _FEMGUARD(READDIR, readdir), 153*7c478bd9Sstevel@tonic-gate _FEMGUARD(SYMLINK, symlink), 154*7c478bd9Sstevel@tonic-gate _FEMGUARD(READLINK, readlink), 155*7c478bd9Sstevel@tonic-gate _FEMGUARD(FSYNC, fsync), 156*7c478bd9Sstevel@tonic-gate _FEMGUARD(INACTIVE, inactive), 157*7c478bd9Sstevel@tonic-gate _FEMGUARD(FID, fid), 158*7c478bd9Sstevel@tonic-gate _FEMGUARD(RWLOCK, rwlock), 159*7c478bd9Sstevel@tonic-gate _FEMGUARD(RWUNLOCK, rwunlock), 160*7c478bd9Sstevel@tonic-gate _FEMGUARD(SEEK, seek), 161*7c478bd9Sstevel@tonic-gate _FEMGUARD(CMP, cmp), 162*7c478bd9Sstevel@tonic-gate _FEMGUARD(FRLOCK, frlock), 163*7c478bd9Sstevel@tonic-gate _FEMGUARD(SPACE, space), 164*7c478bd9Sstevel@tonic-gate _FEMGUARD(REALVP, realvp), 165*7c478bd9Sstevel@tonic-gate _FEMGUARD(GETPAGE, getpage), 166*7c478bd9Sstevel@tonic-gate _FEMGUARD(PUTPAGE, putpage), 167*7c478bd9Sstevel@tonic-gate _FEMGUARD(MAP, map), 168*7c478bd9Sstevel@tonic-gate _FEMGUARD(ADDMAP, addmap), 169*7c478bd9Sstevel@tonic-gate _FEMGUARD(DELMAP, delmap), 170*7c478bd9Sstevel@tonic-gate _FEMGUARD(POLL, poll), 171*7c478bd9Sstevel@tonic-gate _FEMGUARD(DUMP, dump), 172*7c478bd9Sstevel@tonic-gate _FEMGUARD(PATHCONF, pathconf), 173*7c478bd9Sstevel@tonic-gate _FEMGUARD(PAGEIO, pageio), 174*7c478bd9Sstevel@tonic-gate _FEMGUARD(DUMPCTL, dumpctl), 175*7c478bd9Sstevel@tonic-gate _FEMGUARD(DISPOSE, dispose), 176*7c478bd9Sstevel@tonic-gate _FEMGUARD(SETSECATTR, setsecattr), 177*7c478bd9Sstevel@tonic-gate _FEMGUARD(GETSECATTR, getsecattr), 178*7c478bd9Sstevel@tonic-gate _FEMGUARD(SHRLOCK, shrlock), 179*7c478bd9Sstevel@tonic-gate _FEMGUARD(VNEVENT, vnevent), 180*7c478bd9Sstevel@tonic-gate { NULL, NULL } 181*7c478bd9Sstevel@tonic-gate }; 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate #define _FSEMOPDEF(name, member) \ 185*7c478bd9Sstevel@tonic-gate { VFSNAME_##name, offsetof(fsem_t, vfsop_##member), NULL, fsem_err } 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate static fs_operation_trans_def_t fsem_opdef[] = { 188*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(MOUNT, mount), 189*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(UNMOUNT, unmount), 190*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(ROOT, root), 191*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(STATVFS, statvfs), 192*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(SYNC, sync), 193*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(VGET, vget), 194*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(MOUNTROOT, mountroot), 195*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(FREEVFS, freevfs), 196*7c478bd9Sstevel@tonic-gate _FSEMOPDEF(VNSTATE, vnstate), 197*7c478bd9Sstevel@tonic-gate { NULL, 0, NULL, NULL } 198*7c478bd9Sstevel@tonic-gate }; 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate #define _FSEMGUARD(name, ignore) \ 201*7c478bd9Sstevel@tonic-gate { VFSNAME_##name, (femop_t *)fsem_err } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate static struct fs_operation_def fsem_guard_ops[] = { 204*7c478bd9Sstevel@tonic-gate _FSEMGUARD(MOUNT, mount), 205*7c478bd9Sstevel@tonic-gate _FSEMGUARD(UNMOUNT, unmount), 206*7c478bd9Sstevel@tonic-gate _FSEMGUARD(ROOT, root), 207*7c478bd9Sstevel@tonic-gate _FSEMGUARD(STATVFS, statvfs), 208*7c478bd9Sstevel@tonic-gate _FSEMGUARD(SYNC, sync), 209*7c478bd9Sstevel@tonic-gate _FSEMGUARD(VGET, vget), 210*7c478bd9Sstevel@tonic-gate _FSEMGUARD(MOUNTROOT, mountroot), 211*7c478bd9Sstevel@tonic-gate _FSEMGUARD(FREEVFS, freevfs), 212*7c478bd9Sstevel@tonic-gate _FSEMGUARD(VNSTATE, vnstate), 213*7c478bd9Sstevel@tonic-gate { NULL, NULL} 214*7c478bd9Sstevel@tonic-gate }; 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* 218*7c478bd9Sstevel@tonic-gate * vsop_find, vfsop_find - 219*7c478bd9Sstevel@tonic-gate * 220*7c478bd9Sstevel@tonic-gate * These macros descend the stack until they find either a basic 221*7c478bd9Sstevel@tonic-gate * vnode/vfs operation [ indicated by a null fn_available ] or a 222*7c478bd9Sstevel@tonic-gate * stacked item where this method is non-null [_vsop]. 223*7c478bd9Sstevel@tonic-gate * 224*7c478bd9Sstevel@tonic-gate * The DEBUG one is written with a single function which manually applies 225*7c478bd9Sstevel@tonic-gate * the structure offsets. It can have additional debugging support. 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate #ifndef DEBUG 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate #define vsop_find(ap, func, funct, arg0, _vop, _vsop) \ 231*7c478bd9Sstevel@tonic-gate for (;;) { \ 232*7c478bd9Sstevel@tonic-gate if ((ap)->fa_fnode->fn_available == NULL) { \ 233*7c478bd9Sstevel@tonic-gate *(func) = (funct (*)())((ap)->fa_fnode->fn_op.vnode->_vop); \ 234*7c478bd9Sstevel@tonic-gate *(arg0) = (void *)(ap)->fa_vnode.vp; \ 235*7c478bd9Sstevel@tonic-gate break; \ 236*7c478bd9Sstevel@tonic-gate } else if ((*(func) = (funct (*)())((ap)->fa_fnode->fn_op.fem->_vsop))\ 237*7c478bd9Sstevel@tonic-gate != NULL) { \ 238*7c478bd9Sstevel@tonic-gate *(arg0) = (void *) (ap); \ 239*7c478bd9Sstevel@tonic-gate break; \ 240*7c478bd9Sstevel@tonic-gate } else { \ 241*7c478bd9Sstevel@tonic-gate (ap)->fa_fnode--; \ 242*7c478bd9Sstevel@tonic-gate } \ 243*7c478bd9Sstevel@tonic-gate } \ 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate #define vfsop_find(ap, func, funct, arg0, _vop, _vsop) \ 246*7c478bd9Sstevel@tonic-gate for (;;) { \ 247*7c478bd9Sstevel@tonic-gate if ((ap)->fa_fnode->fn_available == NULL) { \ 248*7c478bd9Sstevel@tonic-gate *(func) = (funct (*)())((ap)->fa_fnode->fn_op.vfs->_vop); \ 249*7c478bd9Sstevel@tonic-gate *(arg0) = (void *)(ap)->fa_vnode.vp; \ 250*7c478bd9Sstevel@tonic-gate break; \ 251*7c478bd9Sstevel@tonic-gate } else if ((*(func) = (funct (*)())((ap)->fa_fnode->fn_op.fsem->_vsop))\ 252*7c478bd9Sstevel@tonic-gate != NULL) { \ 253*7c478bd9Sstevel@tonic-gate *(arg0) = (void *) (ap); \ 254*7c478bd9Sstevel@tonic-gate break; \ 255*7c478bd9Sstevel@tonic-gate } else { \ 256*7c478bd9Sstevel@tonic-gate (ap)->fa_fnode--; \ 257*7c478bd9Sstevel@tonic-gate } \ 258*7c478bd9Sstevel@tonic-gate } \ 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate #else 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate #define vsop_find(ap, func, funct, arg0, _vop, _vsop) \ 263*7c478bd9Sstevel@tonic-gate *(arg0) = _op_find((ap), (void **)(func), \ 264*7c478bd9Sstevel@tonic-gate offsetof(vnodeops_t, _vop), offsetof(fem_t, _vsop)) 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate #define vfsop_find(ap, func, funct, arg0, _fop, _fsop) \ 267*7c478bd9Sstevel@tonic-gate *(arg0) = _op_find((ap), (void **)(func), \ 268*7c478bd9Sstevel@tonic-gate offsetof(vfsops_t, _fop), offsetof(fsem_t, _fsop)) 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate static void * 271*7c478bd9Sstevel@tonic-gate _op_find(femarg_t *ap, void **fp, int offs0, int offs1) 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate void *ptr; 274*7c478bd9Sstevel@tonic-gate for (;;) { 275*7c478bd9Sstevel@tonic-gate struct fem_node *fnod = ap->fa_fnode; 276*7c478bd9Sstevel@tonic-gate if (fnod->fn_available == NULL) { 277*7c478bd9Sstevel@tonic-gate *fp = *(void **)((char *)fnod->fn_op.anon + offs0); 278*7c478bd9Sstevel@tonic-gate ptr = (void *)(ap->fa_vnode.anon); 279*7c478bd9Sstevel@tonic-gate break; 280*7c478bd9Sstevel@tonic-gate } else if ((*fp = *(void **)((char *)fnod->fn_op.anon+offs1)) 281*7c478bd9Sstevel@tonic-gate != NULL) { 282*7c478bd9Sstevel@tonic-gate ptr = (void *)(ap); 283*7c478bd9Sstevel@tonic-gate break; 284*7c478bd9Sstevel@tonic-gate } else { 285*7c478bd9Sstevel@tonic-gate ap->fa_fnode--; 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate return (ptr); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate #endif 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate static fem_t * 293*7c478bd9Sstevel@tonic-gate fem_alloc() 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate fem_t *p; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate p = (fem_t *)kmem_alloc(sizeof (*p), KM_SLEEP); 298*7c478bd9Sstevel@tonic-gate return (p); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate void 302*7c478bd9Sstevel@tonic-gate fem_free(fem_t *p) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate kmem_free(p, sizeof (*p)); 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate static fsem_t * 308*7c478bd9Sstevel@tonic-gate fsem_alloc() 309*7c478bd9Sstevel@tonic-gate { 310*7c478bd9Sstevel@tonic-gate fsem_t *p; 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate p = (fsem_t *)kmem_alloc(sizeof (*p), KM_SLEEP); 313*7c478bd9Sstevel@tonic-gate return (p); 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate void 317*7c478bd9Sstevel@tonic-gate fsem_free(fsem_t *p) 318*7c478bd9Sstevel@tonic-gate { 319*7c478bd9Sstevel@tonic-gate kmem_free(p, sizeof (*p)); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate /* 324*7c478bd9Sstevel@tonic-gate * fem_get, fem_release - manage reference counts on the stack. 325*7c478bd9Sstevel@tonic-gate * 326*7c478bd9Sstevel@tonic-gate * The list of monitors can be updated while operations are in 327*7c478bd9Sstevel@tonic-gate * progress on the object. 328*7c478bd9Sstevel@tonic-gate * 329*7c478bd9Sstevel@tonic-gate * The reference count facilitates this by counting the number of 330*7c478bd9Sstevel@tonic-gate * current accessors, and deconstructing the list when it is exhausted. 331*7c478bd9Sstevel@tonic-gate * 332*7c478bd9Sstevel@tonic-gate * fem_lock() is required to: 333*7c478bd9Sstevel@tonic-gate * look at femh_list 334*7c478bd9Sstevel@tonic-gate * update what femh_list points to 335*7c478bd9Sstevel@tonic-gate * update femh_list 336*7c478bd9Sstevel@tonic-gate * increase femh_list->feml_refc. 337*7c478bd9Sstevel@tonic-gate * 338*7c478bd9Sstevel@tonic-gate * the feml_refc can decrement without holding the lock; 339*7c478bd9Sstevel@tonic-gate * when feml_refc becomes zero, the list is destroyed. 340*7c478bd9Sstevel@tonic-gate * 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate static struct fem_list * 344*7c478bd9Sstevel@tonic-gate fem_lock(struct fem_head *fp) 345*7c478bd9Sstevel@tonic-gate { 346*7c478bd9Sstevel@tonic-gate struct fem_list *sp = NULL; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate ASSERT(fp != NULL); 349*7c478bd9Sstevel@tonic-gate mutex_enter(&fp->femh_lock); 350*7c478bd9Sstevel@tonic-gate sp = fp->femh_list; 351*7c478bd9Sstevel@tonic-gate return (sp); 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate static void 355*7c478bd9Sstevel@tonic-gate fem_unlock(struct fem_head *fp) 356*7c478bd9Sstevel@tonic-gate { 357*7c478bd9Sstevel@tonic-gate ASSERT(fp != NULL); 358*7c478bd9Sstevel@tonic-gate mutex_exit(&fp->femh_lock); 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* 362*7c478bd9Sstevel@tonic-gate * Addref can only be called while its head->lock is held. 363*7c478bd9Sstevel@tonic-gate */ 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate static void 366*7c478bd9Sstevel@tonic-gate fem_addref(struct fem_list *sp) 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate atomic_add_32(&sp->feml_refc, 1); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate static void 372*7c478bd9Sstevel@tonic-gate fem_delref(struct fem_list *sp) 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate (void) atomic_add_32_nv(&sp->feml_refc, -1); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate static struct fem_list * 378*7c478bd9Sstevel@tonic-gate fem_get(struct fem_head *fp) 379*7c478bd9Sstevel@tonic-gate { 380*7c478bd9Sstevel@tonic-gate struct fem_list *sp = NULL; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate if (fp != NULL) { 383*7c478bd9Sstevel@tonic-gate if ((sp = fem_lock(fp)) != NULL) { 384*7c478bd9Sstevel@tonic-gate fem_addref(sp); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate fem_unlock(fp); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate return (sp); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate static void 392*7c478bd9Sstevel@tonic-gate fem_release(struct fem_list *sp) 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate int i; 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate if (sp->feml_refc != 0) { 397*7c478bd9Sstevel@tonic-gate fem_delref(sp); 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate if (sp->feml_refc == 0) { 400*7c478bd9Sstevel@tonic-gate /* 401*7c478bd9Sstevel@tonic-gate * Before freeing the list, we need to release the 402*7c478bd9Sstevel@tonic-gate * caller-provided data. 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate for (i = sp->feml_tos; i > 0; i--) { 405*7c478bd9Sstevel@tonic-gate struct fem_node *fnp = &sp->feml_nodes[i]; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate if (fnp->fn_av_rele) 408*7c478bd9Sstevel@tonic-gate (*(fnp->fn_av_rele))(fnp->fn_available); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate kmem_free(sp, fl_ntob(sp->feml_ssize)); 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate /* 416*7c478bd9Sstevel@tonic-gate * These are the 'head' operations which perform the interposition. 417*7c478bd9Sstevel@tonic-gate * 418*7c478bd9Sstevel@tonic-gate * This set must be 1:1, onto with the (vnodeops, vfsos). 419*7c478bd9Sstevel@tonic-gate * 420*7c478bd9Sstevel@tonic-gate * If there is a desire to globally disable interposition for a particular 421*7c478bd9Sstevel@tonic-gate * method, the corresponding 'head' routine should unearth the base method 422*7c478bd9Sstevel@tonic-gate * and invoke it directly rather than bypassing the function. 423*7c478bd9Sstevel@tonic-gate * 424*7c478bd9Sstevel@tonic-gate * All the functions are virtually the same, save for names, types & args. 425*7c478bd9Sstevel@tonic-gate * 1. get a reference to the monitor stack for this object. 426*7c478bd9Sstevel@tonic-gate * 2. store the top of stack into the femarg structure. 427*7c478bd9Sstevel@tonic-gate * 3. store the basic object (vnode *, vnode **, vfs *) in the femarg struc. 428*7c478bd9Sstevel@tonic-gate * 4. invoke the "top" method for this object. 429*7c478bd9Sstevel@tonic-gate * 5. release the reference to the monitor stack. 430*7c478bd9Sstevel@tonic-gate * 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate static int 434*7c478bd9Sstevel@tonic-gate vhead_open(vnode_t **vpp, int mode, cred_t *cr) 435*7c478bd9Sstevel@tonic-gate { 436*7c478bd9Sstevel@tonic-gate femarg_t farg; 437*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 438*7c478bd9Sstevel@tonic-gate int (*func)(); 439*7c478bd9Sstevel@tonic-gate void *arg0; 440*7c478bd9Sstevel@tonic-gate int errc; 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock((*vpp)->v_femhead)) == NULL) { 443*7c478bd9Sstevel@tonic-gate func = (int (*)()) ((*vpp)->v_op->vop_open); 444*7c478bd9Sstevel@tonic-gate arg0 = (void *)vpp; 445*7c478bd9Sstevel@tonic-gate fem_unlock((*vpp)->v_femhead); 446*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, mode, cr); 447*7c478bd9Sstevel@tonic-gate } else { 448*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 449*7c478bd9Sstevel@tonic-gate fem_unlock((*vpp)->v_femhead); 450*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vpp = vpp; 451*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 452*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_open, vsop_open); 453*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, mode, cr); 454*7c478bd9Sstevel@tonic-gate fem_release(femsp); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate return (errc); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate static int 460*7c478bd9Sstevel@tonic-gate vhead_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr) 461*7c478bd9Sstevel@tonic-gate { 462*7c478bd9Sstevel@tonic-gate femarg_t farg; 463*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 464*7c478bd9Sstevel@tonic-gate int (*func)(); 465*7c478bd9Sstevel@tonic-gate void *arg0; 466*7c478bd9Sstevel@tonic-gate int errc; 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 469*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_close); 470*7c478bd9Sstevel@tonic-gate arg0 = vp; 471*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 472*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, flag, count, offset, cr); 473*7c478bd9Sstevel@tonic-gate } else { 474*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 475*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 476*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 477*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 478*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_close, vsop_close); 479*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, flag, count, offset, cr); 480*7c478bd9Sstevel@tonic-gate fem_release(femsp); 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate return (errc); 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate static int 486*7c478bd9Sstevel@tonic-gate vhead_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, 487*7c478bd9Sstevel@tonic-gate struct caller_context *ct) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate femarg_t farg; 490*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 491*7c478bd9Sstevel@tonic-gate int (*func)(); 492*7c478bd9Sstevel@tonic-gate void *arg0; 493*7c478bd9Sstevel@tonic-gate int errc; 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 496*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_read); 497*7c478bd9Sstevel@tonic-gate arg0 = vp; 498*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 499*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, ioflag, cr, ct); 500*7c478bd9Sstevel@tonic-gate } else { 501*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 502*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 503*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 504*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 505*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_read, vsop_read); 506*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, ioflag, cr, ct); 507*7c478bd9Sstevel@tonic-gate fem_release(femsp); 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate return (errc); 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate static int 513*7c478bd9Sstevel@tonic-gate vhead_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr, 514*7c478bd9Sstevel@tonic-gate struct caller_context *ct) 515*7c478bd9Sstevel@tonic-gate { 516*7c478bd9Sstevel@tonic-gate femarg_t farg; 517*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 518*7c478bd9Sstevel@tonic-gate int (*func)(); 519*7c478bd9Sstevel@tonic-gate void *arg0; 520*7c478bd9Sstevel@tonic-gate int errc; 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 523*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_write); 524*7c478bd9Sstevel@tonic-gate arg0 = vp; 525*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 526*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, ioflag, cr, ct); 527*7c478bd9Sstevel@tonic-gate } else { 528*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 529*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 530*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 531*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 532*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_write, vsop_write); 533*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, ioflag, cr, ct); 534*7c478bd9Sstevel@tonic-gate fem_release(femsp); 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate return (errc); 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate static int 540*7c478bd9Sstevel@tonic-gate vhead_ioctl(vnode_t *vp, int cmd, intptr_t arg, int flag, cred_t *cr, 541*7c478bd9Sstevel@tonic-gate int *rvalp) 542*7c478bd9Sstevel@tonic-gate { 543*7c478bd9Sstevel@tonic-gate femarg_t farg; 544*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 545*7c478bd9Sstevel@tonic-gate int (*func)(); 546*7c478bd9Sstevel@tonic-gate void *arg0; 547*7c478bd9Sstevel@tonic-gate int errc; 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 550*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_ioctl); 551*7c478bd9Sstevel@tonic-gate arg0 = vp; 552*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 553*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, arg, flag, cr, rvalp); 554*7c478bd9Sstevel@tonic-gate } else { 555*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 556*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 557*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 558*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 559*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_ioctl, vsop_ioctl); 560*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, arg, flag, cr, rvalp); 561*7c478bd9Sstevel@tonic-gate fem_release(femsp); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate return (errc); 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate static int 567*7c478bd9Sstevel@tonic-gate vhead_setfl(vnode_t *vp, int oflags, int nflags, cred_t *cr) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate femarg_t farg; 570*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 571*7c478bd9Sstevel@tonic-gate int (*func)(); 572*7c478bd9Sstevel@tonic-gate void *arg0; 573*7c478bd9Sstevel@tonic-gate int errc; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 576*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_setfl); 577*7c478bd9Sstevel@tonic-gate arg0 = vp; 578*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 579*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, oflags, nflags, cr); 580*7c478bd9Sstevel@tonic-gate } else { 581*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 582*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 583*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 584*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 585*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_setfl, vsop_setfl); 586*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, oflags, nflags, cr); 587*7c478bd9Sstevel@tonic-gate fem_release(femsp); 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate return (errc); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate static int 593*7c478bd9Sstevel@tonic-gate vhead_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr) 594*7c478bd9Sstevel@tonic-gate { 595*7c478bd9Sstevel@tonic-gate femarg_t farg; 596*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 597*7c478bd9Sstevel@tonic-gate int (*func)(); 598*7c478bd9Sstevel@tonic-gate void *arg0; 599*7c478bd9Sstevel@tonic-gate int errc; 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 602*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_getattr); 603*7c478bd9Sstevel@tonic-gate arg0 = vp; 604*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 605*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vap, flags, cr); 606*7c478bd9Sstevel@tonic-gate } else { 607*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 608*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 609*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 610*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 611*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_getattr, 612*7c478bd9Sstevel@tonic-gate vsop_getattr); 613*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vap, flags, cr); 614*7c478bd9Sstevel@tonic-gate fem_release(femsp); 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate return (errc); 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate static int 620*7c478bd9Sstevel@tonic-gate vhead_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, 621*7c478bd9Sstevel@tonic-gate caller_context_t *ct) 622*7c478bd9Sstevel@tonic-gate { 623*7c478bd9Sstevel@tonic-gate femarg_t farg; 624*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 625*7c478bd9Sstevel@tonic-gate int (*func)(); 626*7c478bd9Sstevel@tonic-gate void *arg0; 627*7c478bd9Sstevel@tonic-gate int errc; 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 630*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_setattr); 631*7c478bd9Sstevel@tonic-gate arg0 = vp; 632*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 633*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vap, flags, cr, ct); 634*7c478bd9Sstevel@tonic-gate } else { 635*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 636*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 637*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 638*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 639*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_setattr, 640*7c478bd9Sstevel@tonic-gate vsop_setattr); 641*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vap, flags, cr, ct); 642*7c478bd9Sstevel@tonic-gate fem_release(femsp); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate return (errc); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate 647*7c478bd9Sstevel@tonic-gate static int 648*7c478bd9Sstevel@tonic-gate vhead_access(vnode_t *vp, int mode, int flags, cred_t *cr) 649*7c478bd9Sstevel@tonic-gate { 650*7c478bd9Sstevel@tonic-gate femarg_t farg; 651*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 652*7c478bd9Sstevel@tonic-gate int (*func)(); 653*7c478bd9Sstevel@tonic-gate void *arg0; 654*7c478bd9Sstevel@tonic-gate int errc; 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 657*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_access); 658*7c478bd9Sstevel@tonic-gate arg0 = vp; 659*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 660*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, mode, flags, cr); 661*7c478bd9Sstevel@tonic-gate } else { 662*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 663*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 664*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 665*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 666*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_access, 667*7c478bd9Sstevel@tonic-gate vsop_access); 668*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, mode, flags, cr); 669*7c478bd9Sstevel@tonic-gate fem_release(femsp); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate return (errc); 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate static int 675*7c478bd9Sstevel@tonic-gate vhead_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, 676*7c478bd9Sstevel@tonic-gate int flags, vnode_t *rdir, cred_t *cr) 677*7c478bd9Sstevel@tonic-gate { 678*7c478bd9Sstevel@tonic-gate femarg_t farg; 679*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 680*7c478bd9Sstevel@tonic-gate int (*func)(); 681*7c478bd9Sstevel@tonic-gate void *arg0; 682*7c478bd9Sstevel@tonic-gate int errc; 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 685*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_lookup); 686*7c478bd9Sstevel@tonic-gate arg0 = dvp; 687*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 688*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, vpp, pnp, flags, rdir, cr); 689*7c478bd9Sstevel@tonic-gate } else { 690*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 691*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 692*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 693*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 694*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_lookup, 695*7c478bd9Sstevel@tonic-gate vsop_lookup); 696*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, vpp, pnp, flags, rdir, cr); 697*7c478bd9Sstevel@tonic-gate fem_release(femsp); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate return (errc); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate static int 703*7c478bd9Sstevel@tonic-gate vhead_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl, 704*7c478bd9Sstevel@tonic-gate int mode, vnode_t **vpp, cred_t *cr, int flag) 705*7c478bd9Sstevel@tonic-gate { 706*7c478bd9Sstevel@tonic-gate femarg_t farg; 707*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 708*7c478bd9Sstevel@tonic-gate int (*func)(); 709*7c478bd9Sstevel@tonic-gate void *arg0; 710*7c478bd9Sstevel@tonic-gate int errc; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 713*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_create); 714*7c478bd9Sstevel@tonic-gate arg0 = dvp; 715*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 716*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, name, vap, excl, mode, vpp, cr, flag); 717*7c478bd9Sstevel@tonic-gate } else { 718*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 719*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 720*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 721*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 722*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_create, 723*7c478bd9Sstevel@tonic-gate vsop_create); 724*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, name, vap, excl, mode, vpp, cr, flag); 725*7c478bd9Sstevel@tonic-gate fem_release(femsp); 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate return (errc); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate static int 731*7c478bd9Sstevel@tonic-gate vhead_remove(vnode_t *dvp, char *nm, cred_t *cr) 732*7c478bd9Sstevel@tonic-gate { 733*7c478bd9Sstevel@tonic-gate femarg_t farg; 734*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 735*7c478bd9Sstevel@tonic-gate int (*func)(); 736*7c478bd9Sstevel@tonic-gate void *arg0; 737*7c478bd9Sstevel@tonic-gate int errc; 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 740*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_remove); 741*7c478bd9Sstevel@tonic-gate arg0 = dvp; 742*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 743*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, cr); 744*7c478bd9Sstevel@tonic-gate } else { 745*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 746*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 747*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 748*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 749*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_remove, 750*7c478bd9Sstevel@tonic-gate vsop_remove); 751*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, cr); 752*7c478bd9Sstevel@tonic-gate fem_release(femsp); 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate return (errc); 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate static int 758*7c478bd9Sstevel@tonic-gate vhead_link(vnode_t *tdvp, vnode_t *svp, char *tnm, cred_t *cr) 759*7c478bd9Sstevel@tonic-gate { 760*7c478bd9Sstevel@tonic-gate femarg_t farg; 761*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 762*7c478bd9Sstevel@tonic-gate int (*func)(); 763*7c478bd9Sstevel@tonic-gate void *arg0; 764*7c478bd9Sstevel@tonic-gate int errc; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(tdvp->v_femhead)) == NULL) { 767*7c478bd9Sstevel@tonic-gate func = (int (*)()) (tdvp->v_op->vop_link); 768*7c478bd9Sstevel@tonic-gate arg0 = tdvp; 769*7c478bd9Sstevel@tonic-gate fem_unlock(tdvp->v_femhead); 770*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, svp, tnm, cr); 771*7c478bd9Sstevel@tonic-gate } else { 772*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 773*7c478bd9Sstevel@tonic-gate fem_unlock(tdvp->v_femhead); 774*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = tdvp; 775*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 776*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_link, vsop_link); 777*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, svp, tnm, cr); 778*7c478bd9Sstevel@tonic-gate fem_release(femsp); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate return (errc); 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate static int 784*7c478bd9Sstevel@tonic-gate vhead_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, 785*7c478bd9Sstevel@tonic-gate cred_t *cr) 786*7c478bd9Sstevel@tonic-gate { 787*7c478bd9Sstevel@tonic-gate femarg_t farg; 788*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 789*7c478bd9Sstevel@tonic-gate int (*func)(); 790*7c478bd9Sstevel@tonic-gate void *arg0; 791*7c478bd9Sstevel@tonic-gate int errc; 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(sdvp->v_femhead)) == NULL) { 794*7c478bd9Sstevel@tonic-gate func = (int (*)()) (sdvp->v_op->vop_rename); 795*7c478bd9Sstevel@tonic-gate arg0 = sdvp; 796*7c478bd9Sstevel@tonic-gate fem_unlock(sdvp->v_femhead); 797*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, snm, tdvp, tnm, cr); 798*7c478bd9Sstevel@tonic-gate } else { 799*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 800*7c478bd9Sstevel@tonic-gate fem_unlock(sdvp->v_femhead); 801*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = sdvp; 802*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 803*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_rename, 804*7c478bd9Sstevel@tonic-gate vsop_rename); 805*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, snm, tdvp, tnm, cr); 806*7c478bd9Sstevel@tonic-gate fem_release(femsp); 807*7c478bd9Sstevel@tonic-gate } 808*7c478bd9Sstevel@tonic-gate return (errc); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate static int 812*7c478bd9Sstevel@tonic-gate vhead_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, 813*7c478bd9Sstevel@tonic-gate cred_t *cr) 814*7c478bd9Sstevel@tonic-gate { 815*7c478bd9Sstevel@tonic-gate femarg_t farg; 816*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 817*7c478bd9Sstevel@tonic-gate int (*func)(); 818*7c478bd9Sstevel@tonic-gate void *arg0; 819*7c478bd9Sstevel@tonic-gate int errc; 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 822*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_mkdir); 823*7c478bd9Sstevel@tonic-gate arg0 = dvp; 824*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 825*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, dirname, vap, vpp, cr); 826*7c478bd9Sstevel@tonic-gate } else { 827*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 828*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 829*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 830*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 831*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_mkdir, vsop_mkdir); 832*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, dirname, vap, vpp, cr); 833*7c478bd9Sstevel@tonic-gate fem_release(femsp); 834*7c478bd9Sstevel@tonic-gate } 835*7c478bd9Sstevel@tonic-gate return (errc); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate 838*7c478bd9Sstevel@tonic-gate static int 839*7c478bd9Sstevel@tonic-gate vhead_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cr) 840*7c478bd9Sstevel@tonic-gate { 841*7c478bd9Sstevel@tonic-gate femarg_t farg; 842*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 843*7c478bd9Sstevel@tonic-gate int (*func)(); 844*7c478bd9Sstevel@tonic-gate void *arg0; 845*7c478bd9Sstevel@tonic-gate int errc; 846*7c478bd9Sstevel@tonic-gate 847*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 848*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_rmdir); 849*7c478bd9Sstevel@tonic-gate arg0 = dvp; 850*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 851*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, cdir, cr); 852*7c478bd9Sstevel@tonic-gate } else { 853*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 854*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 855*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 856*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 857*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_rmdir, vsop_rmdir); 858*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, nm, cdir, cr); 859*7c478bd9Sstevel@tonic-gate fem_release(femsp); 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate return (errc); 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate static int 865*7c478bd9Sstevel@tonic-gate vhead_readdir(vnode_t *vp, uio_t *uiop, cred_t *cr, int *eofp) 866*7c478bd9Sstevel@tonic-gate { 867*7c478bd9Sstevel@tonic-gate femarg_t farg; 868*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 869*7c478bd9Sstevel@tonic-gate int (*func)(); 870*7c478bd9Sstevel@tonic-gate void *arg0; 871*7c478bd9Sstevel@tonic-gate int errc; 872*7c478bd9Sstevel@tonic-gate 873*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 874*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_readdir); 875*7c478bd9Sstevel@tonic-gate arg0 = vp; 876*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 877*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, cr, eofp); 878*7c478bd9Sstevel@tonic-gate } else { 879*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 880*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 881*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 882*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 883*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_readdir, 884*7c478bd9Sstevel@tonic-gate vsop_readdir); 885*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, cr, eofp); 886*7c478bd9Sstevel@tonic-gate fem_release(femsp); 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate return (errc); 889*7c478bd9Sstevel@tonic-gate } 890*7c478bd9Sstevel@tonic-gate 891*7c478bd9Sstevel@tonic-gate static int 892*7c478bd9Sstevel@tonic-gate vhead_symlink(vnode_t *dvp, char *linkname, vattr_t *vap, char *target, 893*7c478bd9Sstevel@tonic-gate cred_t *cr) 894*7c478bd9Sstevel@tonic-gate { 895*7c478bd9Sstevel@tonic-gate femarg_t farg; 896*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 897*7c478bd9Sstevel@tonic-gate int (*func)(); 898*7c478bd9Sstevel@tonic-gate void *arg0; 899*7c478bd9Sstevel@tonic-gate int errc; 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(dvp->v_femhead)) == NULL) { 902*7c478bd9Sstevel@tonic-gate func = (int (*)()) (dvp->v_op->vop_symlink); 903*7c478bd9Sstevel@tonic-gate arg0 = dvp; 904*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 905*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, linkname, vap, target, cr); 906*7c478bd9Sstevel@tonic-gate } else { 907*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 908*7c478bd9Sstevel@tonic-gate fem_unlock(dvp->v_femhead); 909*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = dvp; 910*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 911*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_symlink, 912*7c478bd9Sstevel@tonic-gate vsop_symlink); 913*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, linkname, vap, target, cr); 914*7c478bd9Sstevel@tonic-gate fem_release(femsp); 915*7c478bd9Sstevel@tonic-gate } 916*7c478bd9Sstevel@tonic-gate return (errc); 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate 919*7c478bd9Sstevel@tonic-gate static int 920*7c478bd9Sstevel@tonic-gate vhead_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr) 921*7c478bd9Sstevel@tonic-gate { 922*7c478bd9Sstevel@tonic-gate femarg_t farg; 923*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 924*7c478bd9Sstevel@tonic-gate int (*func)(); 925*7c478bd9Sstevel@tonic-gate void *arg0; 926*7c478bd9Sstevel@tonic-gate int errc; 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 929*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_readlink); 930*7c478bd9Sstevel@tonic-gate arg0 = vp; 931*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 932*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, cr); 933*7c478bd9Sstevel@tonic-gate } else { 934*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 935*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 936*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 937*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 938*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_readlink, 939*7c478bd9Sstevel@tonic-gate vsop_readlink); 940*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, uiop, cr); 941*7c478bd9Sstevel@tonic-gate fem_release(femsp); 942*7c478bd9Sstevel@tonic-gate } 943*7c478bd9Sstevel@tonic-gate return (errc); 944*7c478bd9Sstevel@tonic-gate } 945*7c478bd9Sstevel@tonic-gate 946*7c478bd9Sstevel@tonic-gate static int 947*7c478bd9Sstevel@tonic-gate vhead_fsync(vnode_t *vp, int syncflag, cred_t *cr) 948*7c478bd9Sstevel@tonic-gate { 949*7c478bd9Sstevel@tonic-gate femarg_t farg; 950*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 951*7c478bd9Sstevel@tonic-gate int (*func)(); 952*7c478bd9Sstevel@tonic-gate void *arg0; 953*7c478bd9Sstevel@tonic-gate int errc; 954*7c478bd9Sstevel@tonic-gate 955*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 956*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_fsync); 957*7c478bd9Sstevel@tonic-gate arg0 = vp; 958*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 959*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, syncflag, cr); 960*7c478bd9Sstevel@tonic-gate } else { 961*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 962*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 963*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 964*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 965*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_fsync, vsop_fsync); 966*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, syncflag, cr); 967*7c478bd9Sstevel@tonic-gate fem_release(femsp); 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate return (errc); 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate static void 973*7c478bd9Sstevel@tonic-gate vhead_inactive(vnode_t *vp, cred_t *cr) 974*7c478bd9Sstevel@tonic-gate { 975*7c478bd9Sstevel@tonic-gate femarg_t farg; 976*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 977*7c478bd9Sstevel@tonic-gate void (*func)(); 978*7c478bd9Sstevel@tonic-gate void *arg0; 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 981*7c478bd9Sstevel@tonic-gate func = (void (*)()) (vp->v_op->vop_inactive); 982*7c478bd9Sstevel@tonic-gate arg0 = vp; 983*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 984*7c478bd9Sstevel@tonic-gate (*func)(arg0, cr); 985*7c478bd9Sstevel@tonic-gate } else { 986*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 987*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 988*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 989*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 990*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, void, &arg0, vop_inactive, 991*7c478bd9Sstevel@tonic-gate vsop_inactive); 992*7c478bd9Sstevel@tonic-gate (*func)(arg0, cr); 993*7c478bd9Sstevel@tonic-gate fem_release(femsp); 994*7c478bd9Sstevel@tonic-gate } 995*7c478bd9Sstevel@tonic-gate } 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate static int 998*7c478bd9Sstevel@tonic-gate vhead_fid(vnode_t *vp, fid_t *fidp) 999*7c478bd9Sstevel@tonic-gate { 1000*7c478bd9Sstevel@tonic-gate femarg_t farg; 1001*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1002*7c478bd9Sstevel@tonic-gate int (*func)(); 1003*7c478bd9Sstevel@tonic-gate void *arg0; 1004*7c478bd9Sstevel@tonic-gate int errc; 1005*7c478bd9Sstevel@tonic-gate 1006*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1007*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_fid); 1008*7c478bd9Sstevel@tonic-gate arg0 = vp; 1009*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1010*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, fidp); 1011*7c478bd9Sstevel@tonic-gate } else { 1012*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1013*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1014*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1015*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1016*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_fid, vsop_fid); 1017*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, fidp); 1018*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1019*7c478bd9Sstevel@tonic-gate } 1020*7c478bd9Sstevel@tonic-gate return (errc); 1021*7c478bd9Sstevel@tonic-gate } 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate static int 1024*7c478bd9Sstevel@tonic-gate vhead_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct) 1025*7c478bd9Sstevel@tonic-gate { 1026*7c478bd9Sstevel@tonic-gate femarg_t farg; 1027*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1028*7c478bd9Sstevel@tonic-gate int (*func)(); 1029*7c478bd9Sstevel@tonic-gate void *arg0; 1030*7c478bd9Sstevel@tonic-gate int errc; 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1033*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_rwlock); 1034*7c478bd9Sstevel@tonic-gate arg0 = vp; 1035*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1036*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, write_lock, ct); 1037*7c478bd9Sstevel@tonic-gate } else { 1038*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1039*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1040*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1041*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1042*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_rwlock, 1043*7c478bd9Sstevel@tonic-gate vsop_rwlock); 1044*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, write_lock, ct); 1045*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1046*7c478bd9Sstevel@tonic-gate } 1047*7c478bd9Sstevel@tonic-gate return (errc); 1048*7c478bd9Sstevel@tonic-gate } 1049*7c478bd9Sstevel@tonic-gate 1050*7c478bd9Sstevel@tonic-gate static void 1051*7c478bd9Sstevel@tonic-gate vhead_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct) 1052*7c478bd9Sstevel@tonic-gate { 1053*7c478bd9Sstevel@tonic-gate femarg_t farg; 1054*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1055*7c478bd9Sstevel@tonic-gate void (*func)(); 1056*7c478bd9Sstevel@tonic-gate void *arg0; 1057*7c478bd9Sstevel@tonic-gate 1058*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1059*7c478bd9Sstevel@tonic-gate func = (void (*)()) (vp->v_op->vop_rwunlock); 1060*7c478bd9Sstevel@tonic-gate arg0 = vp; 1061*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1062*7c478bd9Sstevel@tonic-gate (*func)(arg0, write_lock, ct); 1063*7c478bd9Sstevel@tonic-gate } else { 1064*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1065*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1066*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1067*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1068*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, void, &arg0, vop_rwunlock, 1069*7c478bd9Sstevel@tonic-gate vsop_rwunlock); 1070*7c478bd9Sstevel@tonic-gate (*func)(arg0, write_lock, ct); 1071*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate static int 1076*7c478bd9Sstevel@tonic-gate vhead_seek(vnode_t *vp, offset_t ooff, offset_t *noffp) 1077*7c478bd9Sstevel@tonic-gate { 1078*7c478bd9Sstevel@tonic-gate femarg_t farg; 1079*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1080*7c478bd9Sstevel@tonic-gate int (*func)(); 1081*7c478bd9Sstevel@tonic-gate void *arg0; 1082*7c478bd9Sstevel@tonic-gate int errc; 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1085*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_seek); 1086*7c478bd9Sstevel@tonic-gate arg0 = vp; 1087*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1088*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, ooff, noffp); 1089*7c478bd9Sstevel@tonic-gate } else { 1090*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1091*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1092*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1093*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1094*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_seek, vsop_seek); 1095*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, ooff, noffp); 1096*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1097*7c478bd9Sstevel@tonic-gate } 1098*7c478bd9Sstevel@tonic-gate return (errc); 1099*7c478bd9Sstevel@tonic-gate } 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate static int 1102*7c478bd9Sstevel@tonic-gate vhead_cmp(vnode_t *vp1, vnode_t *vp2) 1103*7c478bd9Sstevel@tonic-gate { 1104*7c478bd9Sstevel@tonic-gate femarg_t farg; 1105*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1106*7c478bd9Sstevel@tonic-gate int (*func)(); 1107*7c478bd9Sstevel@tonic-gate void *arg0; 1108*7c478bd9Sstevel@tonic-gate int errc; 1109*7c478bd9Sstevel@tonic-gate 1110*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp1->v_femhead)) == NULL) { 1111*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp1->v_op->vop_cmp); 1112*7c478bd9Sstevel@tonic-gate arg0 = vp1; 1113*7c478bd9Sstevel@tonic-gate fem_unlock(vp1->v_femhead); 1114*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vp2); 1115*7c478bd9Sstevel@tonic-gate } else { 1116*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1117*7c478bd9Sstevel@tonic-gate fem_unlock(vp1->v_femhead); 1118*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp1; 1119*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1120*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_cmp, vsop_cmp); 1121*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vp2); 1122*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate return (errc); 1125*7c478bd9Sstevel@tonic-gate } 1126*7c478bd9Sstevel@tonic-gate 1127*7c478bd9Sstevel@tonic-gate static int 1128*7c478bd9Sstevel@tonic-gate vhead_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, 1129*7c478bd9Sstevel@tonic-gate offset_t offset, struct flk_callback *flk_cbp, cred_t *cr) 1130*7c478bd9Sstevel@tonic-gate { 1131*7c478bd9Sstevel@tonic-gate femarg_t farg; 1132*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1133*7c478bd9Sstevel@tonic-gate int (*func)(); 1134*7c478bd9Sstevel@tonic-gate void *arg0; 1135*7c478bd9Sstevel@tonic-gate int errc; 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1138*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_frlock); 1139*7c478bd9Sstevel@tonic-gate arg0 = vp; 1140*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1141*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, bfp, flag, offset, flk_cbp, cr); 1142*7c478bd9Sstevel@tonic-gate } else { 1143*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1144*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1145*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1146*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1147*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_frlock, 1148*7c478bd9Sstevel@tonic-gate vsop_frlock); 1149*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, bfp, flag, offset, flk_cbp, cr); 1150*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1151*7c478bd9Sstevel@tonic-gate } 1152*7c478bd9Sstevel@tonic-gate return (errc); 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate static int 1156*7c478bd9Sstevel@tonic-gate vhead_space(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, 1157*7c478bd9Sstevel@tonic-gate offset_t offset, cred_t *cr, caller_context_t *ct) 1158*7c478bd9Sstevel@tonic-gate { 1159*7c478bd9Sstevel@tonic-gate femarg_t farg; 1160*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1161*7c478bd9Sstevel@tonic-gate int (*func)(); 1162*7c478bd9Sstevel@tonic-gate void *arg0; 1163*7c478bd9Sstevel@tonic-gate int errc; 1164*7c478bd9Sstevel@tonic-gate 1165*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1166*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_space); 1167*7c478bd9Sstevel@tonic-gate arg0 = vp; 1168*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1169*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, bfp, flag, offset, cr, ct); 1170*7c478bd9Sstevel@tonic-gate } else { 1171*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1172*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1173*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1174*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1175*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_space, vsop_space); 1176*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, bfp, flag, offset, cr, ct); 1177*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1178*7c478bd9Sstevel@tonic-gate } 1179*7c478bd9Sstevel@tonic-gate return (errc); 1180*7c478bd9Sstevel@tonic-gate } 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate static int 1183*7c478bd9Sstevel@tonic-gate vhead_realvp(vnode_t *vp, vnode_t **vpp) 1184*7c478bd9Sstevel@tonic-gate { 1185*7c478bd9Sstevel@tonic-gate femarg_t farg; 1186*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1187*7c478bd9Sstevel@tonic-gate int (*func)(); 1188*7c478bd9Sstevel@tonic-gate void *arg0; 1189*7c478bd9Sstevel@tonic-gate int errc; 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1192*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_realvp); 1193*7c478bd9Sstevel@tonic-gate arg0 = vp; 1194*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1195*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vpp); 1196*7c478bd9Sstevel@tonic-gate } else { 1197*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1198*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1199*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1200*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1201*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_realvp, 1202*7c478bd9Sstevel@tonic-gate vsop_realvp); 1203*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vpp); 1204*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1205*7c478bd9Sstevel@tonic-gate } 1206*7c478bd9Sstevel@tonic-gate return (errc); 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate 1209*7c478bd9Sstevel@tonic-gate static int 1210*7c478bd9Sstevel@tonic-gate vhead_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp, 1211*7c478bd9Sstevel@tonic-gate struct page **plarr, size_t plsz, struct seg *seg, caddr_t addr, 1212*7c478bd9Sstevel@tonic-gate enum seg_rw rw, cred_t *cr) 1213*7c478bd9Sstevel@tonic-gate { 1214*7c478bd9Sstevel@tonic-gate femarg_t farg; 1215*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1216*7c478bd9Sstevel@tonic-gate int (*func)(); 1217*7c478bd9Sstevel@tonic-gate void *arg0; 1218*7c478bd9Sstevel@tonic-gate int errc; 1219*7c478bd9Sstevel@tonic-gate 1220*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1221*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_getpage); 1222*7c478bd9Sstevel@tonic-gate arg0 = vp; 1223*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1224*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, len, protp, plarr, plsz, seg, 1225*7c478bd9Sstevel@tonic-gate addr, rw, cr); 1226*7c478bd9Sstevel@tonic-gate } else { 1227*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1228*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1229*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1230*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1231*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_getpage, 1232*7c478bd9Sstevel@tonic-gate vsop_getpage); 1233*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, len, protp, plarr, plsz, seg, 1234*7c478bd9Sstevel@tonic-gate addr, rw, cr); 1235*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1236*7c478bd9Sstevel@tonic-gate } 1237*7c478bd9Sstevel@tonic-gate return (errc); 1238*7c478bd9Sstevel@tonic-gate } 1239*7c478bd9Sstevel@tonic-gate 1240*7c478bd9Sstevel@tonic-gate static int 1241*7c478bd9Sstevel@tonic-gate vhead_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr) 1242*7c478bd9Sstevel@tonic-gate { 1243*7c478bd9Sstevel@tonic-gate femarg_t farg; 1244*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1245*7c478bd9Sstevel@tonic-gate int (*func)(); 1246*7c478bd9Sstevel@tonic-gate void *arg0; 1247*7c478bd9Sstevel@tonic-gate int errc; 1248*7c478bd9Sstevel@tonic-gate 1249*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1250*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_putpage); 1251*7c478bd9Sstevel@tonic-gate arg0 = vp; 1252*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1253*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, len, flags, cr); 1254*7c478bd9Sstevel@tonic-gate } else { 1255*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1256*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1257*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1258*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1259*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_putpage, 1260*7c478bd9Sstevel@tonic-gate vsop_putpage); 1261*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, len, flags, cr); 1262*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1263*7c478bd9Sstevel@tonic-gate } 1264*7c478bd9Sstevel@tonic-gate return (errc); 1265*7c478bd9Sstevel@tonic-gate } 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate static int 1268*7c478bd9Sstevel@tonic-gate vhead_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, 1269*7c478bd9Sstevel@tonic-gate size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 1270*7c478bd9Sstevel@tonic-gate cred_t *cr) 1271*7c478bd9Sstevel@tonic-gate { 1272*7c478bd9Sstevel@tonic-gate femarg_t farg; 1273*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1274*7c478bd9Sstevel@tonic-gate int (*func)(); 1275*7c478bd9Sstevel@tonic-gate void *arg0; 1276*7c478bd9Sstevel@tonic-gate int errc; 1277*7c478bd9Sstevel@tonic-gate 1278*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1279*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_map); 1280*7c478bd9Sstevel@tonic-gate arg0 = vp; 1281*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1282*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addrp, len, prot, maxprot, 1283*7c478bd9Sstevel@tonic-gate flags, cr); 1284*7c478bd9Sstevel@tonic-gate } else { 1285*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1286*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1287*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1288*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1289*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_map, vsop_map); 1290*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addrp, len, prot, maxprot, 1291*7c478bd9Sstevel@tonic-gate flags, cr); 1292*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1293*7c478bd9Sstevel@tonic-gate } 1294*7c478bd9Sstevel@tonic-gate return (errc); 1295*7c478bd9Sstevel@tonic-gate } 1296*7c478bd9Sstevel@tonic-gate 1297*7c478bd9Sstevel@tonic-gate static int 1298*7c478bd9Sstevel@tonic-gate vhead_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, 1299*7c478bd9Sstevel@tonic-gate size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 1300*7c478bd9Sstevel@tonic-gate cred_t *cr) 1301*7c478bd9Sstevel@tonic-gate { 1302*7c478bd9Sstevel@tonic-gate femarg_t farg; 1303*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1304*7c478bd9Sstevel@tonic-gate int (*func)(); 1305*7c478bd9Sstevel@tonic-gate void *arg0; 1306*7c478bd9Sstevel@tonic-gate int errc; 1307*7c478bd9Sstevel@tonic-gate 1308*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1309*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_addmap); 1310*7c478bd9Sstevel@tonic-gate arg0 = vp; 1311*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1312*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addr, len, prot, maxprot, 1313*7c478bd9Sstevel@tonic-gate flags, cr); 1314*7c478bd9Sstevel@tonic-gate } else { 1315*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1316*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1317*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1318*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1319*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_addmap, 1320*7c478bd9Sstevel@tonic-gate vsop_addmap); 1321*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addr, len, prot, maxprot, 1322*7c478bd9Sstevel@tonic-gate flags, cr); 1323*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1324*7c478bd9Sstevel@tonic-gate } 1325*7c478bd9Sstevel@tonic-gate return (errc); 1326*7c478bd9Sstevel@tonic-gate } 1327*7c478bd9Sstevel@tonic-gate 1328*7c478bd9Sstevel@tonic-gate static int 1329*7c478bd9Sstevel@tonic-gate vhead_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, 1330*7c478bd9Sstevel@tonic-gate size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr) 1331*7c478bd9Sstevel@tonic-gate { 1332*7c478bd9Sstevel@tonic-gate femarg_t farg; 1333*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1334*7c478bd9Sstevel@tonic-gate int (*func)(); 1335*7c478bd9Sstevel@tonic-gate void *arg0; 1336*7c478bd9Sstevel@tonic-gate int errc; 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1339*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_delmap); 1340*7c478bd9Sstevel@tonic-gate arg0 = vp; 1341*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1342*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addr, len, prot, maxprot, 1343*7c478bd9Sstevel@tonic-gate flags, cr); 1344*7c478bd9Sstevel@tonic-gate } else { 1345*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1346*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1347*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1348*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1349*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_delmap, 1350*7c478bd9Sstevel@tonic-gate vsop_delmap); 1351*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, off, as, addr, len, prot, maxprot, 1352*7c478bd9Sstevel@tonic-gate flags, cr); 1353*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1354*7c478bd9Sstevel@tonic-gate } 1355*7c478bd9Sstevel@tonic-gate return (errc); 1356*7c478bd9Sstevel@tonic-gate } 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate static int 1359*7c478bd9Sstevel@tonic-gate vhead_poll(vnode_t *vp, short events, int anyyet, short *reventsp, 1360*7c478bd9Sstevel@tonic-gate struct pollhead **phpp) 1361*7c478bd9Sstevel@tonic-gate { 1362*7c478bd9Sstevel@tonic-gate femarg_t farg; 1363*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1364*7c478bd9Sstevel@tonic-gate int (*func)(); 1365*7c478bd9Sstevel@tonic-gate void *arg0; 1366*7c478bd9Sstevel@tonic-gate int errc; 1367*7c478bd9Sstevel@tonic-gate 1368*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1369*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_poll); 1370*7c478bd9Sstevel@tonic-gate arg0 = vp; 1371*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1372*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, events, anyyet, reventsp, phpp); 1373*7c478bd9Sstevel@tonic-gate } else { 1374*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1375*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1376*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1377*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1378*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_poll, vsop_poll); 1379*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, events, anyyet, reventsp, phpp); 1380*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate return (errc); 1383*7c478bd9Sstevel@tonic-gate } 1384*7c478bd9Sstevel@tonic-gate 1385*7c478bd9Sstevel@tonic-gate static int 1386*7c478bd9Sstevel@tonic-gate vhead_dump(vnode_t *vp, caddr_t addr, int lbdn, int dblks) 1387*7c478bd9Sstevel@tonic-gate { 1388*7c478bd9Sstevel@tonic-gate femarg_t farg; 1389*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1390*7c478bd9Sstevel@tonic-gate int (*func)(); 1391*7c478bd9Sstevel@tonic-gate void *arg0; 1392*7c478bd9Sstevel@tonic-gate int errc; 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1395*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_dump); 1396*7c478bd9Sstevel@tonic-gate arg0 = vp; 1397*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1398*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, addr, lbdn, dblks); 1399*7c478bd9Sstevel@tonic-gate } else { 1400*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1401*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1402*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1403*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1404*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_dump, vsop_dump); 1405*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, addr, lbdn, dblks); 1406*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1407*7c478bd9Sstevel@tonic-gate } 1408*7c478bd9Sstevel@tonic-gate return (errc); 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate 1411*7c478bd9Sstevel@tonic-gate static int 1412*7c478bd9Sstevel@tonic-gate vhead_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr) 1413*7c478bd9Sstevel@tonic-gate { 1414*7c478bd9Sstevel@tonic-gate femarg_t farg; 1415*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1416*7c478bd9Sstevel@tonic-gate int (*func)(); 1417*7c478bd9Sstevel@tonic-gate void *arg0; 1418*7c478bd9Sstevel@tonic-gate int errc; 1419*7c478bd9Sstevel@tonic-gate 1420*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1421*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_pathconf); 1422*7c478bd9Sstevel@tonic-gate arg0 = vp; 1423*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1424*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, valp, cr); 1425*7c478bd9Sstevel@tonic-gate } else { 1426*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1427*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1428*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1429*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1430*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_pathconf, 1431*7c478bd9Sstevel@tonic-gate vsop_pathconf); 1432*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, valp, cr); 1433*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1434*7c478bd9Sstevel@tonic-gate } 1435*7c478bd9Sstevel@tonic-gate return (errc); 1436*7c478bd9Sstevel@tonic-gate } 1437*7c478bd9Sstevel@tonic-gate 1438*7c478bd9Sstevel@tonic-gate static int 1439*7c478bd9Sstevel@tonic-gate vhead_pageio(vnode_t *vp, struct page *pp, u_offset_t io_off, 1440*7c478bd9Sstevel@tonic-gate size_t io_len, int flags, cred_t *cr) 1441*7c478bd9Sstevel@tonic-gate { 1442*7c478bd9Sstevel@tonic-gate femarg_t farg; 1443*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1444*7c478bd9Sstevel@tonic-gate int (*func)(); 1445*7c478bd9Sstevel@tonic-gate void *arg0; 1446*7c478bd9Sstevel@tonic-gate int errc; 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1449*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_pageio); 1450*7c478bd9Sstevel@tonic-gate arg0 = vp; 1451*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1452*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, pp, io_off, io_len, flags, cr); 1453*7c478bd9Sstevel@tonic-gate } else { 1454*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1455*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1456*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1457*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1458*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_pageio, 1459*7c478bd9Sstevel@tonic-gate vsop_pageio); 1460*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, pp, io_off, io_len, flags, cr); 1461*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1462*7c478bd9Sstevel@tonic-gate } 1463*7c478bd9Sstevel@tonic-gate return (errc); 1464*7c478bd9Sstevel@tonic-gate } 1465*7c478bd9Sstevel@tonic-gate 1466*7c478bd9Sstevel@tonic-gate static int 1467*7c478bd9Sstevel@tonic-gate vhead_dumpctl(vnode_t *vp, int action, int *blkp) 1468*7c478bd9Sstevel@tonic-gate { 1469*7c478bd9Sstevel@tonic-gate femarg_t farg; 1470*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1471*7c478bd9Sstevel@tonic-gate int (*func)(); 1472*7c478bd9Sstevel@tonic-gate void *arg0; 1473*7c478bd9Sstevel@tonic-gate int errc; 1474*7c478bd9Sstevel@tonic-gate 1475*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1476*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_dumpctl); 1477*7c478bd9Sstevel@tonic-gate arg0 = vp; 1478*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1479*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, action, blkp); 1480*7c478bd9Sstevel@tonic-gate } else { 1481*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1482*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1483*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1484*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1485*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_dumpctl, 1486*7c478bd9Sstevel@tonic-gate vsop_dumpctl); 1487*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, action, blkp); 1488*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1489*7c478bd9Sstevel@tonic-gate } 1490*7c478bd9Sstevel@tonic-gate return (errc); 1491*7c478bd9Sstevel@tonic-gate } 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate static void 1494*7c478bd9Sstevel@tonic-gate vhead_dispose(vnode_t *vp, struct page *pp, int flag, int dn, cred_t *cr) 1495*7c478bd9Sstevel@tonic-gate { 1496*7c478bd9Sstevel@tonic-gate femarg_t farg; 1497*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1498*7c478bd9Sstevel@tonic-gate void (*func)(); 1499*7c478bd9Sstevel@tonic-gate void *arg0; 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1502*7c478bd9Sstevel@tonic-gate func = (void (*)()) (vp->v_op->vop_dispose); 1503*7c478bd9Sstevel@tonic-gate arg0 = vp; 1504*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1505*7c478bd9Sstevel@tonic-gate (*func)(arg0, pp, flag, dn, cr); 1506*7c478bd9Sstevel@tonic-gate } else { 1507*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1508*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1509*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1510*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1511*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, void, &arg0, vop_dispose, 1512*7c478bd9Sstevel@tonic-gate vsop_dispose); 1513*7c478bd9Sstevel@tonic-gate (*func)(arg0, pp, flag, dn, cr); 1514*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1515*7c478bd9Sstevel@tonic-gate } 1516*7c478bd9Sstevel@tonic-gate } 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate static int 1519*7c478bd9Sstevel@tonic-gate vhead_setsecattr(vnode_t *vp, vsecattr_t *vsap, int flag, cred_t *cr) 1520*7c478bd9Sstevel@tonic-gate { 1521*7c478bd9Sstevel@tonic-gate femarg_t farg; 1522*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1523*7c478bd9Sstevel@tonic-gate int (*func)(); 1524*7c478bd9Sstevel@tonic-gate void *arg0; 1525*7c478bd9Sstevel@tonic-gate int errc; 1526*7c478bd9Sstevel@tonic-gate 1527*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1528*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_setsecattr); 1529*7c478bd9Sstevel@tonic-gate arg0 = vp; 1530*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1531*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vsap, flag, cr); 1532*7c478bd9Sstevel@tonic-gate } else { 1533*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1534*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1535*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1536*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1537*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_setsecattr, 1538*7c478bd9Sstevel@tonic-gate vsop_setsecattr); 1539*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vsap, flag, cr); 1540*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1541*7c478bd9Sstevel@tonic-gate } 1542*7c478bd9Sstevel@tonic-gate return (errc); 1543*7c478bd9Sstevel@tonic-gate } 1544*7c478bd9Sstevel@tonic-gate 1545*7c478bd9Sstevel@tonic-gate static int 1546*7c478bd9Sstevel@tonic-gate vhead_getsecattr(vnode_t *vp, vsecattr_t *vsap, int flag, cred_t *cr) 1547*7c478bd9Sstevel@tonic-gate { 1548*7c478bd9Sstevel@tonic-gate femarg_t farg; 1549*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1550*7c478bd9Sstevel@tonic-gate int (*func)(); 1551*7c478bd9Sstevel@tonic-gate void *arg0; 1552*7c478bd9Sstevel@tonic-gate int errc; 1553*7c478bd9Sstevel@tonic-gate 1554*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1555*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_getsecattr); 1556*7c478bd9Sstevel@tonic-gate arg0 = vp; 1557*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1558*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vsap, flag, cr); 1559*7c478bd9Sstevel@tonic-gate } else { 1560*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1561*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1562*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1563*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1564*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_getsecattr, 1565*7c478bd9Sstevel@tonic-gate vsop_getsecattr); 1566*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vsap, flag, cr); 1567*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1568*7c478bd9Sstevel@tonic-gate } 1569*7c478bd9Sstevel@tonic-gate return (errc); 1570*7c478bd9Sstevel@tonic-gate } 1571*7c478bd9Sstevel@tonic-gate 1572*7c478bd9Sstevel@tonic-gate static int 1573*7c478bd9Sstevel@tonic-gate vhead_shrlock(vnode_t *vp, int cmd, struct shrlock *shr, int flag, 1574*7c478bd9Sstevel@tonic-gate cred_t *cr) 1575*7c478bd9Sstevel@tonic-gate { 1576*7c478bd9Sstevel@tonic-gate femarg_t farg; 1577*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1578*7c478bd9Sstevel@tonic-gate int (*func)(); 1579*7c478bd9Sstevel@tonic-gate void *arg0; 1580*7c478bd9Sstevel@tonic-gate int errc; 1581*7c478bd9Sstevel@tonic-gate 1582*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1583*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_shrlock); 1584*7c478bd9Sstevel@tonic-gate arg0 = vp; 1585*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1586*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, shr, flag, cr); 1587*7c478bd9Sstevel@tonic-gate } else { 1588*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1589*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1590*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1591*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1592*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_shrlock, 1593*7c478bd9Sstevel@tonic-gate vsop_shrlock); 1594*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, cmd, shr, flag, cr); 1595*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1596*7c478bd9Sstevel@tonic-gate } 1597*7c478bd9Sstevel@tonic-gate return (errc); 1598*7c478bd9Sstevel@tonic-gate } 1599*7c478bd9Sstevel@tonic-gate 1600*7c478bd9Sstevel@tonic-gate static int 1601*7c478bd9Sstevel@tonic-gate vhead_vnevent(vnode_t *vp, vnevent_t vnevent) 1602*7c478bd9Sstevel@tonic-gate { 1603*7c478bd9Sstevel@tonic-gate femarg_t farg; 1604*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1605*7c478bd9Sstevel@tonic-gate int (*func)(); 1606*7c478bd9Sstevel@tonic-gate void *arg0; 1607*7c478bd9Sstevel@tonic-gate int errc; 1608*7c478bd9Sstevel@tonic-gate 1609*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vp->v_femhead)) == NULL) { 1610*7c478bd9Sstevel@tonic-gate func = (int (*)()) (vp->v_op->vop_vnevent); 1611*7c478bd9Sstevel@tonic-gate arg0 = vp; 1612*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1613*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vnevent); 1614*7c478bd9Sstevel@tonic-gate } else { 1615*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1616*7c478bd9Sstevel@tonic-gate fem_unlock(vp->v_femhead); 1617*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vp = vp; 1618*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1619*7c478bd9Sstevel@tonic-gate vsop_find(&farg, &func, int, &arg0, vop_vnevent, 1620*7c478bd9Sstevel@tonic-gate vsop_vnevent); 1621*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vnevent); 1622*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1623*7c478bd9Sstevel@tonic-gate } 1624*7c478bd9Sstevel@tonic-gate return (errc); 1625*7c478bd9Sstevel@tonic-gate } 1626*7c478bd9Sstevel@tonic-gate 1627*7c478bd9Sstevel@tonic-gate static int 1628*7c478bd9Sstevel@tonic-gate fshead_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) 1629*7c478bd9Sstevel@tonic-gate { 1630*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1631*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1632*7c478bd9Sstevel@tonic-gate int (*func)(); 1633*7c478bd9Sstevel@tonic-gate void *arg0; 1634*7c478bd9Sstevel@tonic-gate int errc; 1635*7c478bd9Sstevel@tonic-gate 1636*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1637*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_mount; 1638*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1639*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, mvp, uap, cr); 1640*7c478bd9Sstevel@tonic-gate } else { 1641*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1642*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1643*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1644*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1645*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_mount, 1646*7c478bd9Sstevel@tonic-gate vfsop_mount); 1647*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, mvp, uap, cr); 1648*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1649*7c478bd9Sstevel@tonic-gate } 1650*7c478bd9Sstevel@tonic-gate return (errc); 1651*7c478bd9Sstevel@tonic-gate } 1652*7c478bd9Sstevel@tonic-gate 1653*7c478bd9Sstevel@tonic-gate static int 1654*7c478bd9Sstevel@tonic-gate fshead_unmount(vfs_t *vfsp, int flag, cred_t *cr) 1655*7c478bd9Sstevel@tonic-gate { 1656*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1657*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1658*7c478bd9Sstevel@tonic-gate int (*func)(); 1659*7c478bd9Sstevel@tonic-gate void *arg0; 1660*7c478bd9Sstevel@tonic-gate int errc; 1661*7c478bd9Sstevel@tonic-gate 1662*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1663*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_unmount; 1664*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1665*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, flag, cr); 1666*7c478bd9Sstevel@tonic-gate } else { 1667*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1668*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1669*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1670*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1671*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_unmount, 1672*7c478bd9Sstevel@tonic-gate vfsop_unmount); 1673*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, flag, cr); 1674*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1675*7c478bd9Sstevel@tonic-gate } 1676*7c478bd9Sstevel@tonic-gate return (errc); 1677*7c478bd9Sstevel@tonic-gate } 1678*7c478bd9Sstevel@tonic-gate 1679*7c478bd9Sstevel@tonic-gate static int 1680*7c478bd9Sstevel@tonic-gate fshead_root(vfs_t *vfsp, vnode_t **vpp) 1681*7c478bd9Sstevel@tonic-gate { 1682*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1683*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1684*7c478bd9Sstevel@tonic-gate int (*func)(); 1685*7c478bd9Sstevel@tonic-gate void *arg0; 1686*7c478bd9Sstevel@tonic-gate int errc; 1687*7c478bd9Sstevel@tonic-gate 1688*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1689*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_root; 1690*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1691*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, vpp); 1692*7c478bd9Sstevel@tonic-gate } else { 1693*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1694*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1695*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1696*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1697*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_root, vfsop_root); 1698*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vpp); 1699*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1700*7c478bd9Sstevel@tonic-gate } 1701*7c478bd9Sstevel@tonic-gate return (errc); 1702*7c478bd9Sstevel@tonic-gate } 1703*7c478bd9Sstevel@tonic-gate 1704*7c478bd9Sstevel@tonic-gate static int 1705*7c478bd9Sstevel@tonic-gate fshead_statvfs(vfs_t *vfsp, statvfs64_t *sp) 1706*7c478bd9Sstevel@tonic-gate { 1707*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1708*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1709*7c478bd9Sstevel@tonic-gate int (*func)(); 1710*7c478bd9Sstevel@tonic-gate void *arg0; 1711*7c478bd9Sstevel@tonic-gate int errc; 1712*7c478bd9Sstevel@tonic-gate 1713*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1714*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_statvfs; 1715*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1716*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, sp); 1717*7c478bd9Sstevel@tonic-gate } else { 1718*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1719*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1720*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1721*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1722*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_statvfs, 1723*7c478bd9Sstevel@tonic-gate vfsop_statvfs); 1724*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, sp); 1725*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1726*7c478bd9Sstevel@tonic-gate } 1727*7c478bd9Sstevel@tonic-gate return (errc); 1728*7c478bd9Sstevel@tonic-gate } 1729*7c478bd9Sstevel@tonic-gate 1730*7c478bd9Sstevel@tonic-gate static int 1731*7c478bd9Sstevel@tonic-gate fshead_sync(vfs_t *vfsp, short flag, cred_t *cr) 1732*7c478bd9Sstevel@tonic-gate { 1733*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1734*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1735*7c478bd9Sstevel@tonic-gate int (*func)(); 1736*7c478bd9Sstevel@tonic-gate void *arg0; 1737*7c478bd9Sstevel@tonic-gate int errc; 1738*7c478bd9Sstevel@tonic-gate 1739*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1740*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_sync; 1741*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1742*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, flag, cr); 1743*7c478bd9Sstevel@tonic-gate } else { 1744*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1745*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1746*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1747*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1748*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_sync, vfsop_sync); 1749*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, flag, cr); 1750*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1751*7c478bd9Sstevel@tonic-gate } 1752*7c478bd9Sstevel@tonic-gate return (errc); 1753*7c478bd9Sstevel@tonic-gate } 1754*7c478bd9Sstevel@tonic-gate 1755*7c478bd9Sstevel@tonic-gate static int 1756*7c478bd9Sstevel@tonic-gate fshead_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp) 1757*7c478bd9Sstevel@tonic-gate { 1758*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1759*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1760*7c478bd9Sstevel@tonic-gate int (*func)(); 1761*7c478bd9Sstevel@tonic-gate void *arg0; 1762*7c478bd9Sstevel@tonic-gate int errc; 1763*7c478bd9Sstevel@tonic-gate 1764*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1765*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_vget; 1766*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1767*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, vpp, fidp); 1768*7c478bd9Sstevel@tonic-gate } else { 1769*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1770*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1771*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1772*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1773*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_vget, vfsop_vget); 1774*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vpp, fidp); 1775*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1776*7c478bd9Sstevel@tonic-gate } 1777*7c478bd9Sstevel@tonic-gate return (errc); 1778*7c478bd9Sstevel@tonic-gate } 1779*7c478bd9Sstevel@tonic-gate 1780*7c478bd9Sstevel@tonic-gate static int 1781*7c478bd9Sstevel@tonic-gate fshead_mountroot(vfs_t *vfsp, enum whymountroot reason) 1782*7c478bd9Sstevel@tonic-gate { 1783*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1784*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1785*7c478bd9Sstevel@tonic-gate int (*func)(); 1786*7c478bd9Sstevel@tonic-gate void *arg0; 1787*7c478bd9Sstevel@tonic-gate int errc; 1788*7c478bd9Sstevel@tonic-gate 1789*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1790*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_mountroot; 1791*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1792*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, reason); 1793*7c478bd9Sstevel@tonic-gate } else { 1794*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1795*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1796*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1797*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1798*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_mountroot, 1799*7c478bd9Sstevel@tonic-gate vfsop_mountroot); 1800*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, reason); 1801*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1802*7c478bd9Sstevel@tonic-gate } 1803*7c478bd9Sstevel@tonic-gate return (errc); 1804*7c478bd9Sstevel@tonic-gate } 1805*7c478bd9Sstevel@tonic-gate 1806*7c478bd9Sstevel@tonic-gate static void 1807*7c478bd9Sstevel@tonic-gate fshead_freevfs(vfs_t *vfsp) 1808*7c478bd9Sstevel@tonic-gate { 1809*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1810*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1811*7c478bd9Sstevel@tonic-gate void (*func)(); 1812*7c478bd9Sstevel@tonic-gate void *arg0; 1813*7c478bd9Sstevel@tonic-gate 1814*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1815*7c478bd9Sstevel@tonic-gate func = (void (*)()) vfsp->vfs_op->vfs_freevfs; 1816*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1817*7c478bd9Sstevel@tonic-gate (*func)(vfsp); 1818*7c478bd9Sstevel@tonic-gate } else { 1819*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1820*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1821*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1822*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1823*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, void, &arg0, vfs_freevfs, 1824*7c478bd9Sstevel@tonic-gate vfsop_freevfs); 1825*7c478bd9Sstevel@tonic-gate (*func)(arg0); 1826*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1827*7c478bd9Sstevel@tonic-gate } 1828*7c478bd9Sstevel@tonic-gate } 1829*7c478bd9Sstevel@tonic-gate 1830*7c478bd9Sstevel@tonic-gate static int 1831*7c478bd9Sstevel@tonic-gate fshead_vnstate(vfs_t *vfsp, vnode_t *vp, vntrans_t nstate) 1832*7c478bd9Sstevel@tonic-gate { 1833*7c478bd9Sstevel@tonic-gate fsemarg_t farg; 1834*7c478bd9Sstevel@tonic-gate struct fem_list *femsp; 1835*7c478bd9Sstevel@tonic-gate int (*func)(); 1836*7c478bd9Sstevel@tonic-gate void *arg0; 1837*7c478bd9Sstevel@tonic-gate int errc; 1838*7c478bd9Sstevel@tonic-gate 1839*7c478bd9Sstevel@tonic-gate if ((femsp = fem_lock(vfsp->vfs_femhead)) == NULL) { 1840*7c478bd9Sstevel@tonic-gate func = (int (*)()) vfsp->vfs_op->vfs_vnstate; 1841*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1842*7c478bd9Sstevel@tonic-gate errc = (*func)(vfsp, vp, nstate); 1843*7c478bd9Sstevel@tonic-gate } else { 1844*7c478bd9Sstevel@tonic-gate fem_addref(femsp); 1845*7c478bd9Sstevel@tonic-gate fem_unlock(vfsp->vfs_femhead); 1846*7c478bd9Sstevel@tonic-gate farg.fa_vnode.vfsp = vfsp; 1847*7c478bd9Sstevel@tonic-gate farg.fa_fnode = femsp->feml_nodes + femsp->feml_tos; 1848*7c478bd9Sstevel@tonic-gate vfsop_find(&farg, &func, int, &arg0, vfs_vnstate, 1849*7c478bd9Sstevel@tonic-gate vfsop_vnstate); 1850*7c478bd9Sstevel@tonic-gate errc = (*func)(arg0, vp, nstate); 1851*7c478bd9Sstevel@tonic-gate fem_release(femsp); 1852*7c478bd9Sstevel@tonic-gate } 1853*7c478bd9Sstevel@tonic-gate return (errc); 1854*7c478bd9Sstevel@tonic-gate } 1855*7c478bd9Sstevel@tonic-gate 1856*7c478bd9Sstevel@tonic-gate 1857*7c478bd9Sstevel@tonic-gate /* 1858*7c478bd9Sstevel@tonic-gate * specification table for the vhead vnode operations. 1859*7c478bd9Sstevel@tonic-gate * It is an error for any operations to be missing. 1860*7c478bd9Sstevel@tonic-gate */ 1861*7c478bd9Sstevel@tonic-gate 1862*7c478bd9Sstevel@tonic-gate static struct fs_operation_def fhead_vn_spec[] = { 1863*7c478bd9Sstevel@tonic-gate { VOPNAME_OPEN, (femop_t *)vhead_open }, 1864*7c478bd9Sstevel@tonic-gate { VOPNAME_CLOSE, (femop_t *)vhead_close }, 1865*7c478bd9Sstevel@tonic-gate { VOPNAME_READ, (femop_t *)vhead_read }, 1866*7c478bd9Sstevel@tonic-gate { VOPNAME_WRITE, (femop_t *)vhead_write }, 1867*7c478bd9Sstevel@tonic-gate { VOPNAME_IOCTL, (femop_t *)vhead_ioctl }, 1868*7c478bd9Sstevel@tonic-gate { VOPNAME_SETFL, (femop_t *)vhead_setfl }, 1869*7c478bd9Sstevel@tonic-gate { VOPNAME_GETATTR, (femop_t *)vhead_getattr }, 1870*7c478bd9Sstevel@tonic-gate { VOPNAME_SETATTR, (femop_t *)vhead_setattr }, 1871*7c478bd9Sstevel@tonic-gate { VOPNAME_ACCESS, (femop_t *)vhead_access }, 1872*7c478bd9Sstevel@tonic-gate { VOPNAME_LOOKUP, (femop_t *)vhead_lookup }, 1873*7c478bd9Sstevel@tonic-gate { VOPNAME_CREATE, (femop_t *)vhead_create }, 1874*7c478bd9Sstevel@tonic-gate { VOPNAME_REMOVE, (femop_t *)vhead_remove }, 1875*7c478bd9Sstevel@tonic-gate { VOPNAME_LINK, (femop_t *)vhead_link }, 1876*7c478bd9Sstevel@tonic-gate { VOPNAME_RENAME, (femop_t *)vhead_rename }, 1877*7c478bd9Sstevel@tonic-gate { VOPNAME_MKDIR, (femop_t *)vhead_mkdir }, 1878*7c478bd9Sstevel@tonic-gate { VOPNAME_RMDIR, (femop_t *)vhead_rmdir }, 1879*7c478bd9Sstevel@tonic-gate { VOPNAME_READDIR, (femop_t *)vhead_readdir }, 1880*7c478bd9Sstevel@tonic-gate { VOPNAME_SYMLINK, (femop_t *)vhead_symlink }, 1881*7c478bd9Sstevel@tonic-gate { VOPNAME_READLINK, (femop_t *)vhead_readlink }, 1882*7c478bd9Sstevel@tonic-gate { VOPNAME_FSYNC, (femop_t *)vhead_fsync }, 1883*7c478bd9Sstevel@tonic-gate { VOPNAME_INACTIVE, (femop_t *)vhead_inactive }, 1884*7c478bd9Sstevel@tonic-gate { VOPNAME_FID, (femop_t *)vhead_fid }, 1885*7c478bd9Sstevel@tonic-gate { VOPNAME_RWLOCK, (femop_t *)vhead_rwlock }, 1886*7c478bd9Sstevel@tonic-gate { VOPNAME_RWUNLOCK, (femop_t *)vhead_rwunlock }, 1887*7c478bd9Sstevel@tonic-gate { VOPNAME_SEEK, (femop_t *)vhead_seek }, 1888*7c478bd9Sstevel@tonic-gate { VOPNAME_CMP, (femop_t *)vhead_cmp }, 1889*7c478bd9Sstevel@tonic-gate { VOPNAME_FRLOCK, (femop_t *)vhead_frlock }, 1890*7c478bd9Sstevel@tonic-gate { VOPNAME_SPACE, (femop_t *)vhead_space }, 1891*7c478bd9Sstevel@tonic-gate { VOPNAME_REALVP, (femop_t *)vhead_realvp }, 1892*7c478bd9Sstevel@tonic-gate { VOPNAME_GETPAGE, (femop_t *)vhead_getpage }, 1893*7c478bd9Sstevel@tonic-gate { VOPNAME_PUTPAGE, (femop_t *)vhead_putpage }, 1894*7c478bd9Sstevel@tonic-gate { VOPNAME_MAP, (femop_t *)vhead_map }, 1895*7c478bd9Sstevel@tonic-gate { VOPNAME_ADDMAP, (femop_t *)vhead_addmap }, 1896*7c478bd9Sstevel@tonic-gate { VOPNAME_DELMAP, (femop_t *)vhead_delmap }, 1897*7c478bd9Sstevel@tonic-gate { VOPNAME_POLL, (femop_t *)vhead_poll }, 1898*7c478bd9Sstevel@tonic-gate { VOPNAME_DUMP, (femop_t *)vhead_dump }, 1899*7c478bd9Sstevel@tonic-gate { VOPNAME_PATHCONF, (femop_t *)vhead_pathconf }, 1900*7c478bd9Sstevel@tonic-gate { VOPNAME_PAGEIO, (femop_t *)vhead_pageio }, 1901*7c478bd9Sstevel@tonic-gate { VOPNAME_DUMPCTL, (femop_t *)vhead_dumpctl }, 1902*7c478bd9Sstevel@tonic-gate { VOPNAME_DISPOSE, (femop_t *)vhead_dispose }, 1903*7c478bd9Sstevel@tonic-gate { VOPNAME_SETSECATTR, (femop_t *)vhead_setsecattr }, 1904*7c478bd9Sstevel@tonic-gate { VOPNAME_GETSECATTR, (femop_t *)vhead_getsecattr }, 1905*7c478bd9Sstevel@tonic-gate { VOPNAME_SHRLOCK, (femop_t *)vhead_shrlock }, 1906*7c478bd9Sstevel@tonic-gate { VOPNAME_VNEVENT, (femop_t *)vhead_vnevent }, 1907*7c478bd9Sstevel@tonic-gate { NULL, NULL } 1908*7c478bd9Sstevel@tonic-gate }; 1909*7c478bd9Sstevel@tonic-gate 1910*7c478bd9Sstevel@tonic-gate /* 1911*7c478bd9Sstevel@tonic-gate * specification table for the vfshead vnode operations. 1912*7c478bd9Sstevel@tonic-gate * It is an error for any operations to be missing. 1913*7c478bd9Sstevel@tonic-gate */ 1914*7c478bd9Sstevel@tonic-gate 1915*7c478bd9Sstevel@tonic-gate static struct fs_operation_def fshead_vfs_spec[] = { 1916*7c478bd9Sstevel@tonic-gate { VFSNAME_MOUNT, (femop_t *)fshead_mount }, 1917*7c478bd9Sstevel@tonic-gate { VFSNAME_UNMOUNT, (femop_t *)fshead_unmount }, 1918*7c478bd9Sstevel@tonic-gate { VFSNAME_ROOT, (femop_t *)fshead_root }, 1919*7c478bd9Sstevel@tonic-gate { VFSNAME_STATVFS, (femop_t *)fshead_statvfs }, 1920*7c478bd9Sstevel@tonic-gate { VFSNAME_SYNC, (femop_t *)fshead_sync }, 1921*7c478bd9Sstevel@tonic-gate { VFSNAME_VGET, (femop_t *)fshead_vget }, 1922*7c478bd9Sstevel@tonic-gate { VFSNAME_MOUNTROOT, (femop_t *)fshead_mountroot }, 1923*7c478bd9Sstevel@tonic-gate { VFSNAME_FREEVFS, (femop_t *)fshead_freevfs }, 1924*7c478bd9Sstevel@tonic-gate { VFSNAME_VNSTATE, (femop_t *)fshead_vnstate }, 1925*7c478bd9Sstevel@tonic-gate { NULL, NULL } 1926*7c478bd9Sstevel@tonic-gate }; 1927*7c478bd9Sstevel@tonic-gate 1928*7c478bd9Sstevel@tonic-gate /* 1929*7c478bd9Sstevel@tonic-gate * This set of routines transfer control to the next stacked monitor. 1930*7c478bd9Sstevel@tonic-gate * 1931*7c478bd9Sstevel@tonic-gate * Each routine is identical except for naming, types and arguments. 1932*7c478bd9Sstevel@tonic-gate * 1933*7c478bd9Sstevel@tonic-gate * The basic steps are: 1934*7c478bd9Sstevel@tonic-gate * 1. Decrease the stack pointer by one. 1935*7c478bd9Sstevel@tonic-gate * 2. If the current item is a base operation (vnode, vfs), goto 5. 1936*7c478bd9Sstevel@tonic-gate * 3. If the current item does not have a corresponding operation, goto 1 1937*7c478bd9Sstevel@tonic-gate * 4. Return by invoking the current item with the argument handle. 1938*7c478bd9Sstevel@tonic-gate * 5. Return by invoking the base operation with the base object. 1939*7c478bd9Sstevel@tonic-gate * 1940*7c478bd9Sstevel@tonic-gate * for each classification, there needs to be at least one "next" operation 1941*7c478bd9Sstevel@tonic-gate * for each "head"operation. 1942*7c478bd9Sstevel@tonic-gate * 1943*7c478bd9Sstevel@tonic-gate */ 1944*7c478bd9Sstevel@tonic-gate 1945*7c478bd9Sstevel@tonic-gate int 1946*7c478bd9Sstevel@tonic-gate vnext_open(femarg_t *vf, int mode, cred_t *cr) 1947*7c478bd9Sstevel@tonic-gate { 1948*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 1949*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 1950*7c478bd9Sstevel@tonic-gate 1951*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 1952*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 1953*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_open, vsop_open); 1954*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 1955*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 1956*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, mode, cr)); 1957*7c478bd9Sstevel@tonic-gate } 1958*7c478bd9Sstevel@tonic-gate 1959*7c478bd9Sstevel@tonic-gate int 1960*7c478bd9Sstevel@tonic-gate vnext_close(femarg_t *vf, int flag, int count, offset_t offset, cred_t *cr) 1961*7c478bd9Sstevel@tonic-gate { 1962*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 1963*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 1964*7c478bd9Sstevel@tonic-gate 1965*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 1966*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 1967*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_close, vsop_close); 1968*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 1969*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 1970*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, flag, count, offset, cr)); 1971*7c478bd9Sstevel@tonic-gate } 1972*7c478bd9Sstevel@tonic-gate 1973*7c478bd9Sstevel@tonic-gate int 1974*7c478bd9Sstevel@tonic-gate vnext_read(femarg_t *vf, uio_t *uiop, int ioflag, cred_t *cr, 1975*7c478bd9Sstevel@tonic-gate struct caller_context *ct) 1976*7c478bd9Sstevel@tonic-gate { 1977*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 1978*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 1979*7c478bd9Sstevel@tonic-gate 1980*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 1981*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 1982*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_read, vsop_read); 1983*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 1984*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 1985*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, uiop, ioflag, cr, ct)); 1986*7c478bd9Sstevel@tonic-gate } 1987*7c478bd9Sstevel@tonic-gate 1988*7c478bd9Sstevel@tonic-gate int 1989*7c478bd9Sstevel@tonic-gate vnext_write(femarg_t *vf, uio_t *uiop, int ioflag, cred_t *cr, 1990*7c478bd9Sstevel@tonic-gate struct caller_context *ct) 1991*7c478bd9Sstevel@tonic-gate { 1992*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 1993*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 1994*7c478bd9Sstevel@tonic-gate 1995*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 1996*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 1997*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_write, vsop_write); 1998*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 1999*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2000*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, uiop, ioflag, cr, ct)); 2001*7c478bd9Sstevel@tonic-gate } 2002*7c478bd9Sstevel@tonic-gate 2003*7c478bd9Sstevel@tonic-gate int 2004*7c478bd9Sstevel@tonic-gate vnext_ioctl(femarg_t *vf, int cmd, intptr_t arg, int flag, cred_t *cr, 2005*7c478bd9Sstevel@tonic-gate int *rvalp) 2006*7c478bd9Sstevel@tonic-gate { 2007*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2008*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2009*7c478bd9Sstevel@tonic-gate 2010*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2011*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2012*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_ioctl, vsop_ioctl); 2013*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2014*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2015*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, cmd, arg, flag, cr, rvalp)); 2016*7c478bd9Sstevel@tonic-gate } 2017*7c478bd9Sstevel@tonic-gate 2018*7c478bd9Sstevel@tonic-gate int 2019*7c478bd9Sstevel@tonic-gate vnext_setfl(femarg_t *vf, int oflags, int nflags, cred_t *cr) 2020*7c478bd9Sstevel@tonic-gate { 2021*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2022*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2023*7c478bd9Sstevel@tonic-gate 2024*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2025*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2026*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_setfl, vsop_setfl); 2027*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2028*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2029*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, oflags, nflags, cr)); 2030*7c478bd9Sstevel@tonic-gate } 2031*7c478bd9Sstevel@tonic-gate 2032*7c478bd9Sstevel@tonic-gate int 2033*7c478bd9Sstevel@tonic-gate vnext_getattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr) 2034*7c478bd9Sstevel@tonic-gate { 2035*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2036*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2037*7c478bd9Sstevel@tonic-gate 2038*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2039*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2040*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_getattr, vsop_getattr); 2041*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2042*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2043*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vap, flags, cr)); 2044*7c478bd9Sstevel@tonic-gate } 2045*7c478bd9Sstevel@tonic-gate 2046*7c478bd9Sstevel@tonic-gate int 2047*7c478bd9Sstevel@tonic-gate vnext_setattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr, 2048*7c478bd9Sstevel@tonic-gate caller_context_t *ct) 2049*7c478bd9Sstevel@tonic-gate { 2050*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2051*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2052*7c478bd9Sstevel@tonic-gate 2053*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2054*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2055*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_setattr, vsop_setattr); 2056*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2057*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2058*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vap, flags, cr, ct)); 2059*7c478bd9Sstevel@tonic-gate } 2060*7c478bd9Sstevel@tonic-gate 2061*7c478bd9Sstevel@tonic-gate int 2062*7c478bd9Sstevel@tonic-gate vnext_access(femarg_t *vf, int mode, int flags, cred_t *cr) 2063*7c478bd9Sstevel@tonic-gate { 2064*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2065*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2066*7c478bd9Sstevel@tonic-gate 2067*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2068*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2069*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_access, vsop_access); 2070*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2071*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2072*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, mode, flags, cr)); 2073*7c478bd9Sstevel@tonic-gate } 2074*7c478bd9Sstevel@tonic-gate 2075*7c478bd9Sstevel@tonic-gate int 2076*7c478bd9Sstevel@tonic-gate vnext_lookup(femarg_t *vf, char *nm, vnode_t **vpp, pathname_t *pnp, 2077*7c478bd9Sstevel@tonic-gate int flags, vnode_t *rdir, cred_t *cr) 2078*7c478bd9Sstevel@tonic-gate { 2079*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2080*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2081*7c478bd9Sstevel@tonic-gate 2082*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2083*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2084*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_lookup, vsop_lookup); 2085*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2086*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2087*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, nm, vpp, pnp, flags, rdir, cr)); 2088*7c478bd9Sstevel@tonic-gate } 2089*7c478bd9Sstevel@tonic-gate 2090*7c478bd9Sstevel@tonic-gate int 2091*7c478bd9Sstevel@tonic-gate vnext_create(femarg_t *vf, char *name, vattr_t *vap, vcexcl_t excl, 2092*7c478bd9Sstevel@tonic-gate int mode, vnode_t **vpp, cred_t *cr, int flag) 2093*7c478bd9Sstevel@tonic-gate { 2094*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2095*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2096*7c478bd9Sstevel@tonic-gate 2097*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2098*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2099*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_create, vsop_create); 2100*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2101*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2102*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, name, vap, excl, mode, vpp, cr, flag)); 2103*7c478bd9Sstevel@tonic-gate } 2104*7c478bd9Sstevel@tonic-gate 2105*7c478bd9Sstevel@tonic-gate int 2106*7c478bd9Sstevel@tonic-gate vnext_remove(femarg_t *vf, char *nm, cred_t *cr) 2107*7c478bd9Sstevel@tonic-gate { 2108*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2109*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2110*7c478bd9Sstevel@tonic-gate 2111*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2112*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2113*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_remove, vsop_remove); 2114*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2115*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2116*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, nm, cr)); 2117*7c478bd9Sstevel@tonic-gate } 2118*7c478bd9Sstevel@tonic-gate 2119*7c478bd9Sstevel@tonic-gate int 2120*7c478bd9Sstevel@tonic-gate vnext_link(femarg_t *vf, vnode_t *svp, char *tnm, cred_t *cr) 2121*7c478bd9Sstevel@tonic-gate { 2122*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2123*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2124*7c478bd9Sstevel@tonic-gate 2125*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2126*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2127*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_link, vsop_link); 2128*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2129*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2130*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, svp, tnm, cr)); 2131*7c478bd9Sstevel@tonic-gate } 2132*7c478bd9Sstevel@tonic-gate 2133*7c478bd9Sstevel@tonic-gate int 2134*7c478bd9Sstevel@tonic-gate vnext_rename(femarg_t *vf, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr) 2135*7c478bd9Sstevel@tonic-gate { 2136*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2137*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2138*7c478bd9Sstevel@tonic-gate 2139*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2140*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2141*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_rename, vsop_rename); 2142*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2143*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2144*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, snm, tdvp, tnm, cr)); 2145*7c478bd9Sstevel@tonic-gate } 2146*7c478bd9Sstevel@tonic-gate 2147*7c478bd9Sstevel@tonic-gate int 2148*7c478bd9Sstevel@tonic-gate vnext_mkdir(femarg_t *vf, char *dirname, vattr_t *vap, vnode_t **vpp, 2149*7c478bd9Sstevel@tonic-gate cred_t *cr) 2150*7c478bd9Sstevel@tonic-gate { 2151*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2152*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2153*7c478bd9Sstevel@tonic-gate 2154*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2155*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2156*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_mkdir, vsop_mkdir); 2157*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2158*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2159*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, dirname, vap, vpp, cr)); 2160*7c478bd9Sstevel@tonic-gate } 2161*7c478bd9Sstevel@tonic-gate 2162*7c478bd9Sstevel@tonic-gate int 2163*7c478bd9Sstevel@tonic-gate vnext_rmdir(femarg_t *vf, char *nm, vnode_t *cdir, cred_t *cr) 2164*7c478bd9Sstevel@tonic-gate { 2165*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2166*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2167*7c478bd9Sstevel@tonic-gate 2168*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2169*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2170*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_rmdir, vsop_rmdir); 2171*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2172*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2173*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, nm, cdir, cr)); 2174*7c478bd9Sstevel@tonic-gate } 2175*7c478bd9Sstevel@tonic-gate 2176*7c478bd9Sstevel@tonic-gate int 2177*7c478bd9Sstevel@tonic-gate vnext_readdir(femarg_t *vf, uio_t *uiop, cred_t *cr, int *eofp) 2178*7c478bd9Sstevel@tonic-gate { 2179*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2180*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2181*7c478bd9Sstevel@tonic-gate 2182*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2183*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2184*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_readdir, vsop_readdir); 2185*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2186*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2187*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, uiop, cr, eofp)); 2188*7c478bd9Sstevel@tonic-gate } 2189*7c478bd9Sstevel@tonic-gate 2190*7c478bd9Sstevel@tonic-gate int 2191*7c478bd9Sstevel@tonic-gate vnext_symlink(femarg_t *vf, char *linkname, vattr_t *vap, char *target, 2192*7c478bd9Sstevel@tonic-gate cred_t *cr) 2193*7c478bd9Sstevel@tonic-gate { 2194*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2195*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2196*7c478bd9Sstevel@tonic-gate 2197*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2198*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2199*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_symlink, vsop_symlink); 2200*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2201*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2202*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, linkname, vap, target, cr)); 2203*7c478bd9Sstevel@tonic-gate } 2204*7c478bd9Sstevel@tonic-gate 2205*7c478bd9Sstevel@tonic-gate int 2206*7c478bd9Sstevel@tonic-gate vnext_readlink(femarg_t *vf, uio_t *uiop, cred_t *cr) 2207*7c478bd9Sstevel@tonic-gate { 2208*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2209*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2210*7c478bd9Sstevel@tonic-gate 2211*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2212*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2213*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_readlink, vsop_readlink); 2214*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2215*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2216*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, uiop, cr)); 2217*7c478bd9Sstevel@tonic-gate } 2218*7c478bd9Sstevel@tonic-gate 2219*7c478bd9Sstevel@tonic-gate int 2220*7c478bd9Sstevel@tonic-gate vnext_fsync(femarg_t *vf, int syncflag, cred_t *cr) 2221*7c478bd9Sstevel@tonic-gate { 2222*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2223*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2224*7c478bd9Sstevel@tonic-gate 2225*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2226*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2227*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_fsync, vsop_fsync); 2228*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2229*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2230*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, syncflag, cr)); 2231*7c478bd9Sstevel@tonic-gate } 2232*7c478bd9Sstevel@tonic-gate 2233*7c478bd9Sstevel@tonic-gate void 2234*7c478bd9Sstevel@tonic-gate vnext_inactive(femarg_t *vf, cred_t *cr) 2235*7c478bd9Sstevel@tonic-gate { 2236*7c478bd9Sstevel@tonic-gate void (*func)() = NULL; 2237*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2238*7c478bd9Sstevel@tonic-gate 2239*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2240*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2241*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, void, &arg0, vop_inactive, vsop_inactive); 2242*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2243*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2244*7c478bd9Sstevel@tonic-gate (*func)(arg0, cr); 2245*7c478bd9Sstevel@tonic-gate } 2246*7c478bd9Sstevel@tonic-gate 2247*7c478bd9Sstevel@tonic-gate int 2248*7c478bd9Sstevel@tonic-gate vnext_fid(femarg_t *vf, fid_t *fidp) 2249*7c478bd9Sstevel@tonic-gate { 2250*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2251*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2252*7c478bd9Sstevel@tonic-gate 2253*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2254*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2255*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_fid, vsop_fid); 2256*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2257*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2258*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, fidp)); 2259*7c478bd9Sstevel@tonic-gate } 2260*7c478bd9Sstevel@tonic-gate 2261*7c478bd9Sstevel@tonic-gate int 2262*7c478bd9Sstevel@tonic-gate vnext_rwlock(femarg_t *vf, int write_lock, caller_context_t *ct) 2263*7c478bd9Sstevel@tonic-gate { 2264*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2265*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2266*7c478bd9Sstevel@tonic-gate 2267*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2268*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2269*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_rwlock, vsop_rwlock); 2270*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2271*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2272*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, write_lock, ct)); 2273*7c478bd9Sstevel@tonic-gate } 2274*7c478bd9Sstevel@tonic-gate 2275*7c478bd9Sstevel@tonic-gate void 2276*7c478bd9Sstevel@tonic-gate vnext_rwunlock(femarg_t *vf, int write_lock, caller_context_t *ct) 2277*7c478bd9Sstevel@tonic-gate { 2278*7c478bd9Sstevel@tonic-gate void (*func)() = NULL; 2279*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2280*7c478bd9Sstevel@tonic-gate 2281*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2282*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2283*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, void, &arg0, vop_rwunlock, vsop_rwunlock); 2284*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2285*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2286*7c478bd9Sstevel@tonic-gate (*func)(arg0, write_lock, ct); 2287*7c478bd9Sstevel@tonic-gate } 2288*7c478bd9Sstevel@tonic-gate 2289*7c478bd9Sstevel@tonic-gate int 2290*7c478bd9Sstevel@tonic-gate vnext_seek(femarg_t *vf, offset_t ooff, offset_t *noffp) 2291*7c478bd9Sstevel@tonic-gate { 2292*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2293*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2294*7c478bd9Sstevel@tonic-gate 2295*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2296*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2297*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_seek, vsop_seek); 2298*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2299*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2300*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, ooff, noffp)); 2301*7c478bd9Sstevel@tonic-gate } 2302*7c478bd9Sstevel@tonic-gate 2303*7c478bd9Sstevel@tonic-gate int 2304*7c478bd9Sstevel@tonic-gate vnext_cmp(femarg_t *vf, vnode_t *vp2) 2305*7c478bd9Sstevel@tonic-gate { 2306*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2307*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2308*7c478bd9Sstevel@tonic-gate 2309*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2310*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2311*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_cmp, vsop_cmp); 2312*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2313*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2314*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vp2)); 2315*7c478bd9Sstevel@tonic-gate } 2316*7c478bd9Sstevel@tonic-gate 2317*7c478bd9Sstevel@tonic-gate int 2318*7c478bd9Sstevel@tonic-gate vnext_frlock(femarg_t *vf, int cmd, struct flock64 *bfp, int flag, 2319*7c478bd9Sstevel@tonic-gate offset_t offset, struct flk_callback *flk_cbp, cred_t *cr) 2320*7c478bd9Sstevel@tonic-gate { 2321*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2322*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2323*7c478bd9Sstevel@tonic-gate 2324*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2325*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2326*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_frlock, vsop_frlock); 2327*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2328*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2329*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, cmd, bfp, flag, offset, flk_cbp, cr)); 2330*7c478bd9Sstevel@tonic-gate } 2331*7c478bd9Sstevel@tonic-gate 2332*7c478bd9Sstevel@tonic-gate int 2333*7c478bd9Sstevel@tonic-gate vnext_space(femarg_t *vf, int cmd, struct flock64 *bfp, int flag, 2334*7c478bd9Sstevel@tonic-gate offset_t offset, cred_t *cr, caller_context_t *ct) 2335*7c478bd9Sstevel@tonic-gate { 2336*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2337*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2338*7c478bd9Sstevel@tonic-gate 2339*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2340*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2341*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_space, vsop_space); 2342*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2343*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2344*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, cmd, bfp, flag, offset, cr, ct)); 2345*7c478bd9Sstevel@tonic-gate } 2346*7c478bd9Sstevel@tonic-gate 2347*7c478bd9Sstevel@tonic-gate int 2348*7c478bd9Sstevel@tonic-gate vnext_realvp(femarg_t *vf, vnode_t **vpp) 2349*7c478bd9Sstevel@tonic-gate { 2350*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2351*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2352*7c478bd9Sstevel@tonic-gate 2353*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2354*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2355*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_realvp, vsop_realvp); 2356*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2357*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2358*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vpp)); 2359*7c478bd9Sstevel@tonic-gate } 2360*7c478bd9Sstevel@tonic-gate 2361*7c478bd9Sstevel@tonic-gate int 2362*7c478bd9Sstevel@tonic-gate vnext_getpage(femarg_t *vf, offset_t off, size_t len, uint_t *protp, 2363*7c478bd9Sstevel@tonic-gate struct page **plarr, size_t plsz, struct seg *seg, caddr_t addr, 2364*7c478bd9Sstevel@tonic-gate enum seg_rw rw, cred_t *cr) 2365*7c478bd9Sstevel@tonic-gate { 2366*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2367*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2368*7c478bd9Sstevel@tonic-gate 2369*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2370*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2371*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_getpage, vsop_getpage); 2372*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2373*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2374*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, off, len, protp, plarr, plsz, seg, addr, rw, 2375*7c478bd9Sstevel@tonic-gate cr)); 2376*7c478bd9Sstevel@tonic-gate } 2377*7c478bd9Sstevel@tonic-gate 2378*7c478bd9Sstevel@tonic-gate int 2379*7c478bd9Sstevel@tonic-gate vnext_putpage(femarg_t *vf, offset_t off, size_t len, int flags, 2380*7c478bd9Sstevel@tonic-gate cred_t *cr) 2381*7c478bd9Sstevel@tonic-gate { 2382*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2383*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2384*7c478bd9Sstevel@tonic-gate 2385*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2386*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2387*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_putpage, vsop_putpage); 2388*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2389*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2390*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, off, len, flags, cr)); 2391*7c478bd9Sstevel@tonic-gate } 2392*7c478bd9Sstevel@tonic-gate 2393*7c478bd9Sstevel@tonic-gate int 2394*7c478bd9Sstevel@tonic-gate vnext_map(femarg_t *vf, offset_t off, struct as *as, caddr_t *addrp, 2395*7c478bd9Sstevel@tonic-gate size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 2396*7c478bd9Sstevel@tonic-gate cred_t *cr) 2397*7c478bd9Sstevel@tonic-gate { 2398*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2399*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2400*7c478bd9Sstevel@tonic-gate 2401*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2402*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2403*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_map, vsop_map); 2404*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2405*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2406*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, off, as, addrp, len, prot, maxprot, flags, 2407*7c478bd9Sstevel@tonic-gate cr)); 2408*7c478bd9Sstevel@tonic-gate } 2409*7c478bd9Sstevel@tonic-gate 2410*7c478bd9Sstevel@tonic-gate int 2411*7c478bd9Sstevel@tonic-gate vnext_addmap(femarg_t *vf, offset_t off, struct as *as, caddr_t addr, 2412*7c478bd9Sstevel@tonic-gate size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, 2413*7c478bd9Sstevel@tonic-gate cred_t *cr) 2414*7c478bd9Sstevel@tonic-gate { 2415*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2416*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2417*7c478bd9Sstevel@tonic-gate 2418*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2419*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2420*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_addmap, vsop_addmap); 2421*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2422*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2423*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, off, as, addr, len, prot, maxprot, flags, cr)); 2424*7c478bd9Sstevel@tonic-gate } 2425*7c478bd9Sstevel@tonic-gate 2426*7c478bd9Sstevel@tonic-gate int 2427*7c478bd9Sstevel@tonic-gate vnext_delmap(femarg_t *vf, offset_t off, struct as *as, caddr_t addr, 2428*7c478bd9Sstevel@tonic-gate size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr) 2429*7c478bd9Sstevel@tonic-gate { 2430*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2431*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2432*7c478bd9Sstevel@tonic-gate 2433*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2434*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2435*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_delmap, vsop_delmap); 2436*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2437*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2438*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, off, as, addr, len, prot, maxprot, flags, cr)); 2439*7c478bd9Sstevel@tonic-gate } 2440*7c478bd9Sstevel@tonic-gate 2441*7c478bd9Sstevel@tonic-gate int 2442*7c478bd9Sstevel@tonic-gate vnext_poll(femarg_t *vf, short events, int anyyet, short *reventsp, 2443*7c478bd9Sstevel@tonic-gate struct pollhead **phpp) 2444*7c478bd9Sstevel@tonic-gate { 2445*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2446*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2447*7c478bd9Sstevel@tonic-gate 2448*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2449*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2450*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_poll, vsop_poll); 2451*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2452*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2453*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, events, anyyet, reventsp, phpp)); 2454*7c478bd9Sstevel@tonic-gate } 2455*7c478bd9Sstevel@tonic-gate 2456*7c478bd9Sstevel@tonic-gate int 2457*7c478bd9Sstevel@tonic-gate vnext_dump(femarg_t *vf, caddr_t addr, int lbdn, int dblks) 2458*7c478bd9Sstevel@tonic-gate { 2459*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2460*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2461*7c478bd9Sstevel@tonic-gate 2462*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2463*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2464*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_dump, vsop_dump); 2465*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2466*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2467*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, addr, lbdn, dblks)); 2468*7c478bd9Sstevel@tonic-gate } 2469*7c478bd9Sstevel@tonic-gate 2470*7c478bd9Sstevel@tonic-gate int 2471*7c478bd9Sstevel@tonic-gate vnext_pathconf(femarg_t *vf, int cmd, ulong_t *valp, cred_t *cr) 2472*7c478bd9Sstevel@tonic-gate { 2473*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2474*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2475*7c478bd9Sstevel@tonic-gate 2476*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2477*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2478*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_pathconf, vsop_pathconf); 2479*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2480*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2481*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, cmd, valp, cr)); 2482*7c478bd9Sstevel@tonic-gate } 2483*7c478bd9Sstevel@tonic-gate 2484*7c478bd9Sstevel@tonic-gate int 2485*7c478bd9Sstevel@tonic-gate vnext_pageio(femarg_t *vf, struct page *pp, u_offset_t io_off, 2486*7c478bd9Sstevel@tonic-gate size_t io_len, int flags, cred_t *cr) 2487*7c478bd9Sstevel@tonic-gate { 2488*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2489*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2490*7c478bd9Sstevel@tonic-gate 2491*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2492*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2493*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_pageio, vsop_pageio); 2494*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2495*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2496*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, pp, io_off, io_len, flags, cr)); 2497*7c478bd9Sstevel@tonic-gate } 2498*7c478bd9Sstevel@tonic-gate 2499*7c478bd9Sstevel@tonic-gate int 2500*7c478bd9Sstevel@tonic-gate vnext_dumpctl(femarg_t *vf, int action, int *blkp) 2501*7c478bd9Sstevel@tonic-gate { 2502*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2503*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2504*7c478bd9Sstevel@tonic-gate 2505*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2506*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2507*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_dumpctl, vsop_dumpctl); 2508*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2509*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2510*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, action, blkp)); 2511*7c478bd9Sstevel@tonic-gate } 2512*7c478bd9Sstevel@tonic-gate 2513*7c478bd9Sstevel@tonic-gate void 2514*7c478bd9Sstevel@tonic-gate vnext_dispose(femarg_t *vf, struct page *pp, int flag, int dn, cred_t *cr) 2515*7c478bd9Sstevel@tonic-gate { 2516*7c478bd9Sstevel@tonic-gate void (*func)() = NULL; 2517*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2518*7c478bd9Sstevel@tonic-gate 2519*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2520*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2521*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, void, &arg0, vop_dispose, vsop_dispose); 2522*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2523*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2524*7c478bd9Sstevel@tonic-gate (*func)(arg0, pp, flag, dn, cr); 2525*7c478bd9Sstevel@tonic-gate } 2526*7c478bd9Sstevel@tonic-gate 2527*7c478bd9Sstevel@tonic-gate int 2528*7c478bd9Sstevel@tonic-gate vnext_setsecattr(femarg_t *vf, vsecattr_t *vsap, int flag, cred_t *cr) 2529*7c478bd9Sstevel@tonic-gate { 2530*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2531*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2532*7c478bd9Sstevel@tonic-gate 2533*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2534*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2535*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_setsecattr, vsop_setsecattr); 2536*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2537*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2538*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vsap, flag, cr)); 2539*7c478bd9Sstevel@tonic-gate } 2540*7c478bd9Sstevel@tonic-gate 2541*7c478bd9Sstevel@tonic-gate int 2542*7c478bd9Sstevel@tonic-gate vnext_getsecattr(femarg_t *vf, vsecattr_t *vsap, int flag, cred_t *cr) 2543*7c478bd9Sstevel@tonic-gate { 2544*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2545*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2546*7c478bd9Sstevel@tonic-gate 2547*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2548*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2549*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_getsecattr, vsop_getsecattr); 2550*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2551*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2552*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vsap, flag, cr)); 2553*7c478bd9Sstevel@tonic-gate } 2554*7c478bd9Sstevel@tonic-gate 2555*7c478bd9Sstevel@tonic-gate int 2556*7c478bd9Sstevel@tonic-gate vnext_shrlock(femarg_t *vf, int cmd, struct shrlock *shr, int flag, 2557*7c478bd9Sstevel@tonic-gate cred_t *cr) 2558*7c478bd9Sstevel@tonic-gate { 2559*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2560*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2561*7c478bd9Sstevel@tonic-gate 2562*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2563*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2564*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_shrlock, vsop_shrlock); 2565*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2566*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2567*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, cmd, shr, flag, cr)); 2568*7c478bd9Sstevel@tonic-gate } 2569*7c478bd9Sstevel@tonic-gate 2570*7c478bd9Sstevel@tonic-gate int 2571*7c478bd9Sstevel@tonic-gate vnext_vnevent(femarg_t *vf, vnevent_t vnevent) 2572*7c478bd9Sstevel@tonic-gate { 2573*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2574*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2575*7c478bd9Sstevel@tonic-gate 2576*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2577*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2578*7c478bd9Sstevel@tonic-gate vsop_find(vf, &func, int, &arg0, vop_vnevent, vsop_vnevent); 2579*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2580*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2581*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vnevent)); 2582*7c478bd9Sstevel@tonic-gate } 2583*7c478bd9Sstevel@tonic-gate 2584*7c478bd9Sstevel@tonic-gate int 2585*7c478bd9Sstevel@tonic-gate vfsnext_mount(fsemarg_t *vf, vnode_t *mvp, struct mounta *uap, cred_t *cr) 2586*7c478bd9Sstevel@tonic-gate { 2587*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2588*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2589*7c478bd9Sstevel@tonic-gate 2590*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2591*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2592*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_mount, vfsop_mount); 2593*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2594*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2595*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, mvp, uap, cr)); 2596*7c478bd9Sstevel@tonic-gate } 2597*7c478bd9Sstevel@tonic-gate 2598*7c478bd9Sstevel@tonic-gate int 2599*7c478bd9Sstevel@tonic-gate vfsnext_unmount(fsemarg_t *vf, int flag, cred_t *cr) 2600*7c478bd9Sstevel@tonic-gate { 2601*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2602*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2603*7c478bd9Sstevel@tonic-gate 2604*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2605*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2606*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_unmount, vfsop_unmount); 2607*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2608*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2609*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, flag, cr)); 2610*7c478bd9Sstevel@tonic-gate } 2611*7c478bd9Sstevel@tonic-gate 2612*7c478bd9Sstevel@tonic-gate int 2613*7c478bd9Sstevel@tonic-gate vfsnext_root(fsemarg_t *vf, vnode_t **vpp) 2614*7c478bd9Sstevel@tonic-gate { 2615*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2616*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2617*7c478bd9Sstevel@tonic-gate 2618*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2619*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2620*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_root, vfsop_root); 2621*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2622*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2623*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vpp)); 2624*7c478bd9Sstevel@tonic-gate } 2625*7c478bd9Sstevel@tonic-gate 2626*7c478bd9Sstevel@tonic-gate int 2627*7c478bd9Sstevel@tonic-gate vfsnext_statvfs(fsemarg_t *vf, statvfs64_t *sp) 2628*7c478bd9Sstevel@tonic-gate { 2629*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2630*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2631*7c478bd9Sstevel@tonic-gate 2632*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2633*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2634*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_statvfs, vfsop_statvfs); 2635*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2636*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2637*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, sp)); 2638*7c478bd9Sstevel@tonic-gate } 2639*7c478bd9Sstevel@tonic-gate 2640*7c478bd9Sstevel@tonic-gate int 2641*7c478bd9Sstevel@tonic-gate vfsnext_sync(fsemarg_t *vf, short flag, cred_t *cr) 2642*7c478bd9Sstevel@tonic-gate { 2643*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2644*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2645*7c478bd9Sstevel@tonic-gate 2646*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2647*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2648*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_sync, vfsop_sync); 2649*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2650*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2651*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, flag, cr)); 2652*7c478bd9Sstevel@tonic-gate } 2653*7c478bd9Sstevel@tonic-gate 2654*7c478bd9Sstevel@tonic-gate int 2655*7c478bd9Sstevel@tonic-gate vfsnext_vget(fsemarg_t *vf, vnode_t **vpp, fid_t *fidp) 2656*7c478bd9Sstevel@tonic-gate { 2657*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2658*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2659*7c478bd9Sstevel@tonic-gate 2660*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2661*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2662*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_vget, vfsop_vget); 2663*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2664*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2665*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vpp, fidp)); 2666*7c478bd9Sstevel@tonic-gate } 2667*7c478bd9Sstevel@tonic-gate 2668*7c478bd9Sstevel@tonic-gate int 2669*7c478bd9Sstevel@tonic-gate vfsnext_mountroot(fsemarg_t *vf, enum whymountroot reason) 2670*7c478bd9Sstevel@tonic-gate { 2671*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2672*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2673*7c478bd9Sstevel@tonic-gate 2674*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2675*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2676*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_mountroot, vfsop_mountroot); 2677*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2678*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2679*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, reason)); 2680*7c478bd9Sstevel@tonic-gate } 2681*7c478bd9Sstevel@tonic-gate 2682*7c478bd9Sstevel@tonic-gate void 2683*7c478bd9Sstevel@tonic-gate vfsnext_freevfs(fsemarg_t *vf) 2684*7c478bd9Sstevel@tonic-gate { 2685*7c478bd9Sstevel@tonic-gate void (*func)() = NULL; 2686*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2687*7c478bd9Sstevel@tonic-gate 2688*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2689*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2690*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, void, &arg0, vfs_freevfs, vfsop_freevfs); 2691*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2692*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2693*7c478bd9Sstevel@tonic-gate (*func)(arg0); 2694*7c478bd9Sstevel@tonic-gate } 2695*7c478bd9Sstevel@tonic-gate 2696*7c478bd9Sstevel@tonic-gate int 2697*7c478bd9Sstevel@tonic-gate vfsnext_vnstate(fsemarg_t *vf, vnode_t *vp, vntrans_t nstate) 2698*7c478bd9Sstevel@tonic-gate { 2699*7c478bd9Sstevel@tonic-gate int (*func)() = NULL; 2700*7c478bd9Sstevel@tonic-gate void *arg0 = NULL; 2701*7c478bd9Sstevel@tonic-gate 2702*7c478bd9Sstevel@tonic-gate ASSERT(vf != NULL); 2703*7c478bd9Sstevel@tonic-gate vf->fa_fnode--; 2704*7c478bd9Sstevel@tonic-gate vfsop_find(vf, &func, int, &arg0, vfs_vnstate, vfsop_vnstate); 2705*7c478bd9Sstevel@tonic-gate ASSERT(func != NULL); 2706*7c478bd9Sstevel@tonic-gate ASSERT(arg0 != NULL); 2707*7c478bd9Sstevel@tonic-gate return ((*func)(arg0, vp, nstate)); 2708*7c478bd9Sstevel@tonic-gate } 2709*7c478bd9Sstevel@tonic-gate 2710*7c478bd9Sstevel@tonic-gate 2711*7c478bd9Sstevel@tonic-gate /* 2712*7c478bd9Sstevel@tonic-gate * Create a new fem_head and associate with the vnode. 2713*7c478bd9Sstevel@tonic-gate * To keep the unaugmented vnode access path lock free, we spin 2714*7c478bd9Sstevel@tonic-gate * update this - create a new one, then try and install it. If 2715*7c478bd9Sstevel@tonic-gate * we fail to install, release the old one and pretend we succeeded. 2716*7c478bd9Sstevel@tonic-gate */ 2717*7c478bd9Sstevel@tonic-gate 2718*7c478bd9Sstevel@tonic-gate static struct fem_head * 2719*7c478bd9Sstevel@tonic-gate new_femhead(struct fem_head **hp) 2720*7c478bd9Sstevel@tonic-gate { 2721*7c478bd9Sstevel@tonic-gate struct fem_head *head; 2722*7c478bd9Sstevel@tonic-gate 2723*7c478bd9Sstevel@tonic-gate head = kmem_alloc(sizeof (*head), KM_SLEEP); 2724*7c478bd9Sstevel@tonic-gate mutex_init(&head->femh_lock, NULL, MUTEX_DEFAULT, NULL); 2725*7c478bd9Sstevel@tonic-gate head->femh_list = NULL; 2726*7c478bd9Sstevel@tonic-gate if (casptr(hp, NULL, head) != NULL) { 2727*7c478bd9Sstevel@tonic-gate kmem_free(head, sizeof (*head)); 2728*7c478bd9Sstevel@tonic-gate head = *hp; 2729*7c478bd9Sstevel@tonic-gate } 2730*7c478bd9Sstevel@tonic-gate return (head); 2731*7c478bd9Sstevel@tonic-gate } 2732*7c478bd9Sstevel@tonic-gate 2733*7c478bd9Sstevel@tonic-gate /* 2734*7c478bd9Sstevel@tonic-gate * Create a fem_list. The fem_list that gets returned is in a 2735*7c478bd9Sstevel@tonic-gate * very rudimentary state and MUST NOT be used until it's initialized 2736*7c478bd9Sstevel@tonic-gate * (usually by femlist_construct() or fem_dup_list()). The refcount 2737*7c478bd9Sstevel@tonic-gate * and size is set properly and top-of-stack is set to the "guard" node 2738*7c478bd9Sstevel@tonic-gate * just to be consistent. 2739*7c478bd9Sstevel@tonic-gate * 2740*7c478bd9Sstevel@tonic-gate * If anyone were to accidentally trying to run on this fem_list before 2741*7c478bd9Sstevel@tonic-gate * it's initialized then the system would likely panic trying to defererence 2742*7c478bd9Sstevel@tonic-gate * the (NULL) fn_op pointer. 2743*7c478bd9Sstevel@tonic-gate * 2744*7c478bd9Sstevel@tonic-gate */ 2745*7c478bd9Sstevel@tonic-gate static struct fem_list * 2746*7c478bd9Sstevel@tonic-gate femlist_create(int numnodes) 2747*7c478bd9Sstevel@tonic-gate { 2748*7c478bd9Sstevel@tonic-gate struct fem_list *sp; 2749*7c478bd9Sstevel@tonic-gate 2750*7c478bd9Sstevel@tonic-gate sp = kmem_alloc(fl_ntob(numnodes), KM_SLEEP); 2751*7c478bd9Sstevel@tonic-gate sp->feml_refc = 1; 2752*7c478bd9Sstevel@tonic-gate sp->feml_ssize = numnodes; 2753*7c478bd9Sstevel@tonic-gate sp->feml_nodes[0] = FEM_GUARD(FEMTYPE_NULL); 2754*7c478bd9Sstevel@tonic-gate sp->feml_tos = 0; 2755*7c478bd9Sstevel@tonic-gate return (sp); 2756*7c478bd9Sstevel@tonic-gate } 2757*7c478bd9Sstevel@tonic-gate 2758*7c478bd9Sstevel@tonic-gate /* 2759*7c478bd9Sstevel@tonic-gate * Construct a new femlist. 2760*7c478bd9Sstevel@tonic-gate * The list is constructed with the appropriate type of guard to 2761*7c478bd9Sstevel@tonic-gate * anchor it, and inserts the original ops. 2762*7c478bd9Sstevel@tonic-gate */ 2763*7c478bd9Sstevel@tonic-gate 2764*7c478bd9Sstevel@tonic-gate static struct fem_list * 2765*7c478bd9Sstevel@tonic-gate femlist_construct(void *baseops, int type, int numnodes) 2766*7c478bd9Sstevel@tonic-gate { 2767*7c478bd9Sstevel@tonic-gate struct fem_list *sp; 2768*7c478bd9Sstevel@tonic-gate 2769*7c478bd9Sstevel@tonic-gate sp = femlist_create(numnodes); 2770*7c478bd9Sstevel@tonic-gate sp->feml_nodes[0] = FEM_GUARD(type); 2771*7c478bd9Sstevel@tonic-gate sp->feml_nodes[1].fn_op.anon = baseops; 2772*7c478bd9Sstevel@tonic-gate sp->feml_nodes[1].fn_available = NULL; 2773*7c478bd9Sstevel@tonic-gate sp->feml_nodes[1].fn_av_hold = NULL; 2774*7c478bd9Sstevel@tonic-gate sp->feml_nodes[1].fn_av_rele = NULL; 2775*7c478bd9Sstevel@tonic-gate sp->feml_tos = 1; 2776*7c478bd9Sstevel@tonic-gate return (sp); 2777*7c478bd9Sstevel@tonic-gate } 2778*7c478bd9Sstevel@tonic-gate 2779*7c478bd9Sstevel@tonic-gate /* 2780*7c478bd9Sstevel@tonic-gate * Duplicate a list. Copy the original list to the clone. 2781*7c478bd9Sstevel@tonic-gate * 2782*7c478bd9Sstevel@tonic-gate * NOTE: The caller must have the fem_head for the lists locked. 2783*7c478bd9Sstevel@tonic-gate * Assuming the appropriate lock is held and the caller has done the 2784*7c478bd9Sstevel@tonic-gate * math right, the clone list should be big enough to old the original. 2785*7c478bd9Sstevel@tonic-gate */ 2786*7c478bd9Sstevel@tonic-gate 2787*7c478bd9Sstevel@tonic-gate static void 2788*7c478bd9Sstevel@tonic-gate fem_dup_list(struct fem_list *orig, struct fem_list *clone) 2789*7c478bd9Sstevel@tonic-gate { 2790*7c478bd9Sstevel@tonic-gate int i; 2791*7c478bd9Sstevel@tonic-gate 2792*7c478bd9Sstevel@tonic-gate ASSERT(clone->feml_ssize >= orig->feml_ssize); 2793*7c478bd9Sstevel@tonic-gate 2794*7c478bd9Sstevel@tonic-gate bcopy(orig->feml_nodes, clone->feml_nodes, 2795*7c478bd9Sstevel@tonic-gate sizeof (orig->feml_nodes[0]) * orig->feml_ssize); 2796*7c478bd9Sstevel@tonic-gate clone->feml_tos = orig->feml_tos; 2797*7c478bd9Sstevel@tonic-gate /* 2798*7c478bd9Sstevel@tonic-gate * Now that we've copied the old list (orig) to the new list (clone), 2799*7c478bd9Sstevel@tonic-gate * we need to walk the new list and put another hold on fn_available. 2800*7c478bd9Sstevel@tonic-gate */ 2801*7c478bd9Sstevel@tonic-gate for (i = clone->feml_tos; i > 0; i--) { 2802*7c478bd9Sstevel@tonic-gate struct fem_node *fnp = &clone->feml_nodes[i]; 2803*7c478bd9Sstevel@tonic-gate 2804*7c478bd9Sstevel@tonic-gate if (fnp->fn_av_hold) 2805*7c478bd9Sstevel@tonic-gate (*(fnp->fn_av_hold))(fnp->fn_available); 2806*7c478bd9Sstevel@tonic-gate } 2807*7c478bd9Sstevel@tonic-gate } 2808*7c478bd9Sstevel@tonic-gate 2809*7c478bd9Sstevel@tonic-gate 2810*7c478bd9Sstevel@tonic-gate static int 2811*7c478bd9Sstevel@tonic-gate fem_push_node( 2812*7c478bd9Sstevel@tonic-gate struct fem_head **hp, 2813*7c478bd9Sstevel@tonic-gate void **baseops, 2814*7c478bd9Sstevel@tonic-gate int type, 2815*7c478bd9Sstevel@tonic-gate struct fem_node *nnode, 2816*7c478bd9Sstevel@tonic-gate femhow_t how) 2817*7c478bd9Sstevel@tonic-gate { 2818*7c478bd9Sstevel@tonic-gate struct fem_head *hd; 2819*7c478bd9Sstevel@tonic-gate struct fem_list *list; 2820*7c478bd9Sstevel@tonic-gate void *oldops; 2821*7c478bd9Sstevel@tonic-gate int retry; 2822*7c478bd9Sstevel@tonic-gate int error = 0; 2823*7c478bd9Sstevel@tonic-gate int i; 2824*7c478bd9Sstevel@tonic-gate 2825*7c478bd9Sstevel@tonic-gate /* Validate the node */ 2826*7c478bd9Sstevel@tonic-gate if ((nnode->fn_op.anon == NULL) || (nnode->fn_available == NULL)) { 2827*7c478bd9Sstevel@tonic-gate return (EINVAL); 2828*7c478bd9Sstevel@tonic-gate } 2829*7c478bd9Sstevel@tonic-gate 2830*7c478bd9Sstevel@tonic-gate if ((hd = *hp) == NULL) { /* construct a proto-list */ 2831*7c478bd9Sstevel@tonic-gate hd = new_femhead(hp); 2832*7c478bd9Sstevel@tonic-gate } 2833*7c478bd9Sstevel@tonic-gate /* 2834*7c478bd9Sstevel@tonic-gate * RULE: once a femhead has been pushed onto a object, it cannot be 2835*7c478bd9Sstevel@tonic-gate * removed until the object is destroyed. It can be deactivated by 2836*7c478bd9Sstevel@tonic-gate * placing the original 'object operations' onto the object, which 2837*7c478bd9Sstevel@tonic-gate * will ignore the femhead. 2838*7c478bd9Sstevel@tonic-gate * The loop will exist when the femh_list has space to push a monitor 2839*7c478bd9Sstevel@tonic-gate * onto it. 2840*7c478bd9Sstevel@tonic-gate */ 2841*7c478bd9Sstevel@tonic-gate do { 2842*7c478bd9Sstevel@tonic-gate retry = 1; 2843*7c478bd9Sstevel@tonic-gate list = fem_lock(hd); 2844*7c478bd9Sstevel@tonic-gate oldops = *baseops; 2845*7c478bd9Sstevel@tonic-gate 2846*7c478bd9Sstevel@tonic-gate if (list != NULL) { 2847*7c478bd9Sstevel@tonic-gate if (list->feml_tos+1 < list->feml_ssize) { 2848*7c478bd9Sstevel@tonic-gate retry = 0; 2849*7c478bd9Sstevel@tonic-gate } else { 2850*7c478bd9Sstevel@tonic-gate struct fem_list *olist = list; 2851*7c478bd9Sstevel@tonic-gate 2852*7c478bd9Sstevel@tonic-gate fem_addref(olist); 2853*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2854*7c478bd9Sstevel@tonic-gate list = femlist_create(olist->feml_ssize * 2); 2855*7c478bd9Sstevel@tonic-gate (void) fem_lock(hd); 2856*7c478bd9Sstevel@tonic-gate if (hd->femh_list == olist) { 2857*7c478bd9Sstevel@tonic-gate if (list->feml_ssize <= 2858*7c478bd9Sstevel@tonic-gate olist->feml_ssize) { 2859*7c478bd9Sstevel@tonic-gate /* 2860*7c478bd9Sstevel@tonic-gate * We have a new list, but it 2861*7c478bd9Sstevel@tonic-gate * is too small to hold the 2862*7c478bd9Sstevel@tonic-gate * original contents plus the 2863*7c478bd9Sstevel@tonic-gate * one to push. Release the 2864*7c478bd9Sstevel@tonic-gate * new list and start over. 2865*7c478bd9Sstevel@tonic-gate */ 2866*7c478bd9Sstevel@tonic-gate fem_release(list); 2867*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2868*7c478bd9Sstevel@tonic-gate } else { 2869*7c478bd9Sstevel@tonic-gate /* 2870*7c478bd9Sstevel@tonic-gate * Life is good: Our new list 2871*7c478bd9Sstevel@tonic-gate * is big enough to hold the 2872*7c478bd9Sstevel@tonic-gate * original list (olist) + 1. 2873*7c478bd9Sstevel@tonic-gate */ 2874*7c478bd9Sstevel@tonic-gate fem_dup_list(olist, list); 2875*7c478bd9Sstevel@tonic-gate /* orphan this list */ 2876*7c478bd9Sstevel@tonic-gate hd->femh_list = list; 2877*7c478bd9Sstevel@tonic-gate fem_delref(olist); 2878*7c478bd9Sstevel@tonic-gate retry = 0; 2879*7c478bd9Sstevel@tonic-gate } 2880*7c478bd9Sstevel@tonic-gate } else { 2881*7c478bd9Sstevel@tonic-gate /* concurrent update, retry */ 2882*7c478bd9Sstevel@tonic-gate fem_release(list); 2883*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2884*7c478bd9Sstevel@tonic-gate } 2885*7c478bd9Sstevel@tonic-gate /* remove the reference we added above */ 2886*7c478bd9Sstevel@tonic-gate fem_release(olist); 2887*7c478bd9Sstevel@tonic-gate } 2888*7c478bd9Sstevel@tonic-gate } else { 2889*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2890*7c478bd9Sstevel@tonic-gate list = femlist_construct(oldops, type, NNODES_DEFAULT); 2891*7c478bd9Sstevel@tonic-gate (void) fem_lock(hd); 2892*7c478bd9Sstevel@tonic-gate if (hd->femh_list != NULL || *baseops != oldops) { 2893*7c478bd9Sstevel@tonic-gate /* concurrent update, retry */ 2894*7c478bd9Sstevel@tonic-gate fem_release(list); 2895*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2896*7c478bd9Sstevel@tonic-gate } else { 2897*7c478bd9Sstevel@tonic-gate hd->femh_list = list; 2898*7c478bd9Sstevel@tonic-gate *baseops = FEM_HEAD(type); 2899*7c478bd9Sstevel@tonic-gate retry = 0; 2900*7c478bd9Sstevel@tonic-gate } 2901*7c478bd9Sstevel@tonic-gate } 2902*7c478bd9Sstevel@tonic-gate } while (retry); 2903*7c478bd9Sstevel@tonic-gate 2904*7c478bd9Sstevel@tonic-gate ASSERT(mutex_owner(&hd->femh_lock) == curthread); 2905*7c478bd9Sstevel@tonic-gate ASSERT(list->feml_tos+1 < list->feml_ssize); 2906*7c478bd9Sstevel@tonic-gate 2907*7c478bd9Sstevel@tonic-gate /* 2908*7c478bd9Sstevel@tonic-gate * The presence of "how" will modify the behavior of how/if 2909*7c478bd9Sstevel@tonic-gate * nodes are pushed. If it's FORCE, then we can skip 2910*7c478bd9Sstevel@tonic-gate * all the checks and push it on. 2911*7c478bd9Sstevel@tonic-gate */ 2912*7c478bd9Sstevel@tonic-gate if (how != FORCE) { 2913*7c478bd9Sstevel@tonic-gate /* Start at the top and work our way down */ 2914*7c478bd9Sstevel@tonic-gate for (i = list->feml_tos; i > 0; i--) { 2915*7c478bd9Sstevel@tonic-gate void *fn_av = list->feml_nodes[i].fn_available; 2916*7c478bd9Sstevel@tonic-gate void *fn_op = list->feml_nodes[i].fn_op.anon; 2917*7c478bd9Sstevel@tonic-gate 2918*7c478bd9Sstevel@tonic-gate /* 2919*7c478bd9Sstevel@tonic-gate * OPARGUNIQ means that this node should not 2920*7c478bd9Sstevel@tonic-gate * be pushed on if a node with the same op/avail 2921*7c478bd9Sstevel@tonic-gate * combination exists. This situation returns 2922*7c478bd9Sstevel@tonic-gate * EBUSY. 2923*7c478bd9Sstevel@tonic-gate * 2924*7c478bd9Sstevel@tonic-gate * OPUNIQ means that this node should not be 2925*7c478bd9Sstevel@tonic-gate * pushed on if a node with the same op exists. 2926*7c478bd9Sstevel@tonic-gate * This situation also returns EBUSY. 2927*7c478bd9Sstevel@tonic-gate */ 2928*7c478bd9Sstevel@tonic-gate switch (how) { 2929*7c478bd9Sstevel@tonic-gate 2930*7c478bd9Sstevel@tonic-gate case OPUNIQ: 2931*7c478bd9Sstevel@tonic-gate if (fn_op == nnode->fn_op.anon) { 2932*7c478bd9Sstevel@tonic-gate error = EBUSY; 2933*7c478bd9Sstevel@tonic-gate } 2934*7c478bd9Sstevel@tonic-gate break; 2935*7c478bd9Sstevel@tonic-gate 2936*7c478bd9Sstevel@tonic-gate case OPARGUNIQ: 2937*7c478bd9Sstevel@tonic-gate if ((fn_op == nnode->fn_op.anon) && 2938*7c478bd9Sstevel@tonic-gate (fn_av == nnode->fn_available)) { 2939*7c478bd9Sstevel@tonic-gate error = EBUSY; 2940*7c478bd9Sstevel@tonic-gate } 2941*7c478bd9Sstevel@tonic-gate break; 2942*7c478bd9Sstevel@tonic-gate 2943*7c478bd9Sstevel@tonic-gate default: 2944*7c478bd9Sstevel@tonic-gate error = EINVAL; /* Unexpected value */ 2945*7c478bd9Sstevel@tonic-gate break; 2946*7c478bd9Sstevel@tonic-gate } 2947*7c478bd9Sstevel@tonic-gate 2948*7c478bd9Sstevel@tonic-gate if (error) 2949*7c478bd9Sstevel@tonic-gate break; 2950*7c478bd9Sstevel@tonic-gate } 2951*7c478bd9Sstevel@tonic-gate } 2952*7c478bd9Sstevel@tonic-gate 2953*7c478bd9Sstevel@tonic-gate if (error == 0) { 2954*7c478bd9Sstevel@tonic-gate /* 2955*7c478bd9Sstevel@tonic-gate * If no errors, slap the node on the list. 2956*7c478bd9Sstevel@tonic-gate * Note: The following is a structure copy. 2957*7c478bd9Sstevel@tonic-gate */ 2958*7c478bd9Sstevel@tonic-gate list->feml_nodes[++(list->feml_tos)] = *nnode; 2959*7c478bd9Sstevel@tonic-gate } 2960*7c478bd9Sstevel@tonic-gate 2961*7c478bd9Sstevel@tonic-gate fem_unlock(hd); 2962*7c478bd9Sstevel@tonic-gate return (error); 2963*7c478bd9Sstevel@tonic-gate } 2964*7c478bd9Sstevel@tonic-gate 2965*7c478bd9Sstevel@tonic-gate /* 2966*7c478bd9Sstevel@tonic-gate * Remove a node by copying the list above it down a notch. 2967*7c478bd9Sstevel@tonic-gate * If the list is busy, replace it with an idle one and work 2968*7c478bd9Sstevel@tonic-gate * upon it. 2969*7c478bd9Sstevel@tonic-gate * A node matches if the opset matches and the datap matches or is 2970*7c478bd9Sstevel@tonic-gate * null. 2971*7c478bd9Sstevel@tonic-gate */ 2972*7c478bd9Sstevel@tonic-gate 2973*7c478bd9Sstevel@tonic-gate static int 2974*7c478bd9Sstevel@tonic-gate remove_node(struct fem_list *sp, void **baseops, void *opset, void *datap) 2975*7c478bd9Sstevel@tonic-gate { 2976*7c478bd9Sstevel@tonic-gate int i; 2977*7c478bd9Sstevel@tonic-gate struct fem_node *fn; 2978*7c478bd9Sstevel@tonic-gate 2979*7c478bd9Sstevel@tonic-gate for (i = sp->feml_tos; i > 0; i--) { 2980*7c478bd9Sstevel@tonic-gate fn = sp->feml_nodes+i; 2981*7c478bd9Sstevel@tonic-gate if (fn->fn_op.anon == opset && 2982*7c478bd9Sstevel@tonic-gate (fn->fn_available == datap || datap == NULL)) { 2983*7c478bd9Sstevel@tonic-gate break; 2984*7c478bd9Sstevel@tonic-gate } 2985*7c478bd9Sstevel@tonic-gate } 2986*7c478bd9Sstevel@tonic-gate if (i == 0) { 2987*7c478bd9Sstevel@tonic-gate return (EINVAL); 2988*7c478bd9Sstevel@tonic-gate } 2989*7c478bd9Sstevel@tonic-gate 2990*7c478bd9Sstevel@tonic-gate /* 2991*7c478bd9Sstevel@tonic-gate * At this point we have a node in-hand (*fn) that we are about 2992*7c478bd9Sstevel@tonic-gate * to remove by overwriting it and adjusting the stack. This is 2993*7c478bd9Sstevel@tonic-gate * our last chance to do anything with this node so we do the 2994*7c478bd9Sstevel@tonic-gate * release on the arg. 2995*7c478bd9Sstevel@tonic-gate */ 2996*7c478bd9Sstevel@tonic-gate if (fn->fn_av_rele) 2997*7c478bd9Sstevel@tonic-gate (*(fn->fn_av_rele))(fn->fn_available); 2998*7c478bd9Sstevel@tonic-gate 2999*7c478bd9Sstevel@tonic-gate while (i++ < sp->feml_tos) { 3000*7c478bd9Sstevel@tonic-gate sp->feml_nodes[i-1] = sp->feml_nodes[i]; 3001*7c478bd9Sstevel@tonic-gate } 3002*7c478bd9Sstevel@tonic-gate if (--(sp->feml_tos) == 1) { /* Empty, restore ops */ 3003*7c478bd9Sstevel@tonic-gate *baseops = sp->feml_nodes[1].fn_op.anon; 3004*7c478bd9Sstevel@tonic-gate } 3005*7c478bd9Sstevel@tonic-gate return (0); 3006*7c478bd9Sstevel@tonic-gate } 3007*7c478bd9Sstevel@tonic-gate 3008*7c478bd9Sstevel@tonic-gate static int 3009*7c478bd9Sstevel@tonic-gate fem_remove_node(struct fem_head *fh, void **baseops, void *opset, void *datap) 3010*7c478bd9Sstevel@tonic-gate { 3011*7c478bd9Sstevel@tonic-gate struct fem_list *sp; 3012*7c478bd9Sstevel@tonic-gate int error; 3013*7c478bd9Sstevel@tonic-gate int retry; 3014*7c478bd9Sstevel@tonic-gate 3015*7c478bd9Sstevel@tonic-gate if (fh == NULL) { 3016*7c478bd9Sstevel@tonic-gate return (EINVAL); 3017*7c478bd9Sstevel@tonic-gate } 3018*7c478bd9Sstevel@tonic-gate 3019*7c478bd9Sstevel@tonic-gate do { 3020*7c478bd9Sstevel@tonic-gate retry = 0; 3021*7c478bd9Sstevel@tonic-gate if ((sp = fem_lock(fh)) == NULL) { 3022*7c478bd9Sstevel@tonic-gate fem_unlock(fh); 3023*7c478bd9Sstevel@tonic-gate error = EINVAL; 3024*7c478bd9Sstevel@tonic-gate } else if (sp->feml_refc == 1) { 3025*7c478bd9Sstevel@tonic-gate error = remove_node(sp, baseops, opset, datap); 3026*7c478bd9Sstevel@tonic-gate if (sp->feml_tos == 1) { 3027*7c478bd9Sstevel@tonic-gate /* 3028*7c478bd9Sstevel@tonic-gate * The top-of-stack was decremented by 3029*7c478bd9Sstevel@tonic-gate * remove_node(). If it got down to 1, 3030*7c478bd9Sstevel@tonic-gate * then the base ops were replaced and we 3031*7c478bd9Sstevel@tonic-gate * call fem_release() which will free the 3032*7c478bd9Sstevel@tonic-gate * fem_list. 3033*7c478bd9Sstevel@tonic-gate */ 3034*7c478bd9Sstevel@tonic-gate fem_release(sp); 3035*7c478bd9Sstevel@tonic-gate fh->femh_list = NULL; 3036*7c478bd9Sstevel@tonic-gate /* XXX - Do we need a membar_producer() call? */ 3037*7c478bd9Sstevel@tonic-gate } 3038*7c478bd9Sstevel@tonic-gate fem_unlock(fh); 3039*7c478bd9Sstevel@tonic-gate } else { 3040*7c478bd9Sstevel@tonic-gate /* busy - install a new one without this monitor */ 3041*7c478bd9Sstevel@tonic-gate struct fem_list *nsp; /* New fem_list being cloned */ 3042*7c478bd9Sstevel@tonic-gate 3043*7c478bd9Sstevel@tonic-gate fem_addref(sp); 3044*7c478bd9Sstevel@tonic-gate fem_unlock(fh); 3045*7c478bd9Sstevel@tonic-gate nsp = femlist_create(sp->feml_ssize); 3046*7c478bd9Sstevel@tonic-gate if (fem_lock(fh) == sp) { 3047*7c478bd9Sstevel@tonic-gate /* 3048*7c478bd9Sstevel@tonic-gate * We popped out of the lock, created a 3049*7c478bd9Sstevel@tonic-gate * list, then relocked. If we're in here 3050*7c478bd9Sstevel@tonic-gate * then the fem_head points to the same list 3051*7c478bd9Sstevel@tonic-gate * it started with. 3052*7c478bd9Sstevel@tonic-gate */ 3053*7c478bd9Sstevel@tonic-gate fem_dup_list(sp, nsp); 3054*7c478bd9Sstevel@tonic-gate error = remove_node(nsp, baseops, opset, datap); 3055*7c478bd9Sstevel@tonic-gate if (error != 0) { 3056*7c478bd9Sstevel@tonic-gate fem_release(nsp); 3057*7c478bd9Sstevel@tonic-gate } else if (nsp->feml_tos == 1) { 3058*7c478bd9Sstevel@tonic-gate /* New list now empty, tear it down */ 3059*7c478bd9Sstevel@tonic-gate fem_release(nsp); 3060*7c478bd9Sstevel@tonic-gate fh->femh_list = NULL; 3061*7c478bd9Sstevel@tonic-gate } else { 3062*7c478bd9Sstevel@tonic-gate fh->femh_list = nsp; 3063*7c478bd9Sstevel@tonic-gate } 3064*7c478bd9Sstevel@tonic-gate fem_delref(sp); 3065*7c478bd9Sstevel@tonic-gate } else { 3066*7c478bd9Sstevel@tonic-gate /* List changed while locked, try again... */ 3067*7c478bd9Sstevel@tonic-gate fem_release(nsp); 3068*7c478bd9Sstevel@tonic-gate retry = 1; 3069*7c478bd9Sstevel@tonic-gate } 3070*7c478bd9Sstevel@tonic-gate fem_release(sp); 3071*7c478bd9Sstevel@tonic-gate fem_unlock(fh); 3072*7c478bd9Sstevel@tonic-gate } 3073*7c478bd9Sstevel@tonic-gate } while (retry); 3074*7c478bd9Sstevel@tonic-gate return (error); 3075*7c478bd9Sstevel@tonic-gate } 3076*7c478bd9Sstevel@tonic-gate 3077*7c478bd9Sstevel@tonic-gate 3078*7c478bd9Sstevel@tonic-gate /* 3079*7c478bd9Sstevel@tonic-gate * perform operation on each element until one returns non zero 3080*7c478bd9Sstevel@tonic-gate */ 3081*7c478bd9Sstevel@tonic-gate static int 3082*7c478bd9Sstevel@tonic-gate fem_walk_list( 3083*7c478bd9Sstevel@tonic-gate struct fem_list *sp, 3084*7c478bd9Sstevel@tonic-gate int (*f)(struct fem_node *, void *, void *), 3085*7c478bd9Sstevel@tonic-gate void *mon, 3086*7c478bd9Sstevel@tonic-gate void *arg) 3087*7c478bd9Sstevel@tonic-gate { 3088*7c478bd9Sstevel@tonic-gate int i; 3089*7c478bd9Sstevel@tonic-gate 3090*7c478bd9Sstevel@tonic-gate ASSERT(sp != NULL); 3091*7c478bd9Sstevel@tonic-gate for (i = sp->feml_tos; i > 0; i--) { 3092*7c478bd9Sstevel@tonic-gate if ((*f)(sp->feml_nodes+i, mon, arg) != 0) { 3093*7c478bd9Sstevel@tonic-gate break; 3094*7c478bd9Sstevel@tonic-gate } 3095*7c478bd9Sstevel@tonic-gate } 3096*7c478bd9Sstevel@tonic-gate return (i); 3097*7c478bd9Sstevel@tonic-gate } 3098*7c478bd9Sstevel@tonic-gate 3099*7c478bd9Sstevel@tonic-gate /* 3100*7c478bd9Sstevel@tonic-gate * companion comparison functions. 3101*7c478bd9Sstevel@tonic-gate */ 3102*7c478bd9Sstevel@tonic-gate static int 3103*7c478bd9Sstevel@tonic-gate fem_compare_mon(struct fem_node *n, void *mon, void *arg) 3104*7c478bd9Sstevel@tonic-gate { 3105*7c478bd9Sstevel@tonic-gate return ((n->fn_op.anon == mon) && (n->fn_available == arg)); 3106*7c478bd9Sstevel@tonic-gate } 3107*7c478bd9Sstevel@tonic-gate 3108*7c478bd9Sstevel@tonic-gate /* 3109*7c478bd9Sstevel@tonic-gate * VNODE interposition. 3110*7c478bd9Sstevel@tonic-gate */ 3111*7c478bd9Sstevel@tonic-gate 3112*7c478bd9Sstevel@tonic-gate int 3113*7c478bd9Sstevel@tonic-gate fem_create(char *name, const struct fs_operation_def *templ, 3114*7c478bd9Sstevel@tonic-gate fem_t **actual) 3115*7c478bd9Sstevel@tonic-gate { 3116*7c478bd9Sstevel@tonic-gate int unused_ops = 0; 3117*7c478bd9Sstevel@tonic-gate int e; 3118*7c478bd9Sstevel@tonic-gate fem_t *newf; 3119*7c478bd9Sstevel@tonic-gate 3120*7c478bd9Sstevel@tonic-gate newf = fem_alloc(); 3121*7c478bd9Sstevel@tonic-gate newf->name = name; 3122*7c478bd9Sstevel@tonic-gate newf->templ = templ; 3123*7c478bd9Sstevel@tonic-gate 3124*7c478bd9Sstevel@tonic-gate e = fs_build_vector(newf, &unused_ops, fem_opdef, templ); 3125*7c478bd9Sstevel@tonic-gate if (e != 0) { 3126*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 3127*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "fem_create: error %d building vector", e); 3128*7c478bd9Sstevel@tonic-gate #endif 3129*7c478bd9Sstevel@tonic-gate fem_free(newf); 3130*7c478bd9Sstevel@tonic-gate } else { 3131*7c478bd9Sstevel@tonic-gate *actual = newf; 3132*7c478bd9Sstevel@tonic-gate } 3133*7c478bd9Sstevel@tonic-gate return (e); 3134*7c478bd9Sstevel@tonic-gate } 3135*7c478bd9Sstevel@tonic-gate 3136*7c478bd9Sstevel@tonic-gate int 3137*7c478bd9Sstevel@tonic-gate fem_install( 3138*7c478bd9Sstevel@tonic-gate vnode_t *vp, /* Vnode on which monitor is being installed */ 3139*7c478bd9Sstevel@tonic-gate fem_t *mon, /* Monitor operations being installed */ 3140*7c478bd9Sstevel@tonic-gate void *arg, /* Opaque data used by monitor */ 3141*7c478bd9Sstevel@tonic-gate femhow_t how, /* Installation control */ 3142*7c478bd9Sstevel@tonic-gate void (*arg_hold)(void *), /* Hold routine for "arg" */ 3143*7c478bd9Sstevel@tonic-gate void (*arg_rele)(void *)) /* Release routine for "arg" */ 3144*7c478bd9Sstevel@tonic-gate { 3145*7c478bd9Sstevel@tonic-gate int error; 3146*7c478bd9Sstevel@tonic-gate struct fem_node nnode; 3147*7c478bd9Sstevel@tonic-gate 3148*7c478bd9Sstevel@tonic-gate nnode.fn_available = arg; 3149*7c478bd9Sstevel@tonic-gate nnode.fn_op.fem = mon; 3150*7c478bd9Sstevel@tonic-gate nnode.fn_av_hold = arg_hold; 3151*7c478bd9Sstevel@tonic-gate nnode.fn_av_rele = arg_rele; 3152*7c478bd9Sstevel@tonic-gate /* 3153*7c478bd9Sstevel@tonic-gate * If we have a non-NULL hold function, do the hold right away. 3154*7c478bd9Sstevel@tonic-gate * The release is done in remove_node(). 3155*7c478bd9Sstevel@tonic-gate */ 3156*7c478bd9Sstevel@tonic-gate if (arg_hold) 3157*7c478bd9Sstevel@tonic-gate (*arg_hold)(arg); 3158*7c478bd9Sstevel@tonic-gate 3159*7c478bd9Sstevel@tonic-gate error = fem_push_node(&vp->v_femhead, (void **)&vp->v_op, FEMTYPE_VNODE, 3160*7c478bd9Sstevel@tonic-gate &nnode, how); 3161*7c478bd9Sstevel@tonic-gate 3162*7c478bd9Sstevel@tonic-gate /* If there was an error then the monitor wasn't pushed */ 3163*7c478bd9Sstevel@tonic-gate if (error && arg_rele) 3164*7c478bd9Sstevel@tonic-gate (*arg_rele)(arg); 3165*7c478bd9Sstevel@tonic-gate 3166*7c478bd9Sstevel@tonic-gate return (error); 3167*7c478bd9Sstevel@tonic-gate } 3168*7c478bd9Sstevel@tonic-gate 3169*7c478bd9Sstevel@tonic-gate int 3170*7c478bd9Sstevel@tonic-gate fem_is_installed(vnode_t *v, fem_t *mon, void *arg) 3171*7c478bd9Sstevel@tonic-gate { 3172*7c478bd9Sstevel@tonic-gate int e; 3173*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3174*7c478bd9Sstevel@tonic-gate 3175*7c478bd9Sstevel@tonic-gate fl = fem_get(v->v_femhead); 3176*7c478bd9Sstevel@tonic-gate if (fl != NULL) { 3177*7c478bd9Sstevel@tonic-gate e = fem_walk_list(fl, fem_compare_mon, (void *)mon, arg); 3178*7c478bd9Sstevel@tonic-gate fem_release(fl); 3179*7c478bd9Sstevel@tonic-gate return (e); 3180*7c478bd9Sstevel@tonic-gate } 3181*7c478bd9Sstevel@tonic-gate return (0); 3182*7c478bd9Sstevel@tonic-gate } 3183*7c478bd9Sstevel@tonic-gate 3184*7c478bd9Sstevel@tonic-gate int 3185*7c478bd9Sstevel@tonic-gate fem_uninstall(vnode_t *v, fem_t *mon, void *arg) 3186*7c478bd9Sstevel@tonic-gate { 3187*7c478bd9Sstevel@tonic-gate int e; 3188*7c478bd9Sstevel@tonic-gate e = fem_remove_node(v->v_femhead, (void **)&v->v_op, 3189*7c478bd9Sstevel@tonic-gate (void *)mon, arg); 3190*7c478bd9Sstevel@tonic-gate return (e); 3191*7c478bd9Sstevel@tonic-gate } 3192*7c478bd9Sstevel@tonic-gate 3193*7c478bd9Sstevel@tonic-gate void 3194*7c478bd9Sstevel@tonic-gate fem_setvnops(vnode_t *v, vnodeops_t *newops) 3195*7c478bd9Sstevel@tonic-gate { 3196*7c478bd9Sstevel@tonic-gate vnodeops_t *r; 3197*7c478bd9Sstevel@tonic-gate 3198*7c478bd9Sstevel@tonic-gate ASSERT(v != NULL); 3199*7c478bd9Sstevel@tonic-gate ASSERT(newops != NULL); 3200*7c478bd9Sstevel@tonic-gate 3201*7c478bd9Sstevel@tonic-gate do { 3202*7c478bd9Sstevel@tonic-gate r = v->v_op; 3203*7c478bd9Sstevel@tonic-gate membar_consumer(); 3204*7c478bd9Sstevel@tonic-gate if (v->v_femhead != NULL) { 3205*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3206*7c478bd9Sstevel@tonic-gate if ((fl = fem_lock(v->v_femhead)) != NULL) { 3207*7c478bd9Sstevel@tonic-gate fl->feml_nodes[1].fn_op.vnode = newops; 3208*7c478bd9Sstevel@tonic-gate fem_unlock(v->v_femhead); 3209*7c478bd9Sstevel@tonic-gate return; 3210*7c478bd9Sstevel@tonic-gate } 3211*7c478bd9Sstevel@tonic-gate fem_unlock(v->v_femhead); 3212*7c478bd9Sstevel@tonic-gate } 3213*7c478bd9Sstevel@tonic-gate } while (casptr(&v->v_op, r, newops) != r); 3214*7c478bd9Sstevel@tonic-gate } 3215*7c478bd9Sstevel@tonic-gate 3216*7c478bd9Sstevel@tonic-gate vnodeops_t * 3217*7c478bd9Sstevel@tonic-gate fem_getvnops(vnode_t *v) 3218*7c478bd9Sstevel@tonic-gate { 3219*7c478bd9Sstevel@tonic-gate vnodeops_t *r; 3220*7c478bd9Sstevel@tonic-gate 3221*7c478bd9Sstevel@tonic-gate ASSERT(v != NULL); 3222*7c478bd9Sstevel@tonic-gate 3223*7c478bd9Sstevel@tonic-gate r = v->v_op; 3224*7c478bd9Sstevel@tonic-gate membar_consumer(); 3225*7c478bd9Sstevel@tonic-gate if (v->v_femhead != NULL) { 3226*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3227*7c478bd9Sstevel@tonic-gate if ((fl = fem_lock(v->v_femhead)) != NULL) { 3228*7c478bd9Sstevel@tonic-gate r = fl->feml_nodes[1].fn_op.vnode; 3229*7c478bd9Sstevel@tonic-gate } 3230*7c478bd9Sstevel@tonic-gate fem_unlock(v->v_femhead); 3231*7c478bd9Sstevel@tonic-gate } 3232*7c478bd9Sstevel@tonic-gate return (r); 3233*7c478bd9Sstevel@tonic-gate } 3234*7c478bd9Sstevel@tonic-gate 3235*7c478bd9Sstevel@tonic-gate 3236*7c478bd9Sstevel@tonic-gate /* 3237*7c478bd9Sstevel@tonic-gate * VFS interposition 3238*7c478bd9Sstevel@tonic-gate */ 3239*7c478bd9Sstevel@tonic-gate int 3240*7c478bd9Sstevel@tonic-gate fsem_create(char *name, const struct fs_operation_def *templ, 3241*7c478bd9Sstevel@tonic-gate fsem_t **actual) 3242*7c478bd9Sstevel@tonic-gate { 3243*7c478bd9Sstevel@tonic-gate int unused_ops = 0; 3244*7c478bd9Sstevel@tonic-gate int e; 3245*7c478bd9Sstevel@tonic-gate fsem_t *newv; 3246*7c478bd9Sstevel@tonic-gate 3247*7c478bd9Sstevel@tonic-gate newv = fsem_alloc(); 3248*7c478bd9Sstevel@tonic-gate newv->name = (const char *)name; 3249*7c478bd9Sstevel@tonic-gate newv->templ = templ; 3250*7c478bd9Sstevel@tonic-gate 3251*7c478bd9Sstevel@tonic-gate e = fs_build_vector(newv, &unused_ops, fsem_opdef, templ); 3252*7c478bd9Sstevel@tonic-gate if (e != 0) { 3253*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 3254*7c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "fsem_create: error %d building vector", e); 3255*7c478bd9Sstevel@tonic-gate #endif 3256*7c478bd9Sstevel@tonic-gate fsem_free(newv); 3257*7c478bd9Sstevel@tonic-gate } else { 3258*7c478bd9Sstevel@tonic-gate *actual = newv; 3259*7c478bd9Sstevel@tonic-gate } 3260*7c478bd9Sstevel@tonic-gate return (e); 3261*7c478bd9Sstevel@tonic-gate } 3262*7c478bd9Sstevel@tonic-gate 3263*7c478bd9Sstevel@tonic-gate /* 3264*7c478bd9Sstevel@tonic-gate * These need to be re-written, but there should be more common bits. 3265*7c478bd9Sstevel@tonic-gate */ 3266*7c478bd9Sstevel@tonic-gate 3267*7c478bd9Sstevel@tonic-gate int 3268*7c478bd9Sstevel@tonic-gate fsem_is_installed(struct vfs *v, fsem_t *mon, void *arg) 3269*7c478bd9Sstevel@tonic-gate { 3270*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3271*7c478bd9Sstevel@tonic-gate 3272*7c478bd9Sstevel@tonic-gate fl = fem_get(v->vfs_femhead); 3273*7c478bd9Sstevel@tonic-gate if (fl != NULL) { 3274*7c478bd9Sstevel@tonic-gate int e; 3275*7c478bd9Sstevel@tonic-gate e = fem_walk_list(fl, fem_compare_mon, (void *)mon, arg); 3276*7c478bd9Sstevel@tonic-gate fem_release(fl); 3277*7c478bd9Sstevel@tonic-gate return (e); 3278*7c478bd9Sstevel@tonic-gate } 3279*7c478bd9Sstevel@tonic-gate return (0); 3280*7c478bd9Sstevel@tonic-gate } 3281*7c478bd9Sstevel@tonic-gate 3282*7c478bd9Sstevel@tonic-gate int 3283*7c478bd9Sstevel@tonic-gate fsem_install( 3284*7c478bd9Sstevel@tonic-gate struct vfs *vfsp, /* VFS on which monitor is being installed */ 3285*7c478bd9Sstevel@tonic-gate fsem_t *mon, /* Monitor operations being installed */ 3286*7c478bd9Sstevel@tonic-gate void *arg, /* Opaque data used by monitor */ 3287*7c478bd9Sstevel@tonic-gate femhow_t how, /* Installation control */ 3288*7c478bd9Sstevel@tonic-gate void (*arg_hold)(void *), /* Hold routine for "arg" */ 3289*7c478bd9Sstevel@tonic-gate void (*arg_rele)(void *)) /* Release routine for "arg" */ 3290*7c478bd9Sstevel@tonic-gate { 3291*7c478bd9Sstevel@tonic-gate int error; 3292*7c478bd9Sstevel@tonic-gate struct fem_node nnode; 3293*7c478bd9Sstevel@tonic-gate 3294*7c478bd9Sstevel@tonic-gate nnode.fn_available = arg; 3295*7c478bd9Sstevel@tonic-gate nnode.fn_op.fsem = mon; 3296*7c478bd9Sstevel@tonic-gate nnode.fn_av_hold = arg_hold; 3297*7c478bd9Sstevel@tonic-gate nnode.fn_av_rele = arg_rele; 3298*7c478bd9Sstevel@tonic-gate /* 3299*7c478bd9Sstevel@tonic-gate * If we have a non-NULL hold function, do the hold right away. 3300*7c478bd9Sstevel@tonic-gate * The release is done in remove_node(). 3301*7c478bd9Sstevel@tonic-gate */ 3302*7c478bd9Sstevel@tonic-gate if (arg_hold) 3303*7c478bd9Sstevel@tonic-gate (*arg_hold)(arg); 3304*7c478bd9Sstevel@tonic-gate 3305*7c478bd9Sstevel@tonic-gate error = fem_push_node(&vfsp->vfs_femhead, (void **)&vfsp->vfs_op, 3306*7c478bd9Sstevel@tonic-gate FEMTYPE_VFS, &nnode, how); 3307*7c478bd9Sstevel@tonic-gate 3308*7c478bd9Sstevel@tonic-gate /* If there was an error then the monitor wasn't pushed */ 3309*7c478bd9Sstevel@tonic-gate if (error && arg_rele) 3310*7c478bd9Sstevel@tonic-gate (*arg_rele)(arg); 3311*7c478bd9Sstevel@tonic-gate 3312*7c478bd9Sstevel@tonic-gate return (error); 3313*7c478bd9Sstevel@tonic-gate } 3314*7c478bd9Sstevel@tonic-gate 3315*7c478bd9Sstevel@tonic-gate int 3316*7c478bd9Sstevel@tonic-gate fsem_uninstall(struct vfs *v, fsem_t *mon, void *arg) 3317*7c478bd9Sstevel@tonic-gate { 3318*7c478bd9Sstevel@tonic-gate int e; 3319*7c478bd9Sstevel@tonic-gate e = fem_remove_node(v->vfs_femhead, (void **)&v->vfs_op, 3320*7c478bd9Sstevel@tonic-gate (void *)mon, arg); 3321*7c478bd9Sstevel@tonic-gate return (e); 3322*7c478bd9Sstevel@tonic-gate } 3323*7c478bd9Sstevel@tonic-gate 3324*7c478bd9Sstevel@tonic-gate void 3325*7c478bd9Sstevel@tonic-gate fsem_setvfsops(vfs_t *v, vfsops_t *newops) 3326*7c478bd9Sstevel@tonic-gate { 3327*7c478bd9Sstevel@tonic-gate vfsops_t *r; 3328*7c478bd9Sstevel@tonic-gate 3329*7c478bd9Sstevel@tonic-gate ASSERT(v != NULL); 3330*7c478bd9Sstevel@tonic-gate ASSERT(newops != NULL); 3331*7c478bd9Sstevel@tonic-gate 3332*7c478bd9Sstevel@tonic-gate do { 3333*7c478bd9Sstevel@tonic-gate r = v->vfs_op; 3334*7c478bd9Sstevel@tonic-gate membar_consumer(); 3335*7c478bd9Sstevel@tonic-gate if (v->vfs_femhead != NULL) { 3336*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3337*7c478bd9Sstevel@tonic-gate if ((fl = fem_lock(v->vfs_femhead)) != NULL) { 3338*7c478bd9Sstevel@tonic-gate fl->feml_nodes[1].fn_op.vfs = newops; 3339*7c478bd9Sstevel@tonic-gate fem_unlock(v->vfs_femhead); 3340*7c478bd9Sstevel@tonic-gate return; 3341*7c478bd9Sstevel@tonic-gate } 3342*7c478bd9Sstevel@tonic-gate fem_unlock(v->vfs_femhead); 3343*7c478bd9Sstevel@tonic-gate } 3344*7c478bd9Sstevel@tonic-gate } while (casptr(&v->vfs_op, r, newops) != r); 3345*7c478bd9Sstevel@tonic-gate } 3346*7c478bd9Sstevel@tonic-gate 3347*7c478bd9Sstevel@tonic-gate vfsops_t * 3348*7c478bd9Sstevel@tonic-gate fsem_getvfsops(vfs_t *v) 3349*7c478bd9Sstevel@tonic-gate { 3350*7c478bd9Sstevel@tonic-gate vfsops_t *r; 3351*7c478bd9Sstevel@tonic-gate 3352*7c478bd9Sstevel@tonic-gate ASSERT(v != NULL); 3353*7c478bd9Sstevel@tonic-gate 3354*7c478bd9Sstevel@tonic-gate r = v->vfs_op; 3355*7c478bd9Sstevel@tonic-gate membar_consumer(); 3356*7c478bd9Sstevel@tonic-gate if (v->vfs_femhead != NULL) { 3357*7c478bd9Sstevel@tonic-gate struct fem_list *fl; 3358*7c478bd9Sstevel@tonic-gate if ((fl = fem_lock(v->vfs_femhead)) != NULL) { 3359*7c478bd9Sstevel@tonic-gate r = fl->feml_nodes[1].fn_op.vfs; 3360*7c478bd9Sstevel@tonic-gate } 3361*7c478bd9Sstevel@tonic-gate fem_unlock(v->vfs_femhead); 3362*7c478bd9Sstevel@tonic-gate } 3363*7c478bd9Sstevel@tonic-gate return (r); 3364*7c478bd9Sstevel@tonic-gate } 3365*7c478bd9Sstevel@tonic-gate 3366*7c478bd9Sstevel@tonic-gate /* 3367*7c478bd9Sstevel@tonic-gate * Setup FEM. 3368*7c478bd9Sstevel@tonic-gate */ 3369*7c478bd9Sstevel@tonic-gate void 3370*7c478bd9Sstevel@tonic-gate fem_init() 3371*7c478bd9Sstevel@tonic-gate { 3372*7c478bd9Sstevel@tonic-gate struct fem_type_info *fi; 3373*7c478bd9Sstevel@tonic-gate 3374*7c478bd9Sstevel@tonic-gate /* 3375*7c478bd9Sstevel@tonic-gate * This femtype is only used for fem_list creation so we only 3376*7c478bd9Sstevel@tonic-gate * need the "guard" to be initialized so that feml_tos has 3377*7c478bd9Sstevel@tonic-gate * some rudimentary meaning. A fem_list must not be used until 3378*7c478bd9Sstevel@tonic-gate * it has been initialized (either via femlist_construct() or 3379*7c478bd9Sstevel@tonic-gate * fem_dup_list()). Anything that tries to use this fem_list 3380*7c478bd9Sstevel@tonic-gate * before it's actually initialized would panic the system as 3381*7c478bd9Sstevel@tonic-gate * soon as "fn_op" (NULL) is dereferenced. 3382*7c478bd9Sstevel@tonic-gate */ 3383*7c478bd9Sstevel@tonic-gate fi = femtype + FEMTYPE_NULL; 3384*7c478bd9Sstevel@tonic-gate fi->errf = fem_err; 3385*7c478bd9Sstevel@tonic-gate fi->guard.fn_available = (void *)&fi->guard; 3386*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_hold = NULL; 3387*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_rele = NULL; 3388*7c478bd9Sstevel@tonic-gate fi->guard.fn_op.anon = NULL; 3389*7c478bd9Sstevel@tonic-gate 3390*7c478bd9Sstevel@tonic-gate fi = femtype + FEMTYPE_VNODE; 3391*7c478bd9Sstevel@tonic-gate fi->errf = fem_err; 3392*7c478bd9Sstevel@tonic-gate fi->head.fn_available = NULL; 3393*7c478bd9Sstevel@tonic-gate fi->head.fn_av_hold = NULL; 3394*7c478bd9Sstevel@tonic-gate fi->head.fn_av_rele = NULL; 3395*7c478bd9Sstevel@tonic-gate (void) vn_make_ops("fem-head", fhead_vn_spec, &fi->head.fn_op.vnode); 3396*7c478bd9Sstevel@tonic-gate fi->guard.fn_available = (void *)&fi->guard; 3397*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_hold = NULL; 3398*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_rele = NULL; 3399*7c478bd9Sstevel@tonic-gate (void) fem_create("fem-guard", fem_guard_ops, &fi->guard.fn_op.fem); 3400*7c478bd9Sstevel@tonic-gate 3401*7c478bd9Sstevel@tonic-gate fi = femtype + FEMTYPE_VFS; 3402*7c478bd9Sstevel@tonic-gate fi->errf = fsem_err; 3403*7c478bd9Sstevel@tonic-gate fi->head.fn_available = NULL; 3404*7c478bd9Sstevel@tonic-gate fi->head.fn_av_hold = NULL; 3405*7c478bd9Sstevel@tonic-gate fi->head.fn_av_rele = NULL; 3406*7c478bd9Sstevel@tonic-gate (void) vfs_makefsops(fshead_vfs_spec, &fi->head.fn_op.vfs); 3407*7c478bd9Sstevel@tonic-gate 3408*7c478bd9Sstevel@tonic-gate fi->guard.fn_available = (void *)&fi->guard; 3409*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_hold = NULL; 3410*7c478bd9Sstevel@tonic-gate fi->guard.fn_av_rele = NULL; 3411*7c478bd9Sstevel@tonic-gate (void) fsem_create("fem-guard", fsem_guard_ops, &fi->guard.fn_op.fsem); 3412*7c478bd9Sstevel@tonic-gate } 3413*7c478bd9Sstevel@tonic-gate 3414*7c478bd9Sstevel@tonic-gate 3415*7c478bd9Sstevel@tonic-gate int 3416*7c478bd9Sstevel@tonic-gate fem_err() 3417*7c478bd9Sstevel@tonic-gate { 3418*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "fem/vnode operations corrupt"); 3419*7c478bd9Sstevel@tonic-gate return (0); 3420*7c478bd9Sstevel@tonic-gate } 3421*7c478bd9Sstevel@tonic-gate 3422*7c478bd9Sstevel@tonic-gate int 3423*7c478bd9Sstevel@tonic-gate fsem_err() 3424*7c478bd9Sstevel@tonic-gate { 3425*7c478bd9Sstevel@tonic-gate cmn_err(CE_PANIC, "fem/vfs operations corrupt"); 3426*7c478bd9Sstevel@tonic-gate return (0); 3427*7c478bd9Sstevel@tonic-gate } 3428