MFV r316920: 8023 Panic destroying a metaslab deferred range tree
illumos/illumos-gate@3991b535a8
3991b535a8
https://www.illumos.org/issues/8023
$C
ffffff0011bc0970 vpanic()
ffffff0011bc0a00 strlog()
ffffff0011bc0a30 range_tree_destroy+0x72(ffffff043769ad00)
ffffff0011bc0a70 metaslab_fini+0xd5(ffffff0449acf380)
ffffff0011bc0ab0 vdev_metaslab_fini+0x56(ffffff0462bae800)
ffffff0011bc0af0 spa_unload+0x9b(ffffff03e3dac000)
ffffff0011bc0b70 spa_export_common+0x115(ffffff047f4b4000, 2, 0, 0, 0)
ffffff0011bc0b90 spa_destroy+0x1d(ffffff047f4b4000)
ffffff0011bc0bd0 zfs_ioc_pool_destroy+0x20(ffffff047f4b4000)
ffffff0011bc0c80 zfsdev_ioctl+0x4d7(11400000000, 5a01, 8040190, 100003,
ffffff03e1956b10, ffffff0011bc0e68)
ffffff0011bc0cc0 cdev_ioctl+0x39(11400000000, 5a01, 8040190, 100003,
ffffff03e1956b10, ffffff0011bc0e68)
ffffff0011bc0d10 spec_ioctl+0x60(ffffff03d9153b00, 5a01, 8040190, 100003,
ffffff03e1956b10, ffffff0011bc0e68, 0)
ffffff0011bc0da0 fop_ioctl+0x55(ffffff03d9153b00, 5a01, 8040190, 100003,
ffffff03e1956b10, ffffff0011bc0e68, 0)
ffffff0011bc0ec0 ioctl+0x9b(3, 5a01, 8040190)
ffffff0011bc0f10 _sys_sysenter_post_swapgs+0x149()
Reviewed by: Brad Lewis <brad.lewis@delphix.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Approved by: Dan McDonald <danmcd@omniti.com>
Author: George Wilson <george.wilson@delphix.com>
MFC after: 2 weeks
This commit is contained in:
commit
e1b8f10a5e
@ -1552,6 +1552,7 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
* this assertion only if we're not already dirty.
|
||||
*/
|
||||
os = dn->dn_objset;
|
||||
VERIFY3U(tx->tx_txg, <=, spa_final_dirty_txg(os->os_spa));
|
||||
#ifdef DEBUG
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL)
|
||||
rrw_enter(&os->os_dsl_dataset->ds_bp_rwlock, RW_READER, FTAG);
|
||||
|
@ -1652,11 +1652,19 @@ metaslab_set_fragmentation(metaslab_t *msp)
|
||||
uint64_t txg = spa_syncing_txg(spa);
|
||||
vdev_t *vd = msp->ms_group->mg_vd;
|
||||
|
||||
if (spa_writeable(spa)) {
|
||||
/*
|
||||
* If we've reached the final dirty txg, then we must
|
||||
* be shutting down the pool. We don't want to dirty
|
||||
* any data past this point so skip setting the condense
|
||||
* flag. We can retry this action the next time the pool
|
||||
* is imported.
|
||||
*/
|
||||
if (spa_writeable(spa) && txg < spa_final_dirty_txg(spa)) {
|
||||
msp->ms_condense_wanted = B_TRUE;
|
||||
vdev_dirty(vd, VDD_METASLAB, msp, txg + 1);
|
||||
spa_dbgmsg(spa, "txg %llu, requesting force condense: "
|
||||
"msp %p, vd %p", txg, msp, vd);
|
||||
"ms_id %llu, vdev_id %llu", txg, msp->ms_id,
|
||||
vd->vdev_id);
|
||||
}
|
||||
msp->ms_fragmentation = ZFS_FRAG_INVALID;
|
||||
return;
|
||||
@ -2278,13 +2286,17 @@ metaslab_sync(metaslab_t *msp, uint64_t txg)
|
||||
/*
|
||||
* Normally, we don't want to process a metaslab if there
|
||||
* are no allocations or frees to perform. However, if the metaslab
|
||||
* is being forced to condense we need to let it through.
|
||||
* is being forced to condense and it's loaded, we need to let it
|
||||
* through.
|
||||
*/
|
||||
if (range_tree_space(alloctree) == 0 &&
|
||||
range_tree_space(msp->ms_freeingtree) == 0 &&
|
||||
!msp->ms_condense_wanted)
|
||||
!(msp->ms_loaded && msp->ms_condense_wanted))
|
||||
return;
|
||||
|
||||
|
||||
VERIFY(txg <= spa_final_dirty_txg(spa));
|
||||
|
||||
/*
|
||||
* The only state that can actually be changing concurrently with
|
||||
* metaslab_sync() is the metaslab's ms_tree. No other thread can
|
||||
|
@ -1737,6 +1737,16 @@ spa_syncing_txg(spa_t *spa)
|
||||
return (spa->spa_syncing_txg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the last txg where data can be dirtied. The final txgs
|
||||
* will be used to just clear out any deferred frees that remain.
|
||||
*/
|
||||
uint64_t
|
||||
spa_final_dirty_txg(spa_t *spa)
|
||||
{
|
||||
return (spa->spa_final_txg - TXG_DEFER_SIZE);
|
||||
}
|
||||
|
||||
pool_state_t
|
||||
spa_state(spa_t *spa)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
@ -407,6 +407,7 @@ space_map_truncate(space_map_t *sm, dmu_tx_t *tx)
|
||||
|
||||
ASSERT(dsl_pool_sync_context(dmu_objset_pool(os)));
|
||||
ASSERT(dmu_tx_is_syncing(tx));
|
||||
VERIFY3U(dmu_tx_get_txg(tx), <=, spa_final_dirty_txg(spa));
|
||||
|
||||
dmu_object_info_from_db(sm->sm_dbuf, &doi);
|
||||
|
||||
@ -421,9 +422,10 @@ space_map_truncate(space_map_t *sm, dmu_tx_t *tx)
|
||||
if ((spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM) &&
|
||||
doi.doi_bonus_size != sizeof (space_map_phys_t)) ||
|
||||
doi.doi_data_block_size != space_map_blksz) {
|
||||
zfs_dbgmsg("txg %llu, spa %s, reallocating: "
|
||||
"old bonus %u, old blocksz %u", dmu_tx_get_txg(tx),
|
||||
spa_name(spa), doi.doi_bonus_size, doi.doi_data_block_size);
|
||||
zfs_dbgmsg("txg %llu, spa %s, sm %p, reallocating "
|
||||
"object[%llu]: old bonus %u, old blocksz %u",
|
||||
dmu_tx_get_txg(tx), spa_name(spa), sm, sm->sm_object,
|
||||
doi.doi_bonus_size, doi.doi_data_block_size);
|
||||
|
||||
space_map_free(sm, tx);
|
||||
dmu_buf_rele(sm->sm_dbuf, sm);
|
||||
|
@ -791,6 +791,7 @@ extern uint64_t spa_load_guid(spa_t *spa);
|
||||
extern uint64_t spa_last_synced_txg(spa_t *spa);
|
||||
extern uint64_t spa_first_txg(spa_t *spa);
|
||||
extern uint64_t spa_syncing_txg(spa_t *spa);
|
||||
extern uint64_t spa_final_dirty_txg(spa_t *spa);
|
||||
extern uint64_t spa_version(spa_t *spa);
|
||||
extern pool_state_t spa_state(spa_t *spa);
|
||||
extern spa_load_state_t spa_load_state(spa_t *spa);
|
||||
|
Loading…
Reference in New Issue
Block a user