257 * action. Instead, we specify the VFS error function, with fs_error(), but
258 * note that fs_error() is not actually called. Instead it results in the
259 * use of the error function defined for the particular VOP, in vn_ops_table[]:
260 *
261 * - frlock, dispose, shrlock.
262 *
263 *
264 * These VOPs we define to use the corresponding regular NFSv4 vnodeop.
265 * NOTE: if any of these ops involve an OTW call with the stub FH, then
266 * that call must be wrapped with save_mnt_secinfo()/check_mnt_secinfo()
267 * to protect the security data in the servinfo4_t for the "parent"
268 * filesystem that contains the stub.
269 *
270 * - These VOPs should not trigger a mount, so that "ls -l" does not:
271 * pathconf, getsecattr.
272 *
273 * - These VOPs would not make sense to trigger:
274 * inactive, rwlock, rwunlock, fid, realvp.
275 */
276 const fs_operation_def_t nfs4_trigger_vnodeops_template[] = {
277 VOPNAME_OPEN, { .vop_open = nfs4_trigger_open },
278 VOPNAME_GETATTR, { .vop_getattr = nfs4_trigger_getattr },
279 VOPNAME_SETATTR, { .vop_setattr = nfs4_trigger_setattr },
280 VOPNAME_ACCESS, { .vop_access = nfs4_trigger_access },
281 VOPNAME_LOOKUP, { .vop_lookup = nfs4_trigger_lookup },
282 VOPNAME_CREATE, { .vop_create = nfs4_trigger_create },
283 VOPNAME_REMOVE, { .vop_remove = nfs4_trigger_remove },
284 VOPNAME_LINK, { .vop_link = nfs4_trigger_link },
285 VOPNAME_RENAME, { .vop_rename = nfs4_trigger_rename },
286 VOPNAME_MKDIR, { .vop_mkdir = nfs4_trigger_mkdir },
287 VOPNAME_RMDIR, { .vop_rmdir = nfs4_trigger_rmdir },
288 VOPNAME_SYMLINK, { .vop_symlink = nfs4_trigger_symlink },
289 VOPNAME_READLINK, { .vop_readlink = nfs4_trigger_readlink },
290 VOPNAME_INACTIVE, { .vop_inactive = nfs4_inactive },
291 VOPNAME_FID, { .vop_fid = nfs4_fid },
292 VOPNAME_RWLOCK, { .vop_rwlock = nfs4_rwlock },
293 VOPNAME_RWUNLOCK, { .vop_rwunlock = nfs4_rwunlock },
294 VOPNAME_REALVP, { .vop_realvp = nfs4_realvp },
295 VOPNAME_GETSECATTR, { .vop_getsecattr = nfs4_getsecattr },
296 VOPNAME_PATHCONF, { .vop_pathconf = nfs4_pathconf },
297 VOPNAME_FRLOCK, { .error = fs_error },
298 VOPNAME_DISPOSE, { .error = fs_error },
299 VOPNAME_SHRLOCK, { .error = fs_error },
300 VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support },
301 NULL, NULL
302 };
303
304 static void
305 nfs4_ephemeral_tree_incr(nfs4_ephemeral_tree_t *net)
306 {
307 ASSERT(mutex_owned(&net->net_cnt_lock));
308 net->net_refcnt++;
309 ASSERT(net->net_refcnt != 0);
310 }
311
312 static void
313 nfs4_ephemeral_tree_hold(nfs4_ephemeral_tree_t *net)
314 {
315 mutex_enter(&net->net_cnt_lock);
316 nfs4_ephemeral_tree_incr(net);
317 mutex_exit(&net->net_cnt_lock);
318 }
319
320 /*
321 * We need a safe way to decrement the refcnt whilst the
|
257 * action. Instead, we specify the VFS error function, with fs_error(), but
258 * note that fs_error() is not actually called. Instead it results in the
259 * use of the error function defined for the particular VOP, in vn_ops_table[]:
260 *
261 * - frlock, dispose, shrlock.
262 *
263 *
264 * These VOPs we define to use the corresponding regular NFSv4 vnodeop.
265 * NOTE: if any of these ops involve an OTW call with the stub FH, then
266 * that call must be wrapped with save_mnt_secinfo()/check_mnt_secinfo()
267 * to protect the security data in the servinfo4_t for the "parent"
268 * filesystem that contains the stub.
269 *
270 * - These VOPs should not trigger a mount, so that "ls -l" does not:
271 * pathconf, getsecattr.
272 *
273 * - These VOPs would not make sense to trigger:
274 * inactive, rwlock, rwunlock, fid, realvp.
275 */
276 const fs_operation_def_t nfs4_trigger_vnodeops_template[] = {
277 { VOPNAME_OPEN, { .vop_open = nfs4_trigger_open } },
278 { VOPNAME_GETATTR, { .vop_getattr = nfs4_trigger_getattr } },
279 { VOPNAME_SETATTR, { .vop_setattr = nfs4_trigger_setattr } },
280 { VOPNAME_ACCESS, { .vop_access = nfs4_trigger_access } },
281 { VOPNAME_LOOKUP, { .vop_lookup = nfs4_trigger_lookup } },
282 { VOPNAME_CREATE, { .vop_create = nfs4_trigger_create } },
283 { VOPNAME_REMOVE, { .vop_remove = nfs4_trigger_remove } },
284 { VOPNAME_LINK, { .vop_link = nfs4_trigger_link } },
285 { VOPNAME_RENAME, { .vop_rename = nfs4_trigger_rename } },
286 { VOPNAME_MKDIR, { .vop_mkdir = nfs4_trigger_mkdir } },
287 { VOPNAME_RMDIR, { .vop_rmdir = nfs4_trigger_rmdir } },
288 { VOPNAME_SYMLINK, { .vop_symlink = nfs4_trigger_symlink } },
289 { VOPNAME_READLINK, { .vop_readlink = nfs4_trigger_readlink } },
290 { VOPNAME_INACTIVE, { .vop_inactive = nfs4_inactive } },
291 { VOPNAME_FID, { .vop_fid = nfs4_fid } },
292 { VOPNAME_RWLOCK, { .vop_rwlock = nfs4_rwlock } },
293 { VOPNAME_RWUNLOCK, { .vop_rwunlock = nfs4_rwunlock } },
294 { VOPNAME_REALVP, { .vop_realvp = nfs4_realvp } },
295 { VOPNAME_GETSECATTR, { .vop_getsecattr = nfs4_getsecattr } },
296 { VOPNAME_PATHCONF, { .vop_pathconf = nfs4_pathconf } },
297 { VOPNAME_FRLOCK, { .error = fs_error } },
298 { VOPNAME_DISPOSE, { .error = fs_error } },
299 { VOPNAME_SHRLOCK, { .error = fs_error } },
300 { VOPNAME_VNEVENT, { .vop_vnevent = fs_vnevent_support } },
301 { NULL, {NULL } }
302 };
303
304 static void
305 nfs4_ephemeral_tree_incr(nfs4_ephemeral_tree_t *net)
306 {
307 ASSERT(mutex_owned(&net->net_cnt_lock));
308 net->net_refcnt++;
309 ASSERT(net->net_refcnt != 0);
310 }
311
312 static void
313 nfs4_ephemeral_tree_hold(nfs4_ephemeral_tree_t *net)
314 {
315 mutex_enter(&net->net_cnt_lock);
316 nfs4_ephemeral_tree_incr(net);
317 mutex_exit(&net->net_cnt_lock);
318 }
319
320 /*
321 * We need a safe way to decrement the refcnt whilst the
|