Print this page
3749 zfs event processing should work on R/O root filesystems
Submitted by:   Justin Gibbs <justing@spectralogic.com>
Reviewed by:    Matthew Ahrens <mahrens@delphix.com>
Reviewed by:    Eric Schrock <eric.schrock@delphix.com>
        
*** 75,84 ****
--- 75,90 ----
  #endif  /* _KERNEL */
  
  #include "zfs_prop.h"
  #include "zfs_comutil.h"
  
+ /*
+  * The interval, in seconds, 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,5675 ****
          ASSERT(spa->spa_async_suspended != 0);
          spa->spa_async_suspended--;
          mutex_exit(&spa->spa_async_lock);
  }
  
  static void
  spa_async_dispatch(spa_t *spa)
  {
          mutex_enter(&spa->spa_async_lock);
!         if (spa->spa_async_tasks && !spa->spa_async_suspended &&
              spa->spa_async_thread == NULL &&
!             rootdir != NULL && !vn_is_readonly(rootdir))
                  spa->spa_async_thread = thread_create(NULL, 0,
                      spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
          mutex_exit(&spa->spa_async_lock);
  }
  
--- 5665,5702 ----
          ASSERT(spa->spa_async_suspended != 0);
          spa->spa_async_suspended--;
          mutex_exit(&spa->spa_async_lock);
  }
  
+ static boolean_t
+ 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 =
+                     (gethrtime() - spa->spa_ccw_fail_time) <
+                     (zfs_ccw_retry_interval * NANOSEC);
+         }
+ 
+         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_async_tasks_pending(spa) &&
!             !spa->spa_async_suspended &&
              spa->spa_async_thread == NULL &&
!             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);
  }