diff options
author | pjd <pjd@FreeBSD.org> | 2009-08-17 08:36:41 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2009-08-17 08:36:41 +0000 |
commit | ecef618a3741ef25f71cc6f035412f57986febec (patch) | |
tree | 34a52543947457c64be57000b3649f8c12080bc7 | |
parent | 6ccc3544c4c22badc215fc72175b55fa9fa201eb (diff) | |
download | FreeBSD-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.c | 46 |
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); |