mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
Parallel pool import
This commit allow spa_load() to drop the spa_namespace_lock so that imports can happen concurrently. Prior to dropping the spa_namespace_lock, the import logic will set the spa_load_thread value to track the thread which is doing the import. Consumers of spa_lookup() retain the same behavior by blocking when either a thread is holding the spa_namespace_lock or the spa_load_thread value is set. This will ensure that critical concurrent operations cannot take place while a pool is being imported. The zpool command is also enhanced to provide multi-threaded support when invoking zpool import -a. Lastly, zinject provides a mechanism to insert artificial delays when importing a pool and new zfs tests are added to verify parallel import functionality. Contributions-by: Don Brady <don.brady@klarasystems.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: George Wilson <gwilson@delphix.com> Closes #16093
This commit is contained in:
+19
-7
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2024 by Delphix. All rights reserved.
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
* Copyright 2013 Saso Kiselkov. All rights reserved.
|
||||
@@ -82,7 +82,8 @@
|
||||
* - Check if spa_refcount is zero
|
||||
* - Rename a spa_t
|
||||
* - add/remove/attach/detach devices
|
||||
* - Held for the duration of create/destroy/import/export
|
||||
* - Held for the duration of create/destroy/export
|
||||
* - Held at the start and end of import
|
||||
*
|
||||
* It does not need to handle recursion. A create or destroy may
|
||||
* reference objects (files or zvols) in other pools, but by
|
||||
@@ -235,9 +236,9 @@
|
||||
* locking is, always, based on spa_namespace_lock and spa_config_lock[].
|
||||
*/
|
||||
|
||||
static avl_tree_t spa_namespace_avl;
|
||||
avl_tree_t spa_namespace_avl;
|
||||
kmutex_t spa_namespace_lock;
|
||||
static kcondvar_t spa_namespace_cv;
|
||||
kcondvar_t spa_namespace_cv;
|
||||
static const int spa_max_replication_override = SPA_DVAS_PER_BP;
|
||||
|
||||
static kmutex_t spa_spare_lock;
|
||||
@@ -619,6 +620,7 @@ spa_lookup(const char *name)
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
|
||||
retry:
|
||||
(void) strlcpy(search.spa_name, name, sizeof (search.spa_name));
|
||||
|
||||
/*
|
||||
@@ -630,6 +632,14 @@ spa_lookup(const char *name)
|
||||
*cp = '\0';
|
||||
|
||||
spa = avl_find(&spa_namespace_avl, &search, &where);
|
||||
if (spa == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (spa->spa_load_thread != NULL &&
|
||||
spa->spa_load_thread != curthread) {
|
||||
cv_wait(&spa_namespace_cv, &spa_namespace_lock);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
return (spa);
|
||||
}
|
||||
@@ -728,6 +738,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
|
||||
spa_config_lock_init(spa);
|
||||
spa_stats_init(spa);
|
||||
|
||||
ASSERT(MUTEX_HELD(&spa_namespace_lock));
|
||||
avl_add(&spa_namespace_avl, spa);
|
||||
|
||||
/*
|
||||
@@ -826,7 +837,6 @@ spa_remove(spa_t *spa)
|
||||
nvlist_free(spa->spa_config_splitting);
|
||||
|
||||
avl_remove(&spa_namespace_avl, spa);
|
||||
cv_broadcast(&spa_namespace_cv);
|
||||
|
||||
if (spa->spa_root)
|
||||
spa_strfree(spa->spa_root);
|
||||
@@ -920,7 +930,8 @@ void
|
||||
spa_open_ref(spa_t *spa, const void *tag)
|
||||
{
|
||||
ASSERT(zfs_refcount_count(&spa->spa_refcount) >= spa->spa_minref ||
|
||||
MUTEX_HELD(&spa_namespace_lock));
|
||||
MUTEX_HELD(&spa_namespace_lock) ||
|
||||
spa->spa_load_thread == curthread);
|
||||
(void) zfs_refcount_add(&spa->spa_refcount, tag);
|
||||
}
|
||||
|
||||
@@ -932,7 +943,8 @@ void
|
||||
spa_close(spa_t *spa, const void *tag)
|
||||
{
|
||||
ASSERT(zfs_refcount_count(&spa->spa_refcount) > spa->spa_minref ||
|
||||
MUTEX_HELD(&spa_namespace_lock));
|
||||
MUTEX_HELD(&spa_namespace_lock) ||
|
||||
spa->spa_load_thread == curthread);
|
||||
(void) zfs_refcount_remove(&spa->spa_refcount, tag);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user