From: Olaf Faaland Date: Fri, 11 May 2018 19:46:07 +0000 (-0700) Subject: module param callbacks check for initialized spa X-Git-Tag: zfs-0.7.10~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3eef58c9b6753fac47cd0640207873b83432efc7;p=zfs module param callbacks check for initialized spa Callbacks provided for module parameters are executed both after the module is loaded, when a user alters it via sysfs, e.g echo bar > /sys/modules/zfs/parameters/foo as well as when the module is loaded with an argument, e.g. modprobe zfs foo=bar In the latter case, the init functions likely have not run yet, including spa_init() which initializes the namespace lock so it is safe to use. Instead of immediately taking the namespace lock and attemping to iterate over initialized spa structures, check whether spa_mode_global is nonzero. This is set by spa_init() after it has initialized the namespace lock. Reviewed-by: Brian Behlendorf Reviewed-by: Tim Chase Signed-off-by: Olaf Faaland Closes #7496 Closes #7521 --- diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index 3b74a6b61..7523310cd 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -607,7 +607,8 @@ param_set_multihost_interval(const char *val, zfs_kernel_param_t *kp) if (ret < 0) return (ret); - mmp_signal_all_threads(); + if (spa_mode_global != 0) + mmp_signal_all_threads(); return (ret); } diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index d62128353..6761e755a 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -815,19 +815,21 @@ param_set_vdev_scheduler(const char *val, zfs_kernel_param_t *kp) if ((p = strchr(val, '\n')) != NULL) *p = '\0'; - mutex_enter(&spa_namespace_lock); - while ((spa = spa_next(spa)) != NULL) { - if (spa_state(spa) != POOL_STATE_ACTIVE || - !spa_writeable(spa) || spa_suspended(spa)) - continue; - - spa_open_ref(spa, FTAG); - mutex_exit(&spa_namespace_lock); - vdev_elevator_switch(spa->spa_root_vdev, (char *)val); + if (spa_mode_global != 0) { mutex_enter(&spa_namespace_lock); - spa_close(spa, FTAG); + while ((spa = spa_next(spa)) != NULL) { + if (spa_state(spa) != POOL_STATE_ACTIVE || + !spa_writeable(spa) || spa_suspended(spa)) + continue; + + spa_open_ref(spa, FTAG); + mutex_exit(&spa_namespace_lock); + vdev_elevator_switch(spa->spa_root_vdev, (char *)val); + mutex_enter(&spa_namespace_lock); + spa_close(spa, FTAG); + } + mutex_exit(&spa_namespace_lock); } - mutex_exit(&spa_namespace_lock); return (param_set_charp(val, kp)); }