]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/spa.c
Fix hung z_zvol tasks during 'zfs receive'
[mirror_zfs.git] / module / zfs / spa.c
index 736b51feae1e67aa7cfab77e2dc987bbe52ba8b0..4b6196cc3610105e80d4671a730cbdbb6853934a 100644 (file)
@@ -1186,6 +1186,14 @@ spa_activate(spa_t *spa, int mode)
        spa->spa_zvol_taskq = taskq_create("z_zvol", 1, defclsyspri,
            1, INT_MAX, 0);
 
+       /*
+        * Taskq dedicated to prefetcher threads: this is used to prevent the
+        * pool traverse code from monopolizing the global (and limited)
+        * system_taskq by inappropriately scheduling long running tasks on it.
+        */
+       spa->spa_prefetch_taskq = taskq_create("z_prefetch", boot_ncpus,
+           defclsyspri, 1, INT_MAX, TASKQ_DYNAMIC);
+
        /*
         * The taskq to upgrade datasets in this pool. Currently used by
         * feature SPA_FEATURE_USEROBJ_ACCOUNTING/SPA_FEATURE_PROJECT_QUOTA.
@@ -1213,6 +1221,11 @@ spa_deactivate(spa_t *spa)
                spa->spa_zvol_taskq = NULL;
        }
 
+       if (spa->spa_prefetch_taskq) {
+               taskq_destroy(spa->spa_prefetch_taskq);
+               spa->spa_prefetch_taskq = NULL;
+       }
+
        if (spa->spa_upgrade_taskq) {
                taskq_destroy(spa->spa_upgrade_taskq);
                spa->spa_upgrade_taskq = NULL;
@@ -3766,10 +3779,14 @@ spa_get_stats(const char *name, nvlist_t **config,
                            ZPOOL_CONFIG_ERRCOUNT,
                            spa_get_errlog_size(spa)) == 0);
 
-                       if (spa_suspended(spa))
+                       if (spa_suspended(spa)) {
                                VERIFY(nvlist_add_uint64(*config,
                                    ZPOOL_CONFIG_SUSPENDED,
                                    spa->spa_failmode) == 0);
+                               VERIFY(nvlist_add_uint64(*config,
+                                   ZPOOL_CONFIG_SUSPENDED_REASON,
+                                   spa->spa_suspended) == 0);
+                       }
 
                        spa_add_spares(spa, *config);
                        spa_add_l2cache(spa, *config);
@@ -6984,7 +7001,7 @@ spa_sync(spa_t *spa, uint64_t txg)
 
                if (error == 0)
                        break;
-               zio_suspend(spa, NULL);
+               zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR);
                zio_resume_wait(spa);
        }
        dmu_tx_commit(tx);