]> git.proxmox.com Git - mirror_zfs.git/commitdiff
module param callbacks check for initialized spa
authorOlaf Faaland <faaland1@llnl.gov>
Fri, 11 May 2018 19:46:07 +0000 (12:46 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 11 May 2018 19:46:07 +0000 (12:46 -0700)
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 <behlendorf1@llnl.gov>
Reviewed-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
Closes #7496
Closes #7521

module/zfs/mmp.c
module/zfs/vdev_disk.c

index 48aab673ad5ea9391f6744e3e652bc104fb08ead..f51952ee40820c354823e00b3e4a9b323d3ff752 100644 (file)
@@ -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);
 }
index f537c0d27b2b6b6ae6e9a4ae7f271d88e855eeb2..9c3a1ba802102de8c9e541ec61d5cb008880f3dc 100644 (file)
@@ -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));
 }