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


  60 #include <sys/callb.h>
  61 #include <sys/systeminfo.h>
  62 #include <sys/spa_boot.h>
  63 #include <sys/zfs_ioctl.h>
  64 #include <sys/dsl_scan.h>
  65 #include <sys/zfeature.h>
  66 #include <sys/dsl_destroy.h>
  67 
  68 #ifdef  _KERNEL
  69 #include <sys/bootprops.h>
  70 #include <sys/callb.h>
  71 #include <sys/cpupart.h>
  72 #include <sys/pool.h>
  73 #include <sys/sysdc.h>
  74 #include <sys/zone.h>
  75 #endif  /* _KERNEL */
  76 
  77 #include "zfs_prop.h"
  78 #include "zfs_comutil.h"
  79 






  80 typedef enum zti_modes {
  81         ZTI_MODE_FIXED,                 /* value is # of threads (min 1) */
  82         ZTI_MODE_ONLINE_PERCENT,        /* value is % of online CPUs */
  83         ZTI_MODE_BATCH,                 /* cpu-intensive; value is ignored */
  84         ZTI_MODE_NULL,                  /* don't create a taskq */
  85         ZTI_NMODES
  86 } zti_modes_t;
  87 
  88 #define ZTI_P(n, q)     { ZTI_MODE_FIXED, (n), (q) }
  89 #define ZTI_PCT(n)      { ZTI_MODE_ONLINE_PERCENT, (n), 1 }
  90 #define ZTI_BATCH       { ZTI_MODE_BATCH, 0, 1 }
  91 #define ZTI_NULL        { ZTI_MODE_NULL, 0, 0 }
  92 
  93 #define ZTI_N(n)        ZTI_P(n, 1)
  94 #define ZTI_ONE         ZTI_N(1)
  95 
  96 typedef struct zio_taskq_info {
  97         zti_modes_t zti_mode;
  98         uint_t zti_value;
  99         uint_t zti_count;


5644 
5645 void
5646 spa_async_suspend(spa_t *spa)
5647 {
5648         mutex_enter(&spa->spa_async_lock);
5649         spa->spa_async_suspended++;
5650         while (spa->spa_async_thread != NULL)
5651                 cv_wait(&spa->spa_async_cv, &spa->spa_async_lock);
5652         mutex_exit(&spa->spa_async_lock);
5653 }
5654 
5655 void
5656 spa_async_resume(spa_t *spa)
5657 {
5658         mutex_enter(&spa->spa_async_lock);
5659         ASSERT(spa->spa_async_suspended != 0);
5660         spa->spa_async_suspended--;
5661         mutex_exit(&spa->spa_async_lock);
5662 }
5663 



















5664 static void
5665 spa_async_dispatch(spa_t *spa)
5666 {
5667         mutex_enter(&spa->spa_async_lock);
5668         if (spa->spa_async_tasks && !spa->spa_async_suspended &&

5669             spa->spa_async_thread == NULL &&
5670             rootdir != NULL && !vn_is_readonly(rootdir))
5671                 spa->spa_async_thread = thread_create(NULL, 0,
5672                     spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
5673         mutex_exit(&spa->spa_async_lock);
5674 }
5675 
5676 void
5677 spa_async_request(spa_t *spa, int task)
5678 {
5679         zfs_dbgmsg("spa=%s async request task=%u", spa->spa_name, task);
5680         mutex_enter(&spa->spa_async_lock);
5681         spa->spa_async_tasks |= task;
5682         mutex_exit(&spa->spa_async_lock);
5683 }
5684 
5685 /*
5686  * ==========================================================================
5687  * SPA syncing routines
5688  * ==========================================================================
5689  */
5690 




  60 #include <sys/callb.h>
  61 #include <sys/systeminfo.h>
  62 #include <sys/spa_boot.h>
  63 #include <sys/zfs_ioctl.h>
  64 #include <sys/dsl_scan.h>
  65 #include <sys/zfeature.h>
  66 #include <sys/dsl_destroy.h>
  67 
  68 #ifdef  _KERNEL
  69 #include <sys/bootprops.h>
  70 #include <sys/callb.h>
  71 #include <sys/cpupart.h>
  72 #include <sys/pool.h>
  73 #include <sys/sysdc.h>
  74 #include <sys/zone.h>
  75 #endif  /* _KERNEL */
  76 
  77 #include "zfs_prop.h"
  78 #include "zfs_comutil.h"
  79 
  80 /*
  81  * The interval at which failed configuration cache file writes
  82  * should be retried.
  83  */
  84 static int zfs_ccw_retry_interval = 300;
  85 
  86 typedef enum zti_modes {
  87         ZTI_MODE_FIXED,                 /* value is # of threads (min 1) */
  88         ZTI_MODE_ONLINE_PERCENT,        /* value is % of online CPUs */
  89         ZTI_MODE_BATCH,                 /* cpu-intensive; value is ignored */
  90         ZTI_MODE_NULL,                  /* don't create a taskq */
  91         ZTI_NMODES
  92 } zti_modes_t;
  93 
  94 #define ZTI_P(n, q)     { ZTI_MODE_FIXED, (n), (q) }
  95 #define ZTI_PCT(n)      { ZTI_MODE_ONLINE_PERCENT, (n), 1 }
  96 #define ZTI_BATCH       { ZTI_MODE_BATCH, 0, 1 }
  97 #define ZTI_NULL        { ZTI_MODE_NULL, 0, 0 }
  98 
  99 #define ZTI_N(n)        ZTI_P(n, 1)
 100 #define ZTI_ONE         ZTI_N(1)
 101 
 102 typedef struct zio_taskq_info {
 103         zti_modes_t zti_mode;
 104         uint_t zti_value;
 105         uint_t zti_count;


5650 
5651 void
5652 spa_async_suspend(spa_t *spa)
5653 {
5654         mutex_enter(&spa->spa_async_lock);
5655         spa->spa_async_suspended++;
5656         while (spa->spa_async_thread != NULL)
5657                 cv_wait(&spa->spa_async_cv, &spa->spa_async_lock);
5658         mutex_exit(&spa->spa_async_lock);
5659 }
5660 
5661 void
5662 spa_async_resume(spa_t *spa)
5663 {
5664         mutex_enter(&spa->spa_async_lock);
5665         ASSERT(spa->spa_async_suspended != 0);
5666         spa->spa_async_suspended--;
5667         mutex_exit(&spa->spa_async_lock);
5668 }
5669 
5670 static int
5671 spa_async_tasks_pending(spa_t *spa)
5672 {
5673         u_int non_config_tasks;
5674         u_int config_task;
5675         boolean_t config_task_suspended;
5676 
5677         non_config_tasks = spa->spa_async_tasks & ~SPA_ASYNC_CONFIG_UPDATE;
5678         config_task = spa->spa_async_tasks & SPA_ASYNC_CONFIG_UPDATE;
5679         if (spa->spa_ccw_fail_time == 0)
5680                 config_task_suspended = B_FALSE;
5681         else
5682                 config_task_suspended =
5683                     (ddi_get_lbolt64() - spa->spa_ccw_fail_time)
5684                   < (zfs_ccw_retry_interval * hz);
5685 
5686         return (non_config_tasks || (config_task && !config_task_suspended));
5687 }
5688 
5689 static void
5690 spa_async_dispatch(spa_t *spa)
5691 {
5692         mutex_enter(&spa->spa_async_lock);
5693         if (spa_async_tasks_pending(spa) &&
5694             !spa->spa_async_suspended &&
5695             spa->spa_async_thread == NULL &&
5696             rootdir != NULL)
5697                 spa->spa_async_thread = thread_create(NULL, 0,
5698                     spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
5699         mutex_exit(&spa->spa_async_lock);
5700 }
5701 
5702 void
5703 spa_async_request(spa_t *spa, int task)
5704 {
5705         zfs_dbgmsg("spa=%s async request task=%u", spa->spa_name, task);
5706         mutex_enter(&spa->spa_async_lock);
5707         spa->spa_async_tasks |= task;
5708         mutex_exit(&spa->spa_async_lock);
5709 }
5710 
5711 /*
5712  * ==========================================================================
5713  * SPA syncing routines
5714  * ==========================================================================
5715  */
5716