diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 index 932342cfda21..bb54b77fcbbf 100644 --- a/man/man5/zfs-module-parameters.5 +++ b/man/man5/zfs-module-parameters.5 @@ -1049,6 +1049,26 @@ See the section "ZFS I/O SCHEDULER". Default value: \fB1\fR. .RE +.sp +.ne 2 +.na +\fBzfs_vdev_parallel_open_enabled\fR (bool) +.ad +.RS 12n +Accelerates vdev open from pool import or reopen from reload from cache by +allow child vdevs to be opened in parallel. +.sp +This almost always deadlocks in unsupported stacked ZFS configurations where a +zvol from one pool is the vdev for another pool via another type of block +device. Some logic exists in the kernel module to disable this in the direct +case when there is nothing in-between, but it is impossible to detect the +indirect case where another block device exists inbetween. Disabling this will +often make stacked ZFS configurations work, but they continue to be an +unsupported configuration because it is subjected to regression testing. +.sp +Use \fB1\fR for yes (default) and \fB0\fR for no. +.RE + .sp .ne 2 .na diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 5ff5cf3b1271..16bf7aae066e 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -51,6 +51,11 @@ */ int metaslabs_per_vdev = 200; +/* + * Allow system administrator to disable parallel open optimization so that + * unsupported ZFS on something else on zvol is semi-safe. + */ +int zfs_vdev_parallel_open_enabled = 1; /* * Virtual device management. */ @@ -1136,7 +1141,7 @@ vdev_uses_zvols(vdev_t *vd) int c; #ifdef _KERNEL - if (zvol_is_zvol(vd->vdev_path)) + if (zfs_vdev_parallel_open_enabled == 0 || zvol_is_zvol(vd->vdev_path)) return (B_TRUE); #endif @@ -3642,6 +3647,10 @@ EXPORT_SYMBOL(vdev_online); EXPORT_SYMBOL(vdev_offline); EXPORT_SYMBOL(vdev_clear); +module_param(zfs_vdev_parallel_open_enabled, int, 0644); +MODULE_PARM_DESC(zfs_vdev_parallel_open_enabled, + "Open vdev children in parallel during import."); + module_param(metaslabs_per_vdev, int, 0644); MODULE_PARM_DESC(metaslabs_per_vdev, "Divide added vdev into approximately (but no more than) this number "