summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/dsl_dataset.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dsl_dataset.c')
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_dataset.c150
1 files changed, 70 insertions, 80 deletions
diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c
index 555797e77e..6625444e5a 100644
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c
@@ -103,14 +103,8 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
ASSERT(BP_GET_TYPE(bp) != DMU_OT_NONE);
ASSERT(DMU_OT_IS_VALID(BP_GET_TYPE(bp)));
if (ds == NULL) {
- /*
- * Account for the meta-objset space in its placeholder
- * dsl_dir.
- */
- ASSERT3U(compressed, ==, uncompressed); /* it's all metadata */
- dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD,
- used, compressed, uncompressed, tx);
- dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx);
+ dsl_pool_mos_diduse_space(tx->tx_pool,
+ used, compressed, uncompressed);
return;
}
dmu_buf_will_dirty(ds->ds_dbuf, tx);
@@ -146,15 +140,9 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
ASSERT(used > 0);
if (ds == NULL) {
- /*
- * Account for the meta-objset space in its placeholder
- * dataset.
- */
dsl_free(tx->tx_pool, tx->tx_txg, bp);
-
- dsl_dir_diduse_space(tx->tx_pool->dp_mos_dir, DD_USED_HEAD,
- -used, -compressed, -uncompressed, tx);
- dsl_dir_dirty(tx->tx_pool->dp_mos_dir, tx);
+ dsl_pool_mos_diduse_space(tx->tx_pool,
+ -used, -compressed, -uncompressed);
return (used);
}
ASSERT3P(tx->tx_pool, ==, ds->ds_dir->dd_pool);
@@ -1068,26 +1056,26 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
dd = ds->ds_dir;
- /*
- * Check for errors and mark this ds as inconsistent, in
- * case we crash while freeing the objects.
- */
- err = dsl_sync_task_do(dd->dd_pool, dsl_dataset_destroy_begin_check,
- dsl_dataset_destroy_begin_sync, ds, NULL, 0);
- if (err)
- goto out;
-
- err = dmu_objset_from_ds(ds, &os);
- if (err)
- goto out;
-
- /*
- * If async destruction is not enabled try to remove all objects
- * while in the open context so that there is less work to do in
- * the syncing context.
- */
if (!spa_feature_is_enabled(dsl_dataset_get_spa(ds),
&spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
+ /*
+ * Check for errors and mark this ds as inconsistent, in
+ * case we crash while freeing the objects.
+ */
+ err = dsl_sync_task_do(dd->dd_pool,
+ dsl_dataset_destroy_begin_check,
+ dsl_dataset_destroy_begin_sync, ds, NULL, 0);
+ if (err)
+ goto out;
+
+ err = dmu_objset_from_ds(ds, &os);
+ if (err)
+ goto out;
+
+ /*
+ * Remove all objects while in the open context so that
+ * there is less work to do in the syncing context.
+ */
for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE,
ds->ds_phys->ds_prev_snap_txg)) {
/*
@@ -1098,30 +1086,25 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
}
if (err != ESRCH)
goto out;
- }
- /*
- * Only the ZIL knows how to free log blocks.
- */
- zil_destroy(dmu_objset_zil(os), B_FALSE);
-
- /*
- * Sync out all in-flight IO.
- */
- txg_wait_synced(dd->dd_pool, 0);
-
- /*
- * If we managed to free all the objects in open
- * context, the user space accounting should be zero.
- */
- if (ds->ds_phys->ds_bp.blk_fill == 0 &&
- dmu_objset_userused_enabled(os)) {
- uint64_t count;
+ /*
+ * Sync out all in-flight IO.
+ */
+ txg_wait_synced(dd->dd_pool, 0);
- ASSERT(zap_count(os, DMU_USERUSED_OBJECT, &count) != 0 ||
- count == 0);
- ASSERT(zap_count(os, DMU_GROUPUSED_OBJECT, &count) != 0 ||
- count == 0);
+ /*
+ * If we managed to free all the objects in open
+ * context, the user space accounting should be zero.
+ */
+ if (ds->ds_phys->ds_bp.blk_fill == 0 &&
+ dmu_objset_userused_enabled(os)) {
+ uint64_t count;
+
+ ASSERT(zap_count(os, DMU_USERUSED_OBJECT,
+ &count) != 0 || count == 0);
+ ASSERT(zap_count(os, DMU_GROUPUSED_OBJECT,
+ &count) != 0 || count == 0);
+ }
}
rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
@@ -1227,6 +1210,17 @@ dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
}
}
+boolean_t
+dsl_dataset_is_dirty(dsl_dataset_t *ds)
+{
+ for (int t = 0; t < TXG_SIZE; t++) {
+ if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
+ ds, t))
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
/*
* The unique space in the head dataset can be calculated by subtracting
* the space used in the most recent snapshot, that is still being used
@@ -1504,7 +1498,7 @@ remove_from_next_clones(dsl_dataset_t *ds, uint64_t obj, dmu_tx_t *tx)
* remove this one.
*/
if (err != ENOENT) {
- VERIFY3U(err, ==, 0);
+ VERIFY0(err);
}
ASSERT3U(0, ==, zap_count(mos, ds->ds_phys->ds_next_clones_obj,
&count));
@@ -1591,7 +1585,7 @@ process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
poa.pio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
VERIFY3U(0, ==, bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
process_old_cb, &poa, tx));
- VERIFY3U(zio_wait(poa.pio), ==, 0);
+ VERIFY0(zio_wait(poa.pio));
ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
/* change snapused */
@@ -1626,7 +1620,7 @@ old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
err = traverse_dataset(ds,
ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
kill_blkptr, &ka);
- ASSERT3U(err, ==, 0);
+ ASSERT0(err);
ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
return (err);
@@ -1682,7 +1676,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
psa.psa_effective_value = 0; /* predict default value */
dsl_dataset_set_reservation_sync(ds, &psa, tx);
- ASSERT3U(ds->ds_reserved, ==, 0);
+ ASSERT0(ds->ds_reserved);
}
ASSERT(RW_WRITE_HELD(&dp->dp_config_rwlock));
@@ -1859,6 +1853,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
} else {
zfeature_info_t *async_destroy =
&spa_feature_table[SPA_FEATURE_ASYNC_DESTROY];
+ objset_t *os;
/*
* There's no next snapshot, so this is a head dataset.
@@ -1870,6 +1865,8 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
ds->ds_phys->ds_deadlist_obj = 0;
+ VERIFY3U(0, ==, dmu_objset_from_ds(ds, &os));
+
if (!spa_feature_is_enabled(dp->dp_spa, async_destroy)) {
err = old_synchronous_dataset_destroy(ds, tx);
} else {
@@ -1879,12 +1876,12 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
*/
uint64_t used, comp, uncomp;
- ASSERT(err == 0 || err == EBUSY);
+ zil_destroy_sync(dmu_objset_zil(os), tx);
+
if (!spa_feature_is_active(dp->dp_spa, async_destroy)) {
spa_feature_incr(dp->dp_spa, async_destroy, tx);
- dp->dp_bptree_obj = bptree_alloc(
- dp->dp_meta_objset, tx);
- VERIFY(zap_add(dp->dp_meta_objset,
+ dp->dp_bptree_obj = bptree_alloc(mos, tx);
+ VERIFY(zap_add(mos,
DMU_POOL_DIRECTORY_OBJECT,
DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
&dp->dp_bptree_obj, tx) == 0);
@@ -1897,7 +1894,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
ds->ds_phys->ds_unique_bytes == used);
- bptree_add(dp->dp_meta_objset, dp->dp_bptree_obj,
+ bptree_add(mos, dp->dp_bptree_obj,
&ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
used, comp, uncomp, tx);
dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
@@ -1946,7 +1943,7 @@ dsl_dataset_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx)
err = dsl_dataset_snap_lookup(ds_head,
ds->ds_snapname, &val);
- ASSERT3U(err, ==, 0);
+ ASSERT0(err);
ASSERT3U(val, ==, obj);
}
#endif
@@ -2179,7 +2176,6 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
dmu_buf_will_dirty(ds->ds_dbuf, tx);
ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid;
- dsl_dir_dirty(ds->ds_dir, tx);
dmu_objset_sync(ds->ds_objset, zio, tx);
}
@@ -2306,7 +2302,6 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
}
}
}
-
}
void
@@ -2442,13 +2437,13 @@ dsl_dataset_snapshot_rename_sync(void *arg1, void *arg2, dmu_tx_t *tx)
VERIFY(0 == dsl_dataset_get_snapname(ds));
err = dsl_dataset_snap_remove(hds, ds->ds_snapname, tx);
- ASSERT3U(err, ==, 0);
+ ASSERT0(err);
mutex_enter(&ds->ds_lock);
(void) strcpy(ds->ds_snapname, newsnapname);
mutex_exit(&ds->ds_lock);
err = zap_add(mos, hds->ds_phys->ds_snapnames_zapobj,
ds->ds_snapname, 8, 1, &ds->ds_object, tx);
- ASSERT3U(err, ==, 0);
+ ASSERT0(err);
spa_history_log_internal_ds(ds, "rename", tx,
"-> @%s", newsnapname);
@@ -2902,7 +2897,7 @@ dsl_dataset_promote_sync(void *arg1, void *arg2, dmu_tx_t *tx)
zap_cursor_fini(&zc);
}
- ASSERT3U(dsl_prop_numcb(ds), ==, 0);
+ ASSERT0(dsl_prop_numcb(ds));
}
/*
@@ -3447,9 +3442,6 @@ dsl_dataset_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
if (ds->ds_quota != effective_value) {
dmu_buf_will_dirty(ds->ds_dbuf, tx);
ds->ds_quota = effective_value;
-
- spa_history_log_internal_ds(ds, "set refquota", tx,
- "refquota=%lld", (longlong_t)ds->ds_quota);
}
}
@@ -3553,9 +3545,6 @@ dsl_dataset_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
mutex_exit(&ds->ds_dir->dd_lock);
-
- spa_history_log_internal_ds(ds, "set refreservation", tx,
- "refreservation=%lld", (longlong_t)effective_value);
}
int
@@ -3903,6 +3892,10 @@ dsl_dataset_user_release_sync(void *arg1, void *tag, dmu_tx_t *tx)
VERIFY(error == 0 || error == ENOENT);
zapobj = ds->ds_phys->ds_userrefs_obj;
VERIFY(0 == zap_remove(mos, zapobj, ra->htag, tx));
+
+ spa_history_log_internal_ds(ds, "release", tx,
+ "tag = %s refs now = %lld", ra->htag, (longlong_t)refs);
+
if (ds->ds_userrefs == 0 && ds->ds_phys->ds_num_children == 1 &&
DS_IS_DEFER_DESTROY(ds)) {
struct dsl_ds_destroyarg dsda = {0};
@@ -3913,9 +3906,6 @@ dsl_dataset_user_release_sync(void *arg1, void *tag, dmu_tx_t *tx)
/* We already did the destroy_check */
dsl_dataset_destroy_sync(&dsda, tag, tx);
}
-
- spa_history_log_internal_ds(ds, "release", tx,
- "tag = %s refs now = %lld", ra->htag, (longlong_t)refs);
}
static int