From 66c8b2f65a0bd684fb4d57c5072433d5fde1bf49 Mon Sep 17 00:00:00 2001 From: Paul Dagnelie Date: Fri, 5 Jul 2019 16:45:20 -0700 Subject: [PATCH] Don't activate metaslabs with weight 0 We return ENOSPC in metaslab_activate if the metaslab has weight 0, to avoid activating a metaslab with no space available. For sanity checking, we also assert that there is no free space in the range tree in that case. Reviewed-by: Igor Kozhukhov Reviewed by: Matt Ahrens Reviewed by: Serapheim Dimitropoulos Reviewed by: Brian Behlendorf Signed-off-by: Paul Dagnelie Closes #8968 --- module/zfs/metaslab.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index a14057f89..5da929b48 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -2485,6 +2485,18 @@ metaslab_activate(metaslab_t *msp, int allocator, uint64_t activation_weight) return (0); } + /* + * If the metaslab has literally 0 space, it will have weight 0. In + * that case, don't bother activating it. This can happen if the + * metaslab had space during find_valid_metaslab, but another thread + * loaded it and used all that space while we were waiting to grab the + * lock. + */ + if (msp->ms_weight == 0) { + ASSERT0(range_tree_space(msp->ms_allocatable)); + return (SET_ERROR(ENOSPC)); + } + if ((error = metaslab_activate_allocator(msp->ms_group, msp, allocator, activation_weight)) != 0) { return (error); @@ -3735,8 +3747,8 @@ metaslab_group_alloc_normal(metaslab_group_t *mg, zio_alloc_list_t *zal, * worse metaslab (we waited for that metaslab to be loaded * after all). * - * If the activation failed due to an I/O error we skip to - * the next metaslab. + * If the activation failed due to an I/O error or ENOSPC we + * skip to the next metaslab. */ boolean_t activated; if (activation_error == 0) {