aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2019-10-16 06:26:51 +0000
committerAndriy Gapon <avg@FreeBSD.org>2019-10-16 06:26:51 +0000
commit6cb9ab2bad02615ce39526ccdf1b58b63da4d155 (patch)
tree8aa9f21e29df0a7268ebf9dfeca9d3938c94e71f /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
parentb399ca755a71c0de0c7963b509a15260aaa07a99 (diff)
parentb7cab79de23a8bfb689bfb5bddb4deb2e09b360d (diff)
downloadsrc-6cb9ab2bad02615ce39526ccdf1b58b63da4d155.tar.gz
src-6cb9ab2bad02615ce39526ccdf1b58b63da4d155.zip
MFC r353611: 10330 merge recent ZoL vdev and metaslab changes
illumos/illumos-gate@a0b03b161c4df3cfc54fbc741db09b3bdc23ffba https://github.com/illumos/illumos-gate/commit/a0b03b161c4df3cfc54fbc741db09b3bdc23ffba https://www.illumos.org/issues/10330 3 recent ZoL changes in the vdev and metaslab code which we can pull over: PR 8324 c853f382db 8324 Change target size of metaslabs from 256GB to 16GB PR 8290 b194fab0fb 8290 Factor metaslab_load_wait() in metaslab_load() PR 8286 419ba59145 8286 Update vdev_is_spacemap_addressable() for new spacemap encoding Author: Serapheim Dimitropoulos <serapheimd@gmail.com> Obtained from: illumos, ZoL MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=353612
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c82
1 files changed, 47 insertions, 35 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
index cb69664aa2a2..741b47559af6 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
@@ -1468,7 +1468,7 @@ metaslab_ops_t *zfs_metaslab_ops = &metaslab_df_ops;
/*
* Wait for any in-progress metaslab loads to complete.
*/
-void
+static void
metaslab_load_wait(metaslab_t *msp)
{
ASSERT(MUTEX_HELD(&msp->ms_lock));
@@ -1479,20 +1479,17 @@ metaslab_load_wait(metaslab_t *msp)
}
}
-int
-metaslab_load(metaslab_t *msp)
+static int
+metaslab_load_impl(metaslab_t *msp)
{
int error = 0;
- boolean_t success = B_FALSE;
ASSERT(MUTEX_HELD(&msp->ms_lock));
- ASSERT(!msp->ms_loaded);
- ASSERT(!msp->ms_loading);
+ ASSERT(msp->ms_loading);
- msp->ms_loading = B_TRUE;
/*
* Nobody else can manipulate a loading metaslab, so it's now safe
- * to drop the lock. This way we don't have to hold the lock while
+ * to drop the lock. This way we don't have to hold the lock while
* reading the spacemap from disk.
*/
mutex_exit(&msp->ms_lock);
@@ -1509,29 +1506,49 @@ metaslab_load(metaslab_t *msp)
msp->ms_start, msp->ms_size);
}
- success = (error == 0);
-
mutex_enter(&msp->ms_lock);
- msp->ms_loading = B_FALSE;
- if (success) {
- ASSERT3P(msp->ms_group, !=, NULL);
- msp->ms_loaded = B_TRUE;
+ if (error != 0)
+ return (error);
- /*
- * If the metaslab already has a spacemap, then we need to
- * remove all segments from the defer tree; otherwise, the
- * metaslab is completely empty and we can skip this.
- */
- if (msp->ms_sm != NULL) {
- for (int t = 0; t < TXG_DEFER_SIZE; t++) {
- range_tree_walk(msp->ms_defer[t],
- range_tree_remove, msp->ms_allocatable);
- }
+ ASSERT3P(msp->ms_group, !=, NULL);
+ msp->ms_loaded = B_TRUE;
+
+ /*
+ * If the metaslab already has a spacemap, then we need to
+ * remove all segments from the defer tree; otherwise, the
+ * metaslab is completely empty and we can skip this.
+ */
+ if (msp->ms_sm != NULL) {
+ for (int t = 0; t < TXG_DEFER_SIZE; t++) {
+ range_tree_walk(msp->ms_defer[t],
+ range_tree_remove, msp->ms_allocatable);
}
- msp->ms_max_size = metaslab_block_maxsize(msp);
}
+ msp->ms_max_size = metaslab_block_maxsize(msp);
+
+ return (0);
+}
+
+int
+metaslab_load(metaslab_t *msp)
+{
+ ASSERT(MUTEX_HELD(&msp->ms_lock));
+
+ /*
+ * There may be another thread loading the same metaslab, if that's
+ * the case just wait until the other thread is done and return.
+ */
+ metaslab_load_wait(msp);
+ if (msp->ms_loaded)
+ return (0);
+ VERIFY(!msp->ms_loading);
+
+ msp->ms_loading = B_TRUE;
+ int error = metaslab_load_impl(msp);
+ msp->ms_loading = B_FALSE;
cv_broadcast(&msp->ms_load_cv);
+
return (error);
}
@@ -2091,13 +2108,10 @@ metaslab_activate(metaslab_t *msp, int allocator, uint64_t activation_weight)
ASSERT(MUTEX_HELD(&msp->ms_lock));
if ((msp->ms_weight & METASLAB_ACTIVE_MASK) == 0) {
- int error = 0;
- metaslab_load_wait(msp);
- if (!msp->ms_loaded) {
- if ((error = metaslab_load(msp)) != 0) {
- metaslab_group_sort(msp->ms_group, msp, 0);
- return (error);
- }
+ int error = metaslab_load(msp);
+ if (error != 0) {
+ metaslab_group_sort(msp->ms_group, msp, 0);
+ return (error);
}
if ((msp->ms_weight & METASLAB_ACTIVE_MASK) != 0) {
/*
@@ -2209,9 +2223,7 @@ metaslab_preload(void *arg)
ASSERT(!MUTEX_HELD(&msp->ms_group->mg_lock));
mutex_enter(&msp->ms_lock);
- metaslab_load_wait(msp);
- if (!msp->ms_loaded)
- (void) metaslab_load(msp);
+ (void) metaslab_load(msp);
msp->ms_selected_txg = spa_syncing_txg(spa);
mutex_exit(&msp->ms_lock);
}