mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 11:47:43 +03:00
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 <boris.protopopov@actifio.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2217 Closes #3678 Closes #3681
This commit is contained in:
committed by
Brian Behlendorf
parent
eb0856779f
commit
a0bd735adb
+30
-7
@@ -24,6 +24,7 @@
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013, 2014, Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1136,6 +1137,24 @@ spa_activate(spa_t *spa, int mode)
|
||||
avl_create(&spa->spa_errlist_last,
|
||||
spa_error_entry_compare, sizeof (spa_error_entry_t),
|
||||
offsetof(spa_error_entry_t, se_avl));
|
||||
|
||||
/*
|
||||
* This taskq is used to perform zvol-minor-related tasks
|
||||
* asynchronously. This has several advantages, including easy
|
||||
* resolution of various deadlocks (zfsonlinux bug #3681).
|
||||
*
|
||||
* The taskq must be single threaded to ensure tasks are always
|
||||
* processed in the order in which they were dispatched.
|
||||
*
|
||||
* A taskq per pool allows one 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.
|
||||
*/
|
||||
spa->spa_zvol_taskq = taskq_create("z_zvol", 1, defclsyspri,
|
||||
1, INT_MAX, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1154,6 +1173,11 @@ spa_deactivate(spa_t *spa)
|
||||
|
||||
spa_evicting_os_wait(spa);
|
||||
|
||||
if (spa->spa_zvol_taskq) {
|
||||
taskq_destroy(spa->spa_zvol_taskq);
|
||||
spa->spa_zvol_taskq = NULL;
|
||||
}
|
||||
|
||||
txg_list_destroy(&spa->spa_vdev_txg_list);
|
||||
|
||||
list_destroy(&spa->spa_config_dirty_list);
|
||||
@@ -3088,10 +3112,8 @@ 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
|
||||
zvol_create_minors(spa, spa_name(spa), B_TRUE);
|
||||
|
||||
*spapp = spa;
|
||||
|
||||
@@ -4211,10 +4233,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_history_log_version(spa, "import");
|
||||
|
||||
#ifdef _KERNEL
|
||||
zvol_create_minors(pool);
|
||||
#endif
|
||||
zvol_create_minors(spa, pool, B_TRUE);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -4349,6 +4368,10 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
|
||||
spa_open_ref(spa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_async_suspend(spa);
|
||||
if (spa->spa_zvol_taskq) {
|
||||
zvol_remove_minors(spa, spa_name(spa), B_TRUE);
|
||||
taskq_wait(spa->spa_zvol_taskq);
|
||||
}
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user