From d1bade1b129357f3f7086f0c1decdc6bda257136 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sun, 16 Oct 2016 14:02:47 -0400 Subject: [PATCH] Add zfs_vdev_parallel_open_enabled module option Parallel vdev open causes the driver to deadlock when running ZFS on top of a zvol with something in between, including, but not limited to the loop device. Such configurations are historically unsupported. However, enough people have requested the capability over the years that we ought to give them a knob to make the configuration work in most instances. We have tests for the direct case, but the indirect case continues to be unsupported. Signed-off-by: Richard Yao --- man/man5/zfs-module-parameters.5 | 15 +++++++++++++++ module/zfs/vdev.c | 13 ++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 index 2fbab1d010de..68a857a36e36 100644 --- a/man/man5/zfs-module-parameters.5 +++ b/man/man5/zfs-module-parameters.5 @@ -1091,6 +1091,21 @@ queue's min_active. See the section "ZFS I/O SCHEDULER". Default value: \fB1,000\fR. .RE +.sp +.ne 2 +.na +\fBzfs_vdev_parallel_open_enabled\fR (int) +.ad +.RS 12n +Accelerates vdev opening during pool import by allowing all devices to be +opened in parallel. This should be enabled for pools constructed from +independent physical devices. For configurations where a zvol from one pool +is used as vdev in another this option should be disabled. This is needed +in order to avoid a potential deadlock during pool import. +.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 dfb1ef522868..d95b730fba85 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -55,6 +55,12 @@ */ int metaslabs_per_vdev = 200; +/* + * Allow a system administrator to disable the parallel vdev open + * optimization so it's semi-safe to layer pools on top of zvols. + */ +int zfs_vdev_parallel_open_enabled = 1; + /* * Virtual device management. */ @@ -1159,7 +1165,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 @@ -3703,7 +3709,12 @@ EXPORT_SYMBOL(vdev_degrade); EXPORT_SYMBOL(vdev_online); EXPORT_SYMBOL(vdev_offline); EXPORT_SYMBOL(vdev_clear); + /* BEGIN CSTYLED */ +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 "