+#ifdef KERNEL_PRIVATE
+/*
+ * For use with SPI to create trigger vnodes.
+ */
+struct vnode_trigger_param;
+#define VNCREATE_TRIGGER (('T' << 8) + ('V'))
+#define VNCREATE_TRIGGER_SIZE sizeof(struct vnode_trigger_param)
+#endif /* KERNEL_PRIVATE */
+
+
+#ifdef KERNEL_PRIVATE
+/*
+ * Resolver callback SPI for trigger vnodes
+ *
+ * Only available from kernels built with CONFIG_TRIGGERS option
+ */
+
+/*!
+ @enum Pathname Lookup Operations
+ @abstract Constants defining pathname operations (passed to resolver callbacks)
+ */
+enum path_operation {
+ OP_LOOKUP,
+ OP_MOUNT,
+ OP_UNMOUNT,
+ OP_STATFS,
+ OP_OPEN,
+ OP_LINK,
+ OP_UNLINK,
+ OP_RENAME,
+ OP_CHDIR,
+ OP_CHROOT,
+ OP_MKNOD,
+ OP_MKFIFO,
+ OP_SYMLINK,
+ OP_ACCESS,
+ OP_PATHCONF,
+ OP_READLINK,
+ OP_GETATTR,
+ OP_SETATTR,
+ OP_TRUNCATE,
+ OP_COPYFILE,
+ OP_MKDIR,
+ OP_RMDIR,
+ OP_REVOKE,
+ OP_EXCHANGEDATA,
+ OP_SEARCHFS,
+ OP_FSCTL,
+ OP_GETXATTR,
+ OP_SETXATTR,
+ OP_REMOVEXATTR,
+ OP_LISTXATTR,
+ OP_MAXOP /* anything beyond previous entry is invalid */
+};
+
+/*!
+ @enum resolver status
+ @abstract Constants defining resolver status
+ @constant RESOLVER_RESOLVED the resolver has finished (typically means a successful mount)
+ @constant RESOLVER_NOCHANGE the resolver status didn't change
+ @constant RESOLVER_UNRESOLVED the resolver has finished (typically means a successful unmount)
+ @constant RESOLVER_ERROR the resolver encountered an error (errno passed in aux value)
+ @constant RESOLVER_STOP a request to destroy trigger XXX do we need this???
+ */
+enum resolver_status {
+ RESOLVER_RESOLVED,
+ RESOLVER_NOCHANGE,
+ RESOLVER_UNRESOLVED,
+ RESOLVER_ERROR,
+ RESOLVER_STOP
+};
+
+typedef uint64_t resolver_result_t;
+
+/*
+ * Compound resolver result
+ *
+ * The trigger vnode callbacks use a compound result value. In addition
+ * to the resolver status, it contains a sequence number and an auxiliary
+ * value.
+ *
+ * The sequence value is used by VFS to sequence-stamp trigger vnode
+ * state transitions. It is expected to be incremented each time a
+ * resolver changes state (ie resolved or unresolved). A result
+ * containing a stale sequence (older than a trigger vnode's current
+ * value) will be ignored by VFS.
+ *
+ * The auxiliary value is currently only used to deliver the errno
+ * value for RESOLVER_ERROR status conditions. When a RESOLVER_ERROR
+ * occurs, VFS will propagate this error back to the syscall that
+ * encountered the trigger vnode.
+ */
+extern resolver_result_t vfs_resolver_result(uint32_t seq, enum resolver_status stat, int aux);
+
+/*
+ * Extract values from a compound resolver result
+ */
+extern enum resolver_status vfs_resolver_status(resolver_result_t);
+extern uint32_t vfs_resolver_sequence(resolver_result_t);
+extern int vfs_resolver_auxiliary(resolver_result_t);
+
+
+/*!
+ @typedef trigger_vnode_resolve_callback_t
+ @abstract function prototype for a trigger vnode resolve callback
+ @discussion This function is associated with a trigger vnode during a vnode create. It is
+ typically called when a lookup operation occurs for a trigger vnode
+ @param vp The trigger vnode which needs resolving
+ @param cnp Various data about lookup, e.g. filename and state flags
+ @param pop The pathname operation that initiated the lookup (see enum path_operation).
+ @param flags resolve flags
+ @param data Arbitrary data supplied by vnode trigger creator
+ @param ctx Context for authentication.
+ @return RESOLVER_RESOLVED, RESOLVER_NOCHANGE, RESOLVER_UNRESOLVED or RESOLVER_ERROR
+*/
+typedef resolver_result_t (* trigger_vnode_resolve_callback_t)(
+ vnode_t vp,
+ const struct componentname * cnp,
+ enum path_operation pop,
+ int flags,
+ void * data,
+ vfs_context_t ctx);
+
+/*!
+ @typedef trigger_vnode_unresolve_callback_t
+ @abstract function prototype for a trigger vnode unresolve callback
+ @discussion This function is associated with a trigger vnode during a vnode create. It is
+ called to unresolve a trigger vnode (typically this means unmount).
+ @param vp The trigger vnode which needs unresolving
+ @param flags Unmount flags
+ @param data Arbitrary data supplied by vnode trigger creator
+ @param ctx Context for authentication.
+ @return RESOLVER_NOCHANGE, RESOLVER_UNRESOLVED or RESOLVER_ERROR
+*/
+typedef resolver_result_t (* trigger_vnode_unresolve_callback_t)(
+ vnode_t vp,
+ int flags,
+ void * data,
+ vfs_context_t ctx);
+
+/*!
+ @typedef trigger_vnode_rearm_callback_t
+ @abstract function prototype for a trigger vnode rearm callback
+ @discussion This function is associated with a trigger vnode during a vnode create. It is
+ called to verify a rearm from VFS (i.e. should VFS rearm the trigger?).
+ @param vp The trigger vnode which needs rearming
+ @param flags rearm flags
+ @param data Arbitrary data supplied by vnode trigger creator
+ @param ctx Context for authentication.
+ @return RESOLVER_NOCHANGE or RESOLVER_ERROR
+*/
+typedef resolver_result_t (* trigger_vnode_rearm_callback_t)(
+ vnode_t vp,
+ int flags,
+ void * data,
+ vfs_context_t ctx);
+
+/*!
+ @typedef trigger_vnode_reclaim_callback_t
+ @abstract function prototype for a trigger vnode reclaim callback
+ @discussion This function is associated with a trigger vnode during a vnode create. It is
+ called to deallocate private callback argument data
+ @param vp The trigger vnode associated with the data
+ @param data The arbitrary data supplied by vnode trigger creator
+*/
+typedef void (* trigger_vnode_reclaim_callback_t)(
+ vnode_t vp,
+ void * data);
+
+/*!
+ @function vnode_trigger_update
+ @abstract Update a trigger vnode's state.
+ @discussion This allows a resolver to notify VFS of a state change in a trigger vnode.
+ @param vp The trigger vnode whose information to update.
+ @param result A compound resolver result value
+ @return EINVAL if result value is invalid or vp isn't a trigger vnode
+ */
+extern int vnode_trigger_update(vnode_t vp, resolver_result_t result);
+
+struct vnode_trigger_info {
+ trigger_vnode_resolve_callback_t vti_resolve_func;
+ trigger_vnode_unresolve_callback_t vti_unresolve_func;
+ trigger_vnode_rearm_callback_t vti_rearm_func;
+ trigger_vnode_reclaim_callback_t vti_reclaim_func;
+ void * vti_data; /* auxiliary data (optional) */
+ uint32_t vti_flags; /* optional flags (see below) */
+};
+
+/*
+ * SPI for creating a trigger vnode
+ *
+ * Uses the VNCREATE_TRIGGER flavor with existing vnode_create() KPI
+ *
+ * Only one resolver per vnode.
+ *
+ * ERRORS (in addition to vnode_create errors):
+ * EINVAL (invalid resolver info, like invalid flags)
+ * ENOTDIR (only directories can have a resolver)
+ * EPERM (vnode cannot be a trigger - eg root dir of a file system)
+ * ENOMEM
+ */
+struct vnode_trigger_param {
+ struct vnode_fsparam vnt_params; /* same as for VNCREATE_FLAVOR */
+ trigger_vnode_resolve_callback_t vnt_resolve_func;
+ trigger_vnode_unresolve_callback_t vnt_unresolve_func;
+ trigger_vnode_rearm_callback_t vnt_rearm_func;
+ trigger_vnode_reclaim_callback_t vnt_reclaim_func;
+ void * vnt_data; /* auxiliary data (optional) */
+ uint32_t vnt_flags; /* optional flags (see below) */
+};
+
+/*
+ * vnode trigger flags (vnt_flags)
+ *
+ * VNT_AUTO_REARM:
+ * On unmounts of a trigger mount, automatically re-arm the trigger.
+ *
+ * VNT_NO_DIRECT_MOUNT:
+ * A trigger vnode instance that doesn't directly trigger a mount,
+ * instead it triggers the mounting of sub-trigger nodes.
+ */
+#define VNT_AUTO_REARM (1 << 0)
+#define VNT_NO_DIRECT_MOUNT (1 << 1)
+#define VNT_VALID_MASK (VNT_AUTO_REARM | VNT_NO_DIRECT_MOUNT)
+
+#endif /* KERNEL_PRIVATE */
+