diff options
author | Olaf Faaland <[email protected]> | 2018-05-11 12:46:07 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-05-11 12:46:07 -0700 |
commit | bc5f51c5de21fd8b7cf3110801a6b1db1e4c3d0a (patch) | |
tree | 9781fdf091e1a1e364f4ae8a6f1d7ff133da2206 | |
parent | 68fded814692c6a7fa7ca1f584a34a92aaa279af (diff) |
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 <[email protected]>
Reviewed-by: Tim Chase <[email protected]>
Signed-off-by: Olaf Faaland <[email protected]>
Closes #7496
Closes #7521
-rw-r--r-- | module/zfs/mmp.c | 3 | ||||
-rw-r--r-- | module/zfs/vdev_disk.c | 24 |
2 files changed, 15 insertions, 12 deletions
diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index 48aab673a..f51952ee4 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -609,7 +609,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 f537c0d27..9c3a1ba80 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -818,19 +818,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)); } |