diff options
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dmu_objset.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/dmu_objset.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c index 11fea14a91..864cffa615 100644 --- a/usr/src/uts/common/fs/zfs/dmu_objset.c +++ b/usr/src/uts/common/fs/zfs/dmu_objset.c @@ -149,9 +149,11 @@ int dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, objset_impl_t **osip) { - objset_impl_t *winner, *osi; + objset_impl_t *osi; int i, err, checksum; + ASSERT(ds == NULL || MUTEX_HELD(&ds->ds_opening_lock)); + osi = kmem_zalloc(sizeof (objset_impl_t), KM_SLEEP); osi->os.os = osi; osi->os_dsl_dataset = ds; @@ -245,12 +247,13 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, osi->os_meta_dnode = dnode_special_open(osi, &osi->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT); - if (ds != NULL) { - winner = dsl_dataset_set_user_ptr(ds, osi, dmu_objset_evict); - if (winner) { - dmu_objset_evict(ds, osi); - osi = winner; - } + /* + * We should be the only thread trying to do this because we + * have ds_opening_lock + */ + if (ds) { + VERIFY(NULL == dsl_dataset_set_user_ptr(ds, osi, + dmu_objset_evict)); } *osip = osi; @@ -274,6 +277,7 @@ dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, return (err); } + mutex_enter(&ds->ds_opening_lock); osi = dsl_dataset_get_user_ptr(ds); if (osi == NULL) { err = dmu_objset_open_impl(dsl_dataset_get_spa(ds), @@ -284,6 +288,7 @@ dmu_objset_open(const char *name, dmu_objset_type_t type, int mode, return (err); } } + mutex_exit(&ds->ds_opening_lock); os->os = osi; os->os_mode = mode; @@ -304,7 +309,7 @@ dmu_objset_close(objset_t *os) } int -dmu_objset_evict_dbufs(objset_t *os, int try) +dmu_objset_evict_dbufs(objset_t *os, boolean_t try) { objset_impl_t *osi = os->os; dnode_t *dn; @@ -402,7 +407,11 @@ dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, dnode_t *mdn; ASSERT(dmu_tx_is_syncing(tx)); + if (ds) + mutex_enter(&ds->ds_opening_lock); VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &osi)); + if (ds) + mutex_exit(&ds->ds_opening_lock); mdn = osi->os_meta_dnode; dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT, @@ -802,9 +811,10 @@ dmu_objset_sync(objset_impl_t *os, zio_t *pio, dmu_tx_t *tx) zb.zb_object = 0; zb.zb_level = -1; zb.zb_blkid = 0; - if (BP_IS_OLDER(os->os_rootbp, tx->tx_txg)) + if (BP_IS_OLDER(os->os_rootbp, tx->tx_txg)) { dsl_dataset_block_kill(os->os_dsl_dataset, os->os_rootbp, pio, tx); + } zio = arc_write(pio, os->os_spa, os->os_md_checksum, os->os_md_compress, dmu_get_replication_level(os, &zb, DMU_OT_OBJSET), |