summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2009-08-17 08:36:41 +0000
committerpjd <pjd@FreeBSD.org>2009-08-17 08:36:41 +0000
commitecef618a3741ef25f71cc6f035412f57986febec (patch)
tree34a52543947457c64be57000b3649f8c12080bc7
parent6ccc3544c4c22badc215fc72175b55fa9fa201eb (diff)
downloadFreeBSD-src-ecef618a3741ef25f71cc6f035412f57986febec.zip
FreeBSD-src-ecef618a3741ef25f71cc6f035412f57986febec.tar.gz
- Fix a race where /dev/zfs control device is created before ZFS is fully
initialized. Also destroy /dev/zfs before doing other deinitializations. - Initialization through taskq is no longer needed and there is a race where one of the zpool/zfs command loads zfs.ko and tries to do some work immediately, but /dev/zfs is not there yet. Reported by: pav Approved by: re (kib)
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index f2c6e76..ded407e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -3056,44 +3056,35 @@ zfsdev_fini(void)
destroy_dev(zfsdev);
}
-static struct task zfs_start_task;
static struct root_hold_token *zfs_root_token;
-
uint_t zfs_fsyncer_key;
extern uint_t rrw_tsd_key;
-static void
-zfs_start(void *context __unused, int pending __unused)
-{
-
- zfsdev_init();
- spa_init(FREAD | FWRITE);
- zfs_init();
- zvol_init();
-
- tsd_create(&zfs_fsyncer_key, NULL);
- tsd_create(&rrw_tsd_key, NULL);
-
- printf("ZFS storage pool version " SPA_VERSION_STRING "\n");
- root_mount_rel(zfs_root_token);
-}
-
static int
zfs_modevent(module_t mod, int type, void *unused __unused)
{
- int error;
+ int error = 0;
- error = EOPNOTSUPP;
switch (type) {
case MOD_LOAD:
zfs_root_token = root_mount_hold("ZFS");
printf("WARNING: ZFS is considered to be an experimental "
"feature in FreeBSD.\n");
- TASK_INIT(&zfs_start_task, 0, zfs_start, NULL);
- taskqueue_enqueue(taskqueue_thread, &zfs_start_task);
+
mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
- error = 0;
+
+ spa_init(FREAD | FWRITE);
+ zfs_init();
+ zvol_init();
+
+ tsd_create(&zfs_fsyncer_key, NULL);
+ tsd_create(&rrw_tsd_key, NULL);
+
+ printf("ZFS storage pool version " SPA_VERSION_STRING "\n");
+ root_mount_rel(zfs_root_token);
+
+ zfsdev_init();
break;
case MOD_UNLOAD:
if (spa_busy() || zfs_busy() || zvol_busy() ||
@@ -3101,14 +3092,19 @@ zfs_modevent(module_t mod, int type, void *unused __unused)
error = EBUSY;
break;
}
+
+ zfsdev_fini();
zvol_fini();
zfs_fini();
spa_fini();
- zfsdev_fini();
+
tsd_destroy(&zfs_fsyncer_key);
tsd_destroy(&rrw_tsd_key);
+
mutex_destroy(&zfs_share_lock);
- error = 0;
+ break;
+ default:
+ error = EOPNOTSUPP;
break;
}
return (error);
OpenPOWER on IntegriCloud