Zfs.exports
From OpenZFS on OS X
zfs.exports[edit]
We used to list functions from XNU's private.exports, and using a codeless kext let's us call them. With 2.0 re-port, we no longer use zfs.exports, but it would be nice to have some calls back.
_cpu_number ARM64 Comment: Used to spread out lock contention, we use the lock at active-core-index Alternative: None, only using [0] on arm64. Result: performance penalty
_fp_lookup _fp_drop _fp_drop_written _fo_read _fo_write Comment: "zfs send" and "zfs recv" will either do IO on a file (vnode) or pipe. There is no way to do IO on a pipe in a kext without private.exports. Alternative: userland will mknod /tmp/.pipe, spawn a relay helper, and open(/tmp/.pipe) which passes a vnode to kernel. This works, but is complicated, both setting up pipes, and cleaning up. Especially with SIGINT involved. It would be nice to do pipe IO in kext. Result: Complicated code, but already working. Pipes love to deadlock, so corner cases could exist.
_vnode_iocount Comment: Used to know if VFS will re-enter before vnode_put(). Alternative: ((int32_t *)vp)[25] - disgusting, but no choice. Really don't want to look in struct vnode. Result: None, but if struct vnode changes we explode.
_hostname Comment: uses hostname for diagnostic messages, history logs and multihost mounting (failover would display which host stopped and which host took over.) Alternative: None. Some work arounds could be done, like passing hostname from userland. Hashing hostid as string. Result: user confusion to which host was in use. (Until work around)
_virtual_space_start _virtual_space_end _vm_page_free_wanted _vm_page_free_count _vm_page_free_min _vm_page_speculative_count _vm_pool_low Comment: used to detect memory pressure well before jettison. Alternative: implement with optional hardcap limit, mach_vm_pressure_level_monitor and mach_vm_pressure_monitor. Result: Hopefully can be made to run the same, without stutter.
_VFS_ROOT _rootvnode Comment: Used with boot to know when root has been mounted. vfs_rootvnode() does not check for NULL and will just panic. Alternative: None, It would be better if vfs_rootvnode() would not panic. Result: No boot support.
_cache_purgevfs Comment: Used to drop all cache entires for a mount, for example "zfs rollback". Alternative: Implemented with vnode_iterate(cache_purge_negatives() cache_purge()). Working. Result: None. Happy to live without.
_vfs_context_kernel Comment: Used at times when it is correct to use kernel context. Like hfs.kext does as well. Alternative: None Result: No idea, seems to run any way
_vnode_lookupat Comment: Look up a "file" from a directory is useful. Alternative: Implemented with vn_getpath() strcat("/file" and vnode_lookup(). Result: Some string work in kernel, not "that" expensive. Still, vnode_lookupat would be nice.
_kvtophys __mh_execute_header _gLoadedKextSummaries Comment: Used only in debug/panic. To lookup symbols when dumping stack. Alternatives: None, and even harder with arm64's PAC. Can live without. Result: Stack dumps with addresses only, use lldb to resolve symbols.
_kauth_cred_getgroups Comment: Getting a list of other groups, to check for permission. Alternative: Get list of permissions, and compare with _kauth_cred_ismember_gid Result: No difference, just #ifdef in upstream
_cpuid_info Comment: Get CPU features, sse, avx, aes etc. Alternative: inline asm { cpuid }, and create own bit checks. Result: None, just a shame to not be able to use XNU existing API.
thread_set_cpulimit Comment: thread_set_cpulimit() is used to emulate Illumos's duty cycle, and asks xnu to limit a thread's scheduling to less than 100% of a cpu : if over a period of time the thread uses more than that, it is put to sleep for a period before being allowed to continue. The sysdc thread is put into this mode in spa.c. This thread is bursty, and trips the cpu limit from time to time. Alternative: none Result: We have lived (and so can keep living) without it in 2.x, but would be nice to have for smoothness
throttle_set_thread_io_policy Comment: throttle_set_io_policy() lets us passivate our threads so that if they generate IOKit calls they do not get counted by the IO throttle. By default, kernel threads have high priority, so this thread serves to improve the performance of other I/O versus hdiutil-attached images in datasets (which otherwise are promoted from passive to high priority), and zvols with HFS or APFS inside. Alternative: none Result: We have lived (and so can keep living) without it in 2.x, but would be nice to have for smoothness