diff --git a/module/zfs/spa.c b/module/zfs/spa.c index e986e92..65f78b7 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -64,6 +64,7 @@ #include #include #include +#include #ifdef _KERNEL #include @@ -2856,6 +2857,7 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy, spa_load_state_t state = SPA_LOAD_OPEN; int error; int locked = B_FALSE; + int firstopen = B_FALSE; *spapp = NULL; @@ -2879,6 +2881,8 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy, if (spa->spa_state == POOL_STATE_UNINITIALIZED) { zpool_rewind_policy_t policy; + firstopen = B_TRUE; + zpool_get_rewind_policy(nvpolicy ? nvpolicy : spa->spa_config, &policy); if (policy.zrp_request & ZPOOL_DO_REWIND) @@ -2953,6 +2957,11 @@ spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t *nvpolicy, mutex_exit(&spa_namespace_lock); } +#ifdef _KERNEL + if (firstopen) + zvol_create_minors(spa->spa_name); +#endif + *spapp = spa; return (0); @@ -4010,6 +4019,10 @@ spa_import(const char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags) mutex_exit(&spa_namespace_lock); spa_history_log_version(spa, LOG_POOL_IMPORT); +#ifdef _KERNEL + zvol_create_minors(pool); +#endif + return (0); } diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 1226b2c..a9184a1 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -1268,9 +1268,6 @@ zfs_ioc_pool_import(zfs_cmd_t *zc) error = err; } - if (error == 0) - zvol_create_minors(zc->zc_name); - nvlist_free(config); if (props) diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 43a7bb6..e35c91b 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1215,6 +1215,9 @@ zvol_alloc(dev_t dev, const char *name) zv = kmem_zalloc(sizeof (zvol_state_t), KM_SLEEP); + spin_lock_init(&zv->zv_lock); + list_link_init(&zv->zv_next); + zv->zv_queue = blk_init_queue(zvol_request, &zv->zv_lock); if (zv->zv_queue == NULL) goto out_kmem; @@ -1248,9 +1251,6 @@ zvol_alloc(dev_t dev, const char *name) sizeof (rl_t), offsetof(rl_t, r_node)); zv->zv_znode.z_is_zvol = TRUE; - spin_lock_init(&zv->zv_lock); - list_link_init(&zv->zv_next); - zv->zv_disk->major = zvol_major; zv->zv_disk->first_minor = (dev & MINORMASK); zv->zv_disk->fops = &zvol_ops; @@ -1561,30 +1561,36 @@ zvol_init(void) { int error; + list_create(&zvol_state_list, sizeof (zvol_state_t), + offsetof(zvol_state_t, zv_next)); + mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL); + zvol_taskq = taskq_create(ZVOL_DRIVER, zvol_threads, maxclsyspri, zvol_threads, INT_MAX, TASKQ_PREPOPULATE); if (zvol_taskq == NULL) { printk(KERN_INFO "ZFS: taskq_create() failed\n"); - return (-ENOMEM); + error = -ENOMEM; + goto out1; } error = register_blkdev(zvol_major, ZVOL_DRIVER); if (error) { printk(KERN_INFO "ZFS: register_blkdev() failed %d\n", error); - taskq_destroy(zvol_taskq); - return (error); + goto out2; } blk_register_region(MKDEV(zvol_major, 0), 1UL << MINORBITS, THIS_MODULE, zvol_probe, NULL, NULL); - mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL); - list_create(&zvol_state_list, sizeof (zvol_state_t), - offsetof(zvol_state_t, zv_next)); + return (0); - (void) zvol_create_minors(NULL); +out2: + taskq_destroy(zvol_taskq); +out1: + mutex_destroy(&zvol_state_lock); + list_destroy(&zvol_state_list); - return (0); + return (error); } void diff --git a/scripts/zconfig.sh b/scripts/zconfig.sh index 141348c..281166c 100755 --- a/scripts/zconfig.sh +++ b/scripts/zconfig.sh @@ -264,8 +264,9 @@ test_4() { zconfig_zvol_device_stat 0 ${POOL_NAME} ${FULL_ZVOL_NAME} \ ${FULL_SNAP_NAME} ${FULL_CLONE_NAME} || fail 9 - # Load the modules, wait 1 second for udev + # Load the modules, list the pools to ensure they are opened ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 10 + ${ZPOOL} list &>/dev/null # Verify the devices were created zconfig_zvol_device_stat 10 ${POOL_NAME} ${FULL_ZVOL_NAME} \ diff --git a/udev/rules.d/90-zfs.rules.in b/udev/rules.d/90-zfs.rules.in index 52e1d63..a2715d2 100644 --- a/udev/rules.d/90-zfs.rules.in +++ b/udev/rules.d/90-zfs.rules.in @@ -1,4 +1,4 @@ -SUBSYSTEM!="block", GOTO="zfs_end" +SUBSYSTEM!="block|misc", GOTO="zfs_end" ACTION!="add|change", GOTO="zfs_end" ENV{ID_FS_TYPE}=="zfs", RUN+="/sbin/modprobe zfs" @@ -7,4 +7,6 @@ ENV{ID_FS_TYPE}=="zfs_member", RUN+="/sbin/modprobe zfs" KERNEL=="null", SYMLINK+="root" SYMLINK=="null", SYMLINK+="root" +SUBSYSTEM=="misc", KERNEL=="zfs", RUN+="@sbindir@/zpool list" + LABEL="zfs_end"