diff --git a/include/os/freebsd/spl/sys/mod_os.h b/include/os/freebsd/spl/sys/mod_os.h index 9b1bdfbff..5b3b3271e 100644 --- a/include/os/freebsd/spl/sys/mod_os.h +++ b/include/os/freebsd/spl/sys/mod_os.h @@ -57,6 +57,8 @@ #define ZFS_MODULE_PARAM_CALL(scope_prefix, name_prefix, name, func, _, perm, desc) \ ZFS_MODULE_PARAM_CALL_IMPL(_vfs_ ## scope_prefix, name, perm, func ## _args(name_prefix ## name), desc) +#define ZFS_MODULE_VIRTUAL_PARAM_CALL ZFS_MODULE_PARAM_CALL + #define param_set_arc_long_args(var) \ CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU" @@ -84,6 +86,9 @@ #define param_set_max_auto_ashift_args(var) \ CTLTYPE_U64, &var, 0, param_set_max_auto_ashift, "QU" +#define fletcher_4_param_set_args(var) \ + CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A" + #include #define module_init(fn) \ static void \ diff --git a/include/os/linux/kernel/linux/mod_compat.h b/include/os/linux/kernel/linux/mod_compat.h index 62905240b..e96e95313 100644 --- a/include/os/linux/kernel/linux/mod_compat.h +++ b/include/os/linux/kernel/linux/mod_compat.h @@ -144,6 +144,17 @@ enum scope_prefix_types { MODULE_PARM_DESC(name_prefix ## name, desc) /* END CSTYLED */ +/* + * As above, but there is no variable with the name name_prefix ## name, + * so NULL is passed to module_param_call instead. + */ +/* BEGIN CSTYLED */ +#define ZFS_MODULE_VIRTUAL_PARAM_CALL(scope_prefix, name_prefix, name, setfunc, getfunc, perm, desc) \ + CTASSERT_GLOBAL((sizeof (scope_prefix) == sizeof (enum scope_prefix_types))); \ + module_param_call(name_prefix ## name, setfunc, getfunc, NULL, perm); \ + MODULE_PARM_DESC(name_prefix ## name, desc) +/* END CSTYLED */ + #define ZFS_MODULE_PARAM_ARGS const char *buf, zfs_kernel_param_t *kp #define ZFS_MODULE_DESCRIPTION(s) MODULE_DESCRIPTION(s) diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c index c5e63a878..7a9de4a43 100644 --- a/module/zcommon/zfs_fletcher.c +++ b/module/zcommon/zfs_fletcher.c @@ -885,23 +885,26 @@ zio_abd_checksum_func_t fletcher_4_abd_ops = { .acf_iter = abd_fletcher_4_iter }; +#if defined(_KERNEL) -#if defined(_KERNEL) && defined(__linux__) +#define IMPL_FMT(impl, i) (((impl) == (i)) ? "[%s] " : "%s ") + +#if defined(__linux__) static int fletcher_4_param_get(char *buffer, zfs_kernel_param_t *unused) { const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen); char *fmt; - int i, cnt = 0; + int cnt = 0; /* list fastest */ - fmt = (impl == IMPL_FASTEST) ? "[%s] " : "%s "; + fmt = IMPL_FMT(impl, IMPL_FASTEST); cnt += sprintf(buffer + cnt, fmt, "fastest"); /* list all supported implementations */ - for (i = 0; i < fletcher_4_supp_impls_cnt; i++) { - fmt = (i == impl) ? "[%s] " : "%s "; + for (uint32_t i = 0; i < fletcher_4_supp_impls_cnt; ++i) { + fmt = IMPL_FMT(impl, i); cnt += sprintf(buffer + cnt, fmt, fletcher_4_supp_impls[i]->name); } @@ -915,14 +918,62 @@ fletcher_4_param_set(const char *val, zfs_kernel_param_t *unused) return (fletcher_4_impl_set(val)); } +#else + +#include + +static int +fletcher_4_param(ZFS_MODULE_PARAM_ARGS) +{ + int err; + + if (req->newptr == NULL) { + const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen); + const int init_buflen = 64; + const char *fmt; + struct sbuf *s; + + s = sbuf_new_for_sysctl(NULL, NULL, init_buflen, req); + + /* list fastest */ + fmt = IMPL_FMT(impl, IMPL_FASTEST); + (void) sbuf_printf(s, fmt, "fastest"); + + /* list all supported implementations */ + for (uint32_t i = 0; i < fletcher_4_supp_impls_cnt; ++i) { + fmt = IMPL_FMT(impl, i); + (void) sbuf_printf(s, fmt, + fletcher_4_supp_impls[i]->name); + } + + err = sbuf_finish(s); + sbuf_delete(s); + + return (err); + } + + char buf[16]; + + err = sysctl_handle_string(oidp, buf, sizeof (buf), req); + if (err) + return (err); + return (-fletcher_4_impl_set(buf)); +} + +#endif + +#undef IMPL_FMT + /* * Choose a fletcher 4 implementation in ZFS. * Users can choose "cycle" to exercise all implementations, but this is * for testing purpose therefore it can only be set in user space. */ -module_param_call(zfs_fletcher_4_impl, - fletcher_4_param_set, fletcher_4_param_get, NULL, 0644); -MODULE_PARM_DESC(zfs_fletcher_4_impl, "Select fletcher 4 implementation."); +/* BEGIN CSTYLED */ +ZFS_MODULE_VIRTUAL_PARAM_CALL(zfs, zfs_, fletcher_4_impl, + fletcher_4_param_set, fletcher_4_param_get, ZMOD_RW, + "Select fletcher 4 implementation."); +/* END CSTYLED */ EXPORT_SYMBOL(fletcher_init); EXPORT_SYMBOL(fletcher_2_incremental_native);