diff options
author | Boris Protopopov <[email protected]> | 2014-03-22 05:07:14 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-03-10 09:49:22 -0800 |
commit | a0bd735adb1b1eb81fef10b4db102ee051c4d4ff (patch) | |
tree | 121fcde3000a116f0c33143b28a530a87fd6073a /module/zfs/zfs_ioctl.c | |
parent | eb0856779f7b57162c9179f238104f6d6e150745 (diff) |
Add support for asynchronous zvol minor operations
zfsonlinux issue #2217 - zvol minor operations: check snapdev
property before traversing snapshots of a dataset
zfsonlinux issue #3681 - lock order inversion between zvol_open()
and dsl_pool_sync()...zvol_rename_minors()
Create a per-pool zvol taskq for asynchronous zvol tasks.
There are a few key design decisions to be aware of.
* Each taskq must be single threaded to ensure tasks are always
processed in the order in which they were dispatched.
* There is a taskq per-pool in order to keep the pools independent.
This way if one pool is suspended it will not impact another.
* The preferred location to dispatch a zvol minor task is a sync
task. In this context there is easy access to the spa_t and
minimal error handling is required because the sync task must
succeed.
Support for asynchronous zvol minor operations address issue #3681.
Signed-off-by: Boris Protopopov <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2217
Closes #3678
Closes #3681
Diffstat (limited to 'module/zfs/zfs_ioctl.c')
-rw-r--r-- | module/zfs/zfs_ioctl.c | 50 |
1 files changed, 12 insertions, 38 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 746a3f0fc..5c84d238f 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -29,6 +29,7 @@ * Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. + * Copyright (c) 2016 Actifio, Inc. All rights reserved. */ /* @@ -1499,8 +1500,7 @@ zfs_ioc_pool_destroy(zfs_cmd_t *zc) int error; zfs_log_history(zc); error = spa_destroy(zc->zc_name); - if (error == 0) - zvol_remove_minors(zc->zc_name); + return (error); } @@ -1552,8 +1552,7 @@ zfs_ioc_pool_export(zfs_cmd_t *zc) zfs_log_history(zc); error = spa_export(zc->zc_name, NULL, force, hardforce); - if (error == 0) - zvol_remove_minors(zc->zc_name); + return (error); } @@ -2394,7 +2393,7 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, err = zvol_set_volsize(dsname, intval); break; case ZFS_PROP_SNAPDEV: - err = zvol_set_snapdev(dsname, intval); + err = zvol_set_snapdev(dsname, source, intval); break; case ZFS_PROP_VERSION: { @@ -3188,12 +3187,6 @@ zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) if (error != 0) (void) dsl_destroy_head(fsname); } - -#ifdef _KERNEL - if (error == 0 && type == DMU_OST_ZVOL) - zvol_create_minors(fsname); -#endif - return (error); } @@ -3236,12 +3229,6 @@ zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl) if (error != 0) (void) dsl_destroy_head(fsname); } - -#ifdef _KERNEL - if (error == 0) - zvol_create_minors(fsname); -#endif - return (error); } @@ -3304,11 +3291,6 @@ zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl) error = dsl_dataset_snapshot(snaps, props, outnvl); -#ifdef _KERNEL - if (error == 0) - zvol_create_minors(poolname); -#endif - return (error); } @@ -3434,7 +3416,6 @@ zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl) for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL; pair = nvlist_next_nvpair(snaps, pair)) { (void) zfs_unmount_snap(nvpair_name(pair)); - (void) zvol_remove_minor(nvpair_name(pair)); } return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl)); @@ -3560,8 +3541,7 @@ zfs_ioc_destroy(zfs_cmd_t *zc) err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy); else err = dsl_destroy_head(zc->zc_name); - if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0) - (void) zvol_remove_minor(zc->zc_name); + return (err); } @@ -4127,11 +4107,6 @@ zfs_ioc_recv(zfs_cmd_t *zc) } #endif -#ifdef _KERNEL - if (error == 0) - zvol_create_minors(tofs); -#endif - /* * On error, restore the original props. */ @@ -6032,16 +6007,16 @@ _init(void) return (error); } + if ((error = -zvol_init()) != 0) + return (error); + spa_init(FREAD | FWRITE); zfs_init(); - if ((error = -zvol_init()) != 0) - goto out1; - zfs_ioctl_init(); if ((error = zfs_attach()) != 0) - goto out2; + goto out; tsd_create(&zfs_fsyncer_key, NULL); tsd_create(&rrw_tsd_key, rrw_tsd_destroy); @@ -6057,11 +6032,10 @@ _init(void) return (0); -out2: - (void) zvol_fini(); -out1: +out: zfs_fini(); spa_fini(); + (void) zvol_fini(); printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s" ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR, error); @@ -6073,9 +6047,9 @@ static void __exit _fini(void) { zfs_detach(); - zvol_fini(); zfs_fini(); spa_fini(); + zvol_fini(); tsd_destroy(&zfs_fsyncer_key); tsd_destroy(&rrw_tsd_key); |