mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 19:57:43 +03:00
spa_misc: add an API for spa_namespace_lock
This is useful as debugging support, as it lets namespace lock operations be traced directly. It will also be useful for future work to reduce the use of spa_namespace_lock, traditionally a source of difficult deadlocks. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #17906
This commit is contained in:
+87
-87
@@ -1082,7 +1082,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp)
|
||||
int error;
|
||||
|
||||
mutex_enter(&spa->spa_vdev_top_lock);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
|
||||
if (guidp != NULL) {
|
||||
guid = *guidp;
|
||||
@@ -1117,7 +1117,7 @@ spa_change_guid(spa_t *spa, const uint64_t *guidp)
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
mutex_exit(&spa->spa_vdev_top_lock);
|
||||
|
||||
return (error);
|
||||
@@ -2252,7 +2252,7 @@ spa_should_sync_time_logger_on_unload(spa_t *spa)
|
||||
static void
|
||||
spa_unload(spa_t *spa)
|
||||
{
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
|
||||
ASSERT(spa_namespace_held() ||
|
||||
spa->spa_export_thread == curthread);
|
||||
ASSERT(spa_state(spa) != POOL_STATE_UNINITIALIZED);
|
||||
|
||||
@@ -5325,7 +5325,7 @@ spa_ld_read_checkpoint_txg(spa_t *spa)
|
||||
int error = 0;
|
||||
|
||||
ASSERT0(spa->spa_checkpoint_txg);
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock) ||
|
||||
ASSERT(spa_namespace_held() ||
|
||||
spa->spa_load_thread == curthread);
|
||||
|
||||
error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
|
||||
@@ -5352,7 +5352,7 @@ spa_ld_mos_init(spa_t *spa, spa_import_type_t type)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE);
|
||||
|
||||
/*
|
||||
@@ -5428,7 +5428,7 @@ spa_ld_checkpoint_rewind(spa_t *spa)
|
||||
uberblock_t checkpoint;
|
||||
int error = 0;
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
ASSERT(spa->spa_import_flags & ZFS_IMPORT_CHECKPOINT);
|
||||
|
||||
error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
|
||||
@@ -5575,7 +5575,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
|
||||
boolean_t update_config_cache = B_FALSE;
|
||||
hrtime_t load_start = gethrtime();
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
ASSERT(spa->spa_config_source != SPA_CONFIG_SRC_NONE);
|
||||
|
||||
spa_load_note(spa, "LOADING");
|
||||
@@ -5622,7 +5622,7 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
|
||||
* Drop the namespace lock for the rest of the function.
|
||||
*/
|
||||
spa->spa_load_thread = curthread;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
/*
|
||||
* Retrieve the checkpoint txg if the pool has a checkpoint.
|
||||
@@ -5861,9 +5861,9 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
|
||||
|
||||
spa_load_note(spa, "LOADED");
|
||||
fail:
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa->spa_load_thread = NULL;
|
||||
cv_broadcast(&spa_namespace_cv);
|
||||
spa_namespace_broadcast();
|
||||
|
||||
return (error);
|
||||
|
||||
@@ -6025,14 +6025,14 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
|
||||
* up calling spa_open() again. The real fix is to figure out how to
|
||||
* avoid dsl_dir_open() calling this in the first place.
|
||||
*/
|
||||
if (MUTEX_NOT_HELD(&spa_namespace_lock)) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
if (!spa_namespace_held()) {
|
||||
spa_namespace_enter(FTAG);
|
||||
locked = B_TRUE;
|
||||
}
|
||||
|
||||
if ((spa = spa_lookup(pool)) == NULL) {
|
||||
if (locked)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
@@ -6069,7 +6069,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
|
||||
spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE);
|
||||
spa_remove(spa);
|
||||
if (locked)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
@@ -6089,7 +6089,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
|
||||
spa_deactivate(spa);
|
||||
spa->spa_last_open_failed = error;
|
||||
if (locked)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
*spapp = NULL;
|
||||
return (error);
|
||||
}
|
||||
@@ -6113,7 +6113,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
|
||||
spa->spa_last_open_failed = 0;
|
||||
spa->spa_last_ubsync_txg = 0;
|
||||
spa->spa_load_txg = 0;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
if (firstopen)
|
||||
@@ -6146,13 +6146,13 @@ spa_inject_addref(char *name)
|
||||
{
|
||||
spa_t *spa;
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if ((spa = spa_lookup(name)) == NULL) {
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (NULL);
|
||||
}
|
||||
spa->spa_inject_ref++;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
return (spa);
|
||||
}
|
||||
@@ -6160,9 +6160,9 @@ spa_inject_addref(char *name)
|
||||
void
|
||||
spa_inject_delref(spa_t *spa)
|
||||
{
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa->spa_inject_ref--;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6406,14 +6406,14 @@ spa_get_stats(const char *name, nvlist_t **config,
|
||||
*/
|
||||
if (altroot) {
|
||||
if (spa == NULL) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa = spa_lookup(name);
|
||||
if (spa)
|
||||
spa_altroot(spa, altroot, buflen);
|
||||
else
|
||||
altroot[0] = '\0';
|
||||
spa = NULL;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
} else {
|
||||
spa_altroot(spa, altroot, buflen);
|
||||
}
|
||||
@@ -6633,9 +6633,9 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
/*
|
||||
* If this pool already exists, return failure.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if (spa_lookup(poolname) != NULL) {
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
|
||||
@@ -6653,7 +6653,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
if (props && (error = spa_prop_validate(spa, props))) {
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -6686,14 +6686,14 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
if (error != 0) {
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
if (!has_allocclass && zfs_special_devs(nvroot, NULL)) {
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
@@ -6759,7 +6759,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
spa_unload(spa);
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -6912,7 +6912,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
|
||||
spa_import_os(spa);
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -6937,9 +6937,9 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
/*
|
||||
* If a pool with this name exists, return failure.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if (spa_lookup(pool) != NULL) {
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
|
||||
@@ -6966,7 +6966,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE);
|
||||
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
|
||||
zfs_dbgmsg("spa_import: verbatim import of %s", pool);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -7025,7 +7025,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
spa_unload(spa);
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -7093,7 +7093,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||
|
||||
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_IMPORT);
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
zvol_create_minors(pool);
|
||||
|
||||
@@ -7125,7 +7125,7 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||
(void) snprintf(name, MAXPATHLEN, "%s-%llx-%s",
|
||||
TRYIMPORT_NAME, (u_longlong_t)(uintptr_t)curthread, poolname);
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa = spa_add(name, tryconfig, NULL);
|
||||
spa_activate(spa, SPA_MODE_READ);
|
||||
kmem_free(name, MAXPATHLEN);
|
||||
@@ -7223,7 +7223,7 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||
spa_unload(spa);
|
||||
spa_deactivate(spa);
|
||||
spa_remove(spa);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
return (config);
|
||||
}
|
||||
@@ -7251,15 +7251,15 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||
if (!(spa_mode_global & SPA_MODE_WRITE))
|
||||
return (SET_ERROR(EROFS));
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if ((spa = spa_lookup(pool)) == NULL) {
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(ENOENT));
|
||||
}
|
||||
|
||||
if (spa->spa_is_exporting) {
|
||||
/* the pool is being exported by another thread */
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
return (SET_ERROR(ZFS_ERR_EXPORT_IN_PROGRESS));
|
||||
}
|
||||
spa->spa_is_exporting = B_TRUE;
|
||||
@@ -7269,18 +7269,18 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||
* and see if we can export.
|
||||
*/
|
||||
spa_open_ref(spa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
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_namespace_enter(FTAG);
|
||||
spa->spa_export_thread = curthread;
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
goto export_spa;
|
||||
}
|
||||
|
||||
@@ -7304,7 +7304,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
/*
|
||||
* At this point we no longer hold the spa_namespace_lock and
|
||||
* there were no references on the spa. Future spa_lookups will
|
||||
@@ -7323,7 +7323,7 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||
if (!force && new_state == POOL_STATE_EXPORTED &&
|
||||
spa_has_active_shared_spare(spa)) {
|
||||
error = SET_ERROR(EXDEV);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -7398,7 +7398,7 @@ export_spa:
|
||||
/*
|
||||
* Take the namespace lock for the actual spa_t removal
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if (new_state != POOL_STATE_UNINITIALIZED) {
|
||||
if (!hardforce)
|
||||
spa_write_cachefile(spa, B_TRUE, B_TRUE, B_FALSE);
|
||||
@@ -7416,8 +7416,8 @@ export_spa:
|
||||
/*
|
||||
* Wake up any waiters in spa_lookup()
|
||||
*/
|
||||
cv_broadcast(&spa_namespace_cv);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_broadcast();
|
||||
spa_namespace_exit(FTAG);
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
@@ -7428,8 +7428,8 @@ fail:
|
||||
/*
|
||||
* Wake up any waiters in spa_lookup()
|
||||
*/
|
||||
cv_broadcast(&spa_namespace_cv);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_broadcast();
|
||||
spa_namespace_exit(FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@@ -7639,10 +7639,10 @@ spa_vdev_add(spa_t *spa, nvlist_t *nvroot, boolean_t check_ashift)
|
||||
*/
|
||||
(void) spa_vdev_exit(spa, vd, txg, 0);
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
|
||||
spa_event_notify(spa, NULL, NULL, ESC_ZFS_VDEV_ADD);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -7759,7 +7759,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
|
||||
|
||||
oldvd = spa_lookup_by_guid(spa, guid, B_FALSE);
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
|
||||
error = (spa_has_checkpoint(spa)) ?
|
||||
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
|
||||
@@ -8143,7 +8143,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
|
||||
* as spa_vdev_resilver_done() calls this function everything
|
||||
* should be fine as the resilver will return right away.
|
||||
*/
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
|
||||
error = (spa_has_checkpoint(spa)) ?
|
||||
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
|
||||
@@ -8347,28 +8347,28 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
|
||||
if (unspare) {
|
||||
spa_t *altspa = NULL;
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
while ((altspa = spa_next(altspa)) != NULL) {
|
||||
if (altspa->spa_state != POOL_STATE_ACTIVE ||
|
||||
altspa == spa)
|
||||
continue;
|
||||
|
||||
spa_open_ref(altspa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
(void) spa_vdev_remove(altspa, unspare_guid, B_TRUE);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_close(altspa, FTAG);
|
||||
}
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
/* search the rest of the vdevs for spares to remove */
|
||||
spa_vdev_resilver_done(spa);
|
||||
}
|
||||
|
||||
/* all done with the spa; OK to release */
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_close(spa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
return (error);
|
||||
}
|
||||
@@ -8377,7 +8377,7 @@ static int
|
||||
spa_vdev_initialize_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type,
|
||||
list_t *vd_list)
|
||||
{
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
|
||||
spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
|
||||
|
||||
@@ -8461,7 +8461,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type,
|
||||
* we can properly assess the vdev state before we commit to
|
||||
* the initializing operation.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
|
||||
for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
|
||||
pair != NULL; pair = nvlist_next_nvpair(nv, pair)) {
|
||||
@@ -8484,7 +8484,7 @@ spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type,
|
||||
|
||||
/* Sync out the initializing state */
|
||||
txg_wait_synced(spa->spa_dsl_pool, 0);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
list_destroy(&vd_list);
|
||||
|
||||
@@ -8495,7 +8495,7 @@ static int
|
||||
spa_vdev_trim_impl(spa_t *spa, uint64_t guid, uint64_t cmd_type,
|
||||
uint64_t rate, boolean_t partial, boolean_t secure, list_t *vd_list)
|
||||
{
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
|
||||
spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
|
||||
|
||||
@@ -8582,7 +8582,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate,
|
||||
* we can properly assess the vdev state before we commit to
|
||||
* the TRIM operation.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
|
||||
for (nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
|
||||
pair != NULL; pair = nvlist_next_nvpair(nv, pair)) {
|
||||
@@ -8605,7 +8605,7 @@ spa_vdev_trim(spa_t *spa, nvlist_t *nv, uint64_t cmd_type, uint64_t rate,
|
||||
|
||||
/* Sync out the TRIM state */
|
||||
txg_wait_synced(spa->spa_dsl_pool, 0);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
list_destroy(&vd_list);
|
||||
|
||||
@@ -8633,7 +8633,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config,
|
||||
|
||||
txg = spa_vdev_enter(spa);
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
ASSERT(spa_namespace_held());
|
||||
if (spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT)) {
|
||||
error = (spa_has_checkpoint(spa)) ?
|
||||
ZFS_ERR_CHECKPOINT_EXISTS : ZFS_ERR_DISCARDING_CHECKPOINT;
|
||||
@@ -9307,7 +9307,7 @@ spa_async_thread(void *arg)
|
||||
if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
|
||||
uint64_t old_space, new_space;
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
old_space = metaslab_class_get_space(spa_normal_class(spa));
|
||||
old_space += metaslab_class_get_space(spa_special_class(spa));
|
||||
old_space += metaslab_class_get_space(spa_dedup_class(spa));
|
||||
@@ -9325,7 +9325,7 @@ spa_async_thread(void *arg)
|
||||
spa_embedded_log_class(spa));
|
||||
new_space += metaslab_class_get_space(
|
||||
spa_special_embedded_log_class(spa));
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
/*
|
||||
* If the pool grew as a result of the config update,
|
||||
@@ -9394,49 +9394,49 @@ spa_async_thread(void *arg)
|
||||
dsl_scan_restart_resilver(dp, 0);
|
||||
|
||||
if (tasks & SPA_ASYNC_INITIALIZE_RESTART) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
|
||||
vdev_initialize_restart(spa->spa_root_vdev);
|
||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
if (tasks & SPA_ASYNC_TRIM_RESTART) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
|
||||
vdev_trim_restart(spa->spa_root_vdev);
|
||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
if (tasks & SPA_ASYNC_AUTOTRIM_RESTART) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
|
||||
vdev_autotrim_restart(spa);
|
||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kick off L2 cache whole device TRIM.
|
||||
*/
|
||||
if (tasks & SPA_ASYNC_L2CACHE_TRIM) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
|
||||
vdev_trim_l2arc(spa);
|
||||
spa_config_exit(spa, SCL_CONFIG, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kick off L2 cache rebuilding.
|
||||
*/
|
||||
if (tasks & SPA_ASYNC_L2CACHE_REBUILD) {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_config_enter(spa, SCL_L2ARC, FTAG, RW_READER);
|
||||
l2arc_spa_rebuild_start(spa);
|
||||
spa_config_exit(spa, SCL_L2ARC, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -10588,18 +10588,18 @@ void
|
||||
spa_sync_allpools(void)
|
||||
{
|
||||
spa_t *spa = NULL;
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
while ((spa = spa_next(spa)) != NULL) {
|
||||
if (spa_state(spa) != POOL_STATE_ACTIVE ||
|
||||
!spa_writeable(spa) || spa_suspended(spa))
|
||||
continue;
|
||||
spa_open_ref(spa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_close(spa, FTAG);
|
||||
}
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
taskq_t *
|
||||
@@ -10746,7 +10746,7 @@ spa_evict_all(void)
|
||||
* Remove all cached state. All pools should be closed now,
|
||||
* so every spa in the AVL tree should be unreferenced.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
while ((spa = spa_next(NULL)) != NULL) {
|
||||
/*
|
||||
* Stop async tasks. The async thread may need to detach
|
||||
@@ -10754,9 +10754,9 @@ spa_evict_all(void)
|
||||
* spa_namespace_lock, so we must drop it here.
|
||||
*/
|
||||
spa_open_ref(spa, FTAG);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
spa_async_suspend(spa);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
|
||||
@@ -10765,7 +10765,7 @@ spa_evict_all(void)
|
||||
}
|
||||
spa_remove(spa);
|
||||
}
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
vdev_t *
|
||||
|
||||
Reference in New Issue
Block a user