Skip to content

Commit 65a91b1

Browse files
sdimitrobehlendorf
authored andcommitted
metaslab_verify_weight_and_frag() shouldn't cause side-effects
`metaslab_verify_weight_and_frag()` a verification function and by the end of it there shouldn't be any side-effects. The function calls `metaslab_weight()` which in turn calls `metaslab_set_fragmentation()`. The latter can dirty and otherwise not dirty metaslab fro the next TXGand set `metaslab_condense_wanted` if the spacemaps were just upgraded (meaning we just enabled the SPACEMAP_HISTOGRAM feature through upgrade). This patch adds a new flag as a parameter to `metaslab_weight()` and `metaslab_set_fragmentation()` making the dirtying of the metaslab optional. Reviewed-by: Matt Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Serapheim Dimitropoulos <[email protected]> Closes #9185 Closes #9282
1 parent 240c015 commit 65a91b1

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

module/zfs/metaslab.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ int zfs_metaslab_mem_limit = 25;
289289
*/
290290
unsigned long zfs_metaslab_max_size_cache_sec = 3600; /* 1 hour */
291291

292-
static uint64_t metaslab_weight(metaslab_t *);
293-
static void metaslab_set_fragmentation(metaslab_t *);
292+
static uint64_t metaslab_weight(metaslab_t *, boolean_t);
293+
static void metaslab_set_fragmentation(metaslab_t *, boolean_t);
294294
static void metaslab_free_impl(vdev_t *, uint64_t, uint64_t, boolean_t);
295295
static void metaslab_check_free_impl(vdev_t *, uint64_t, uint64_t);
296296

@@ -1845,13 +1845,19 @@ metaslab_verify_weight_and_frag(metaslab_t *msp)
18451845
msp->ms_fragmentation = 0;
18461846

18471847
/*
1848-
* This function is used for verification purposes. Regardless of
1849-
* whether metaslab_weight() thinks this metaslab should be active or
1850-
* not, we want to ensure that the actual weight (and therefore the
1851-
* value of ms_weight) would be the same if it was to be recalculated
1852-
* at this point.
1848+
* This function is used for verification purposes and thus should
1849+
* not introduce any side-effects/mutations on the system's state.
1850+
*
1851+
* Regardless of whether metaslab_weight() thinks this metaslab
1852+
* should be active or not, we want to ensure that the actual weight
1853+
* (and therefore the value of ms_weight) would be the same if it
1854+
* was to be recalculated at this point.
1855+
*
1856+
* In addition we set the nodirty flag so metaslab_weight() does
1857+
* not dirty the metaslab for future TXGs (e.g. when trying to
1858+
* force condensing to upgrade the metaslab spacemaps).
18531859
*/
1854-
msp->ms_weight = metaslab_weight(msp) | was_active;
1860+
msp->ms_weight = metaslab_weight(msp, B_TRUE) | was_active;
18551861

18561862
VERIFY3U(max_segsize, ==, msp->ms_max_size);
18571863

@@ -2335,7 +2341,7 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object,
23352341
ms->ms_trim = range_tree_create(NULL, NULL);
23362342

23372343
metaslab_group_add(mg, ms);
2338-
metaslab_set_fragmentation(ms);
2344+
metaslab_set_fragmentation(ms, B_FALSE);
23392345

23402346
/*
23412347
* If we're opening an existing pool (txg == 0) or creating
@@ -2497,7 +2503,7 @@ int zfs_frag_table[FRAGMENTATION_TABLE_SIZE] = {
24972503
* value should be in the range [0, 100].
24982504
*/
24992505
static void
2500-
metaslab_set_fragmentation(metaslab_t *msp)
2506+
metaslab_set_fragmentation(metaslab_t *msp, boolean_t nodirty)
25012507
{
25022508
spa_t *spa = msp->ms_group->mg_vd->vdev_spa;
25032509
uint64_t fragmentation = 0;
@@ -2532,9 +2538,11 @@ metaslab_set_fragmentation(metaslab_t *msp)
25322538
* be shutting down the pool. We don't want to dirty
25332539
* any data past this point so skip setting the condense
25342540
* flag. We can retry this action the next time the pool
2535-
* is imported.
2541+
* is imported. We also skip marking this metaslab for
2542+
* condensing if the caller has explicitly set nodirty.
25362543
*/
2537-
if (spa_writeable(spa) && txg < spa_final_dirty_txg(spa)) {
2544+
if (!nodirty &&
2545+
spa_writeable(spa) && txg < spa_final_dirty_txg(spa)) {
25382546
msp->ms_condense_wanted = B_TRUE;
25392547
vdev_dirty(vd, VDD_METASLAB, msp, txg + 1);
25402548
zfs_dbgmsg("txg %llu, requesting force condense: "
@@ -2831,16 +2839,17 @@ metaslab_should_allocate(metaslab_t *msp, uint64_t asize, boolean_t try_hard)
28312839

28322840
return (should_allocate);
28332841
}
2842+
28342843
static uint64_t
2835-
metaslab_weight(metaslab_t *msp)
2844+
metaslab_weight(metaslab_t *msp, boolean_t nodirty)
28362845
{
28372846
vdev_t *vd = msp->ms_group->mg_vd;
28382847
spa_t *spa = vd->vdev_spa;
28392848
uint64_t weight;
28402849

28412850
ASSERT(MUTEX_HELD(&msp->ms_lock));
28422851

2843-
metaslab_set_fragmentation(msp);
2852+
metaslab_set_fragmentation(msp, nodirty);
28442853

28452854
/*
28462855
* Update the maximum size. If the metaslab is loaded, this will
@@ -2881,7 +2890,7 @@ metaslab_recalculate_weight_and_sort(metaslab_t *msp)
28812890
/* note: we preserve the mask (e.g. indication of primary, etc..) */
28822891
uint64_t was_active = msp->ms_weight & METASLAB_ACTIVE_MASK;
28832892
metaslab_group_sort(msp->ms_group, msp,
2884-
metaslab_weight(msp) | was_active);
2893+
metaslab_weight(msp, B_FALSE) | was_active);
28852894
}
28862895

28872896
static int

0 commit comments

Comments
 (0)