Print this page
3749 zfs event processing should work on R/O root filesystems
Submitted by:   Justin Gibbs <justing@spectralogic.com>

@@ -75,10 +75,16 @@
 #endif  /* _KERNEL */
 
 #include "zfs_prop.h"
 #include "zfs_comutil.h"
 
+/*
+ * The interval at which failed configuration cache file writes
+ * should be retried.
+ */
+static int zfs_ccw_retry_interval = 300;
+
 typedef enum zti_modes {
         ZTI_MODE_FIXED,                 /* value is # of threads (min 1) */
         ZTI_MODE_ONLINE_PERCENT,        /* value is % of online CPUs */
         ZTI_MODE_BATCH,                 /* cpu-intensive; value is ignored */
         ZTI_MODE_NULL,                  /* don't create a taskq */

@@ -5659,17 +5665,37 @@
         ASSERT(spa->spa_async_suspended != 0);
         spa->spa_async_suspended--;
         mutex_exit(&spa->spa_async_lock);
 }
 
+static int
+spa_async_tasks_pending(spa_t *spa)
+{
+        u_int non_config_tasks;
+        u_int config_task;
+        boolean_t config_task_suspended;
+
+        non_config_tasks = spa->spa_async_tasks & ~SPA_ASYNC_CONFIG_UPDATE;
+        config_task = spa->spa_async_tasks & SPA_ASYNC_CONFIG_UPDATE;
+        if (spa->spa_ccw_fail_time == 0)
+                config_task_suspended = B_FALSE;
+        else
+                config_task_suspended =
+                    (ddi_get_lbolt64() - spa->spa_ccw_fail_time)
+                  < (zfs_ccw_retry_interval * hz);
+
+        return (non_config_tasks || (config_task && !config_task_suspended));
+}
+
 static void
 spa_async_dispatch(spa_t *spa)
 {
         mutex_enter(&spa->spa_async_lock);
-        if (spa->spa_async_tasks && !spa->spa_async_suspended &&
+        if (spa_async_tasks_pending(spa) &&
+            !spa->spa_async_suspended &&
             spa->spa_async_thread == NULL &&
-            rootdir != NULL && !vn_is_readonly(rootdir))
+            rootdir != NULL)
                 spa->spa_async_thread = thread_create(NULL, 0,
                     spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
         mutex_exit(&spa->spa_async_lock);
 }