--- /dev/null
+From f016c38557e02d98bf08b0fc392db00fd4f65107 Mon Sep 17 00:00:00 2001
+From: Darik Horn <dajhorn@vanadac.com>
+Date: Fri, 1 Jun 2012 20:49:10 -0500
+Subject: [PATCH 8/8] Add zvol_inhibit_dev module option.
+
+ZoL can create more zvols at runtime than can be configured during
+system start, which hangs the init stack at reboot.
+
+When a slow system has more than a few hundred zvols, udev will
+fork bomb during system start and spend too much time in device
+detection routines, so upstart kills it.
+
+The zfs_inhibit_dev option allows an affected system to be rescued
+by skipping /dev/zd* creation and thereby avoiding the udev
+overload. All zvols are made inaccessible if this option is set, but
+the `zfs destroy` and `zfs send` commands still work, and ZFS
+filesystems can be mounted.
+---
+ module/zfs/zvol.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
+index 9b13134..5ec8374 100644
+--- a/module/zfs/zvol.c
++++ b/module/zfs/zvol.c
+@@ -46,6 +46,7 @@
+ #include <sys/zvol.h>
+ #include <linux/blkdev_compat.h>
+
++unsigned int zvol_inhibit_dev = 0;
+ unsigned int zvol_major = ZVOL_MAJOR;
+ unsigned int zvol_threads = 32;
+
+@@ -1337,6 +1338,9 @@ zvol_create_minors(const char *pool)
+ spa_t *spa = NULL;
+ int error = 0;
+
++ if (zvol_inhibit_dev)
++ return;
++
+ mutex_enter(&zvol_state_lock);
+ if (pool) {
+ error = dmu_objset_find_spa(NULL, pool, zvol_create_minors_cb,
+@@ -1366,6 +1370,9 @@ zvol_remove_minors(const char *pool)
+ zvol_state_t *zv, *zv_next;
+ char *str;
+
++ if (zvol_inhibit_dev)
++ return;
++
+ str = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
+ if (pool) {
+ (void) strncpy(str, pool, strlen(pool));
+@@ -1427,6 +1434,9 @@ zvol_fini(void)
+ list_destroy(&zvol_state_list);
+ }
+
++module_param(zvol_inhibit_dev, uint, 0444);
++MODULE_PARM_DESC(zvol_inhibit_dev, "Do not create zvol device nodes");
++
+ module_param(zvol_major, uint, 0444);
+ MODULE_PARM_DESC(zvol_major, "Major number for zvol device");
+
+--
+1.7.9.5
+