mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Illumos 5314 - Remove "dbuf phys" db->db_data pointer aliases in ZFS
5314 Remove "dbuf phys" db->db_data pointer aliases in ZFS Author: Justin T. Gibbs <justing@spectralogic.com> Reviewed by: Andriy Gapon <avg@freebsd.org> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Will Andrews <willa@spectralogic.com> Approved by: Dan McDonald <danmcd@omniti.com> References: https://www.illumos.org/issues/5314 https://github.com/illumos/illumos-gate/commit/c137962 Ported-by: Chris Dunlop <chris@onthe.net.au> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
committed by
Brian Behlendorf
parent
945dd93525
commit
d683ddbb72
+117
-102
@@ -78,7 +78,7 @@ dsl_destroy_snapshot_check_impl(dsl_dataset_t *ds, boolean_t defer)
|
||||
/*
|
||||
* Can't delete a branch point.
|
||||
*/
|
||||
if (ds->ds_phys->ds_num_children > 1)
|
||||
if (dsl_dataset_phys(ds)->ds_num_children > 1)
|
||||
return (SET_ERROR(EEXIST));
|
||||
|
||||
return (0);
|
||||
@@ -147,12 +147,12 @@ process_old_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
|
||||
|
||||
ASSERT(!BP_IS_HOLE(bp));
|
||||
|
||||
if (bp->blk_birth <= poa->ds->ds_phys->ds_prev_snap_txg) {
|
||||
if (bp->blk_birth <= dsl_dataset_phys(poa->ds)->ds_prev_snap_txg) {
|
||||
dsl_deadlist_insert(&poa->ds->ds_deadlist, bp, tx);
|
||||
if (poa->ds_prev && !poa->after_branch_point &&
|
||||
bp->blk_birth >
|
||||
poa->ds_prev->ds_phys->ds_prev_snap_txg) {
|
||||
poa->ds_prev->ds_phys->ds_unique_bytes +=
|
||||
dsl_dataset_phys(poa->ds_prev)->ds_prev_snap_txg) {
|
||||
dsl_dataset_phys(poa->ds_prev)->ds_unique_bytes +=
|
||||
bp_get_dsize_sync(dp->dp_spa, bp);
|
||||
}
|
||||
} else {
|
||||
@@ -183,7 +183,7 @@ process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
|
||||
VERIFY0(bpobj_iterate(&ds_next->ds_deadlist.dl_bpobj,
|
||||
process_old_cb, &poa, tx));
|
||||
VERIFY0(zio_wait(poa.pio));
|
||||
ASSERT3U(poa.used, ==, ds->ds_phys->ds_unique_bytes);
|
||||
ASSERT3U(poa.used, ==, dsl_dataset_phys(ds)->ds_unique_bytes);
|
||||
|
||||
/* change snapused */
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
|
||||
@@ -192,12 +192,14 @@ process_old_deadlist(dsl_dataset_t *ds, dsl_dataset_t *ds_prev,
|
||||
/* swap next's deadlist to our deadlist */
|
||||
dsl_deadlist_close(&ds->ds_deadlist);
|
||||
dsl_deadlist_close(&ds_next->ds_deadlist);
|
||||
deadlist_obj = ds->ds_phys->ds_deadlist_obj;
|
||||
ds->ds_phys->ds_deadlist_obj = ds_next->ds_phys->ds_deadlist_obj;
|
||||
ds_next->ds_phys->ds_deadlist_obj = deadlist_obj;
|
||||
dsl_deadlist_open(&ds->ds_deadlist, mos, ds->ds_phys->ds_deadlist_obj);
|
||||
deadlist_obj = dsl_dataset_phys(ds)->ds_deadlist_obj;
|
||||
dsl_dataset_phys(ds)->ds_deadlist_obj =
|
||||
dsl_dataset_phys(ds_next)->ds_deadlist_obj;
|
||||
dsl_dataset_phys(ds_next)->ds_deadlist_obj = deadlist_obj;
|
||||
dsl_deadlist_open(&ds->ds_deadlist, mos,
|
||||
dsl_dataset_phys(ds)->ds_deadlist_obj);
|
||||
dsl_deadlist_open(&ds_next->ds_deadlist, mos,
|
||||
ds_next->ds_phys->ds_deadlist_obj);
|
||||
dsl_dataset_phys(ds_next)->ds_deadlist_obj);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -212,13 +214,13 @@ dsl_dataset_remove_clones_key(dsl_dataset_t *ds, uint64_t mintxg, dmu_tx_t *tx)
|
||||
* find the clones, but dsl_deadlist_remove_key() is a no-op so it
|
||||
* doesn't matter.
|
||||
*/
|
||||
if (ds->ds_dir->dd_phys->dd_clones == 0)
|
||||
if (dsl_dir_phys(ds->ds_dir)->dd_clones == 0)
|
||||
return;
|
||||
|
||||
zc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
|
||||
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||
|
||||
for (zap_cursor_init(zc, mos, ds->ds_dir->dd_phys->dd_clones);
|
||||
for (zap_cursor_init(zc, mos, dsl_dir_phys(ds->ds_dir)->dd_clones);
|
||||
zap_cursor_retrieve(zc, za) == 0;
|
||||
zap_cursor_advance(zc)) {
|
||||
dsl_dataset_t *clone;
|
||||
@@ -253,19 +255,20 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
|
||||
|
||||
ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
|
||||
ASSERT3U(ds->ds_phys->ds_bp.blk_birth, <=, tx->tx_txg);
|
||||
ASSERT3U(dsl_dataset_phys(ds)->ds_bp.blk_birth, <=, tx->tx_txg);
|
||||
ASSERT(refcount_is_zero(&ds->ds_longholds));
|
||||
|
||||
if (defer &&
|
||||
(ds->ds_userrefs > 0 || ds->ds_phys->ds_num_children > 1)) {
|
||||
(ds->ds_userrefs > 0 ||
|
||||
dsl_dataset_phys(ds)->ds_num_children > 1)) {
|
||||
ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_flags |= DS_FLAG_DEFER_DESTROY;
|
||||
dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_DEFER_DESTROY;
|
||||
spa_history_log_internal_ds(ds, "defer_destroy", tx, "");
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT3U(ds->ds_phys->ds_num_children, <=, 1);
|
||||
ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
|
||||
|
||||
/* We need to log before removing it from the namespace. */
|
||||
spa_history_log_internal_ds(ds, "destroy", tx, "");
|
||||
@@ -274,42 +277,44 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
|
||||
obj = ds->ds_object;
|
||||
|
||||
if (ds->ds_phys->ds_prev_snap_obj != 0) {
|
||||
if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
|
||||
ASSERT3P(ds->ds_prev, ==, NULL);
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds->ds_phys->ds_prev_snap_obj, FTAG, &ds_prev));
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_obj, FTAG, &ds_prev));
|
||||
after_branch_point =
|
||||
(ds_prev->ds_phys->ds_next_snap_obj != obj);
|
||||
(dsl_dataset_phys(ds_prev)->ds_next_snap_obj != obj);
|
||||
|
||||
dmu_buf_will_dirty(ds_prev->ds_dbuf, tx);
|
||||
if (after_branch_point &&
|
||||
ds_prev->ds_phys->ds_next_clones_obj != 0) {
|
||||
dsl_dataset_phys(ds_prev)->ds_next_clones_obj != 0) {
|
||||
dsl_dataset_remove_from_next_clones(ds_prev, obj, tx);
|
||||
if (ds->ds_phys->ds_next_snap_obj != 0) {
|
||||
if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0) {
|
||||
VERIFY0(zap_add_int(mos,
|
||||
ds_prev->ds_phys->ds_next_clones_obj,
|
||||
ds->ds_phys->ds_next_snap_obj, tx));
|
||||
dsl_dataset_phys(ds_prev)->
|
||||
ds_next_clones_obj,
|
||||
dsl_dataset_phys(ds)->ds_next_snap_obj,
|
||||
tx));
|
||||
}
|
||||
}
|
||||
if (!after_branch_point) {
|
||||
ds_prev->ds_phys->ds_next_snap_obj =
|
||||
ds->ds_phys->ds_next_snap_obj;
|
||||
dsl_dataset_phys(ds_prev)->ds_next_snap_obj =
|
||||
dsl_dataset_phys(ds)->ds_next_snap_obj;
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds->ds_phys->ds_next_snap_obj, FTAG, &ds_next));
|
||||
ASSERT3U(ds_next->ds_phys->ds_prev_snap_obj, ==, obj);
|
||||
dsl_dataset_phys(ds)->ds_next_snap_obj, FTAG, &ds_next));
|
||||
ASSERT3U(dsl_dataset_phys(ds_next)->ds_prev_snap_obj, ==, obj);
|
||||
|
||||
old_unique = ds_next->ds_phys->ds_unique_bytes;
|
||||
old_unique = dsl_dataset_phys(ds_next)->ds_unique_bytes;
|
||||
|
||||
dmu_buf_will_dirty(ds_next->ds_dbuf, tx);
|
||||
ds_next->ds_phys->ds_prev_snap_obj =
|
||||
ds->ds_phys->ds_prev_snap_obj;
|
||||
ds_next->ds_phys->ds_prev_snap_txg =
|
||||
ds->ds_phys->ds_prev_snap_txg;
|
||||
ASSERT3U(ds->ds_phys->ds_prev_snap_txg, ==,
|
||||
ds_prev ? ds_prev->ds_phys->ds_creation_txg : 0);
|
||||
dsl_dataset_phys(ds_next)->ds_prev_snap_obj =
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_obj;
|
||||
dsl_dataset_phys(ds_next)->ds_prev_snap_txg =
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg;
|
||||
ASSERT3U(dsl_dataset_phys(ds)->ds_prev_snap_txg, ==,
|
||||
ds_prev ? dsl_dataset_phys(ds_prev)->ds_creation_txg : 0);
|
||||
|
||||
if (ds_next->ds_deadlist.dl_oldfmt) {
|
||||
process_old_deadlist(ds, ds_prev, ds_next,
|
||||
@@ -318,38 +323,38 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
/* Adjust prev's unique space. */
|
||||
if (ds_prev && !after_branch_point) {
|
||||
dsl_deadlist_space_range(&ds_next->ds_deadlist,
|
||||
ds_prev->ds_phys->ds_prev_snap_txg,
|
||||
ds->ds_phys->ds_prev_snap_txg,
|
||||
dsl_dataset_phys(ds_prev)->ds_prev_snap_txg,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg,
|
||||
&used, &comp, &uncomp);
|
||||
ds_prev->ds_phys->ds_unique_bytes += used;
|
||||
dsl_dataset_phys(ds_prev)->ds_unique_bytes += used;
|
||||
}
|
||||
|
||||
/* Adjust snapused. */
|
||||
dsl_deadlist_space_range(&ds_next->ds_deadlist,
|
||||
ds->ds_phys->ds_prev_snap_txg, UINT64_MAX,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg, UINT64_MAX,
|
||||
&used, &comp, &uncomp);
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_SNAP,
|
||||
-used, -comp, -uncomp, tx);
|
||||
|
||||
/* Move blocks to be freed to pool's free list. */
|
||||
dsl_deadlist_move_bpobj(&ds_next->ds_deadlist,
|
||||
&dp->dp_free_bpobj, ds->ds_phys->ds_prev_snap_txg,
|
||||
&dp->dp_free_bpobj, dsl_dataset_phys(ds)->ds_prev_snap_txg,
|
||||
tx);
|
||||
dsl_dir_diduse_space(tx->tx_pool->dp_free_dir,
|
||||
DD_USED_HEAD, used, comp, uncomp, tx);
|
||||
|
||||
/* Merge our deadlist into next's and free it. */
|
||||
dsl_deadlist_merge(&ds_next->ds_deadlist,
|
||||
ds->ds_phys->ds_deadlist_obj, tx);
|
||||
dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
|
||||
}
|
||||
dsl_deadlist_close(&ds->ds_deadlist);
|
||||
dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
|
||||
dsl_deadlist_free(mos, dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_deadlist_obj = 0;
|
||||
dsl_dataset_phys(ds)->ds_deadlist_obj = 0;
|
||||
|
||||
/* Collapse range in clone heads */
|
||||
dsl_dataset_remove_clones_key(ds,
|
||||
ds->ds_phys->ds_creation_txg, tx);
|
||||
dsl_dataset_phys(ds)->ds_creation_txg, tx);
|
||||
|
||||
if (dsl_dataset_is_snapshot(ds_next)) {
|
||||
dsl_dataset_t *ds_nextnext;
|
||||
@@ -364,20 +369,21 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
* deadlist).
|
||||
*/
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds_next->ds_phys->ds_next_snap_obj, FTAG, &ds_nextnext));
|
||||
dsl_dataset_phys(ds_next)->ds_next_snap_obj,
|
||||
FTAG, &ds_nextnext));
|
||||
dsl_deadlist_space_range(&ds_nextnext->ds_deadlist,
|
||||
ds->ds_phys->ds_prev_snap_txg,
|
||||
ds->ds_phys->ds_creation_txg,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg,
|
||||
dsl_dataset_phys(ds)->ds_creation_txg,
|
||||
&used, &comp, &uncomp);
|
||||
ds_next->ds_phys->ds_unique_bytes += used;
|
||||
dsl_dataset_phys(ds_next)->ds_unique_bytes += used;
|
||||
dsl_dataset_rele(ds_nextnext, FTAG);
|
||||
ASSERT3P(ds_next->ds_prev, ==, NULL);
|
||||
|
||||
/* Collapse range in this head. */
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &hds));
|
||||
dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj, FTAG, &hds));
|
||||
dsl_deadlist_remove_key(&hds->ds_deadlist,
|
||||
ds->ds_phys->ds_creation_txg, tx);
|
||||
dsl_dataset_phys(ds)->ds_creation_txg, tx);
|
||||
dsl_dataset_rele(hds, FTAG);
|
||||
|
||||
} else {
|
||||
@@ -386,7 +392,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
ds_next->ds_prev = NULL;
|
||||
if (ds_prev) {
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds->ds_phys->ds_prev_snap_obj,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_obj,
|
||||
ds_next, &ds_next->ds_prev));
|
||||
}
|
||||
|
||||
@@ -400,7 +406,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
if (old_unique < ds_next->ds_reserved) {
|
||||
int64_t mrsdelta;
|
||||
uint64_t new_unique =
|
||||
ds_next->ds_phys->ds_unique_bytes;
|
||||
dsl_dataset_phys(ds_next)->ds_unique_bytes;
|
||||
|
||||
ASSERT(old_unique <= new_unique);
|
||||
mrsdelta = MIN(new_unique - old_unique,
|
||||
@@ -421,9 +427,9 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
/* remove from snapshot namespace */
|
||||
ASSERT(ds->ds_phys->ds_snapnames_zapobj == 0);
|
||||
ASSERT(dsl_dataset_phys(ds)->ds_snapnames_zapobj == 0);
|
||||
VERIFY0(dsl_dataset_hold_obj(dp,
|
||||
ds->ds_dir->dd_phys->dd_head_dataset_obj, FTAG, &ds_head));
|
||||
dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj, FTAG, &ds_head));
|
||||
VERIFY0(dsl_dataset_get_snapname(ds));
|
||||
#ifdef ZFS_DEBUG
|
||||
{
|
||||
@@ -443,17 +449,20 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx)
|
||||
|
||||
spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
|
||||
|
||||
if (ds->ds_phys->ds_next_clones_obj != 0) {
|
||||
if (dsl_dataset_phys(ds)->ds_next_clones_obj != 0) {
|
||||
ASSERTV(uint64_t count);
|
||||
ASSERT0(zap_count(mos,
|
||||
ds->ds_phys->ds_next_clones_obj, &count) && count == 0);
|
||||
dsl_dataset_phys(ds)->ds_next_clones_obj, &count) &&
|
||||
count == 0);
|
||||
VERIFY0(dmu_object_free(mos,
|
||||
ds->ds_phys->ds_next_clones_obj, tx));
|
||||
dsl_dataset_phys(ds)->ds_next_clones_obj, tx));
|
||||
}
|
||||
if (ds->ds_phys->ds_props_obj != 0)
|
||||
VERIFY0(zap_destroy(mos, ds->ds_phys->ds_props_obj, tx));
|
||||
if (ds->ds_phys->ds_userrefs_obj != 0)
|
||||
VERIFY0(zap_destroy(mos, ds->ds_phys->ds_userrefs_obj, tx));
|
||||
if (dsl_dataset_phys(ds)->ds_props_obj != 0)
|
||||
VERIFY0(zap_destroy(mos, dsl_dataset_phys(ds)->ds_props_obj,
|
||||
tx));
|
||||
if (dsl_dataset_phys(ds)->ds_userrefs_obj != 0)
|
||||
VERIFY0(zap_destroy(mos, dsl_dataset_phys(ds)->ds_userrefs_obj,
|
||||
tx));
|
||||
dsl_dir_rele(ds->ds_dir, ds);
|
||||
ds->ds_dir = NULL;
|
||||
dmu_object_free_zapified(mos, obj, tx);
|
||||
@@ -556,7 +565,8 @@ kill_blkptr(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
||||
dsl_free(ka->tx->tx_pool, ka->tx->tx_txg, bp);
|
||||
} else {
|
||||
ASSERT(zilog == NULL);
|
||||
ASSERT3U(bp->blk_birth, >, ka->ds->ds_phys->ds_prev_snap_txg);
|
||||
ASSERT3U(bp->blk_birth, >,
|
||||
dsl_dataset_phys(ka->ds)->ds_prev_snap_txg);
|
||||
(void) dsl_dataset_block_kill(ka->ds, bp, tx, B_FALSE);
|
||||
}
|
||||
|
||||
@@ -578,9 +588,10 @@ old_synchronous_dataset_destroy(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
ka.ds = ds;
|
||||
ka.tx = tx;
|
||||
VERIFY0(traverse_dataset(ds,
|
||||
ds->ds_phys->ds_prev_snap_txg, TRAVERSE_POST,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg, TRAVERSE_POST,
|
||||
kill_blkptr, &ka));
|
||||
ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) || ds->ds_phys->ds_unique_bytes == 0);
|
||||
ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
|
||||
dsl_dataset_phys(ds)->ds_unique_bytes == 0);
|
||||
}
|
||||
|
||||
typedef struct dsl_destroy_head_arg {
|
||||
@@ -609,21 +620,21 @@ dsl_destroy_head_check_impl(dsl_dataset_t *ds, int expected_holds)
|
||||
* from.)
|
||||
*/
|
||||
if (ds->ds_prev != NULL &&
|
||||
ds->ds_prev->ds_phys->ds_next_snap_obj == ds->ds_object)
|
||||
dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj == ds->ds_object)
|
||||
return (SET_ERROR(EBUSY));
|
||||
|
||||
/*
|
||||
* Can't delete if there are children of this fs.
|
||||
*/
|
||||
error = zap_count(mos,
|
||||
ds->ds_dir->dd_phys->dd_child_dir_zapobj, &count);
|
||||
dsl_dir_phys(ds->ds_dir)->dd_child_dir_zapobj, &count);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (count != 0)
|
||||
return (SET_ERROR(EEXIST));
|
||||
|
||||
if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev) &&
|
||||
ds->ds_prev->ds_phys->ds_num_children == 2 &&
|
||||
dsl_dataset_phys(ds->ds_prev)->ds_num_children == 2 &&
|
||||
ds->ds_prev->ds_userrefs == 0) {
|
||||
/* We need to remove the origin snapshot as well. */
|
||||
if (!refcount_is_zero(&ds->ds_prev->ds_longholds))
|
||||
@@ -661,7 +672,7 @@ dsl_dir_destroy_sync(uint64_t ddobj, dmu_tx_t *tx)
|
||||
|
||||
VERIFY0(dsl_dir_hold_obj(dp, ddobj, NULL, FTAG, &dd));
|
||||
|
||||
ASSERT0(dd->dd_phys->dd_head_dataset_obj);
|
||||
ASSERT0(dsl_dir_phys(dd)->dd_head_dataset_obj);
|
||||
|
||||
/*
|
||||
* Decrement the filesystem count for all parent filesystems.
|
||||
@@ -680,16 +691,17 @@ dsl_dir_destroy_sync(uint64_t ddobj, dmu_tx_t *tx)
|
||||
*/
|
||||
dsl_dir_set_reservation_sync_impl(dd, 0, tx);
|
||||
|
||||
ASSERT0(dd->dd_phys->dd_used_bytes);
|
||||
ASSERT0(dd->dd_phys->dd_reserved);
|
||||
ASSERT0(dsl_dir_phys(dd)->dd_used_bytes);
|
||||
ASSERT0(dsl_dir_phys(dd)->dd_reserved);
|
||||
for (t = 0; t < DD_USED_NUM; t++)
|
||||
ASSERT0(dd->dd_phys->dd_used_breakdown[t]);
|
||||
ASSERT0(dsl_dir_phys(dd)->dd_used_breakdown[t]);
|
||||
|
||||
VERIFY0(zap_destroy(mos, dd->dd_phys->dd_child_dir_zapobj, tx));
|
||||
VERIFY0(zap_destroy(mos, dd->dd_phys->dd_props_zapobj, tx));
|
||||
VERIFY0(dsl_deleg_destroy(mos, dd->dd_phys->dd_deleg_zapobj, tx));
|
||||
VERIFY0(zap_destroy(mos, dsl_dir_phys(dd)->dd_child_dir_zapobj, tx));
|
||||
VERIFY0(zap_destroy(mos, dsl_dir_phys(dd)->dd_props_zapobj, tx));
|
||||
VERIFY0(dsl_deleg_destroy(mos, dsl_dir_phys(dd)->dd_deleg_zapobj, tx));
|
||||
VERIFY0(zap_remove(mos,
|
||||
dd->dd_parent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, tx));
|
||||
dsl_dir_phys(dd->dd_parent)->dd_child_dir_zapobj,
|
||||
dd->dd_myname, tx));
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
dmu_object_free_zapified(mos, ddobj, tx);
|
||||
@@ -704,10 +716,10 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
boolean_t rmorigin;
|
||||
objset_t *os;
|
||||
|
||||
ASSERT3U(ds->ds_phys->ds_num_children, <=, 1);
|
||||
ASSERT3U(dsl_dataset_phys(ds)->ds_num_children, <=, 1);
|
||||
ASSERT(ds->ds_prev == NULL ||
|
||||
ds->ds_prev->ds_phys->ds_next_snap_obj != ds->ds_object);
|
||||
ASSERT3U(ds->ds_phys->ds_bp.blk_birth, <=, tx->tx_txg);
|
||||
dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj != ds->ds_object);
|
||||
ASSERT3U(dsl_dataset_phys(ds)->ds_bp.blk_birth, <=, tx->tx_txg);
|
||||
ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
|
||||
|
||||
/* We need to log before removing it from the namespace. */
|
||||
@@ -715,7 +727,7 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
|
||||
rmorigin = (dsl_dir_is_clone(ds->ds_dir) &&
|
||||
DS_IS_DEFER_DESTROY(ds->ds_prev) &&
|
||||
ds->ds_prev->ds_phys->ds_num_children == 2 &&
|
||||
dsl_dataset_phys(ds->ds_prev)->ds_num_children == 2 &&
|
||||
ds->ds_prev->ds_userrefs == 0);
|
||||
|
||||
/* Remove our reservation. */
|
||||
@@ -730,20 +742,21 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
|
||||
obj = ds->ds_object;
|
||||
|
||||
if (ds->ds_phys->ds_prev_snap_obj != 0) {
|
||||
if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) {
|
||||
/* This is a clone */
|
||||
ASSERT(ds->ds_prev != NULL);
|
||||
ASSERT3U(ds->ds_prev->ds_phys->ds_next_snap_obj, !=, obj);
|
||||
ASSERT0(ds->ds_phys->ds_next_snap_obj);
|
||||
ASSERT3U(dsl_dataset_phys(ds->ds_prev)->ds_next_snap_obj, !=,
|
||||
obj);
|
||||
ASSERT0(dsl_dataset_phys(ds)->ds_next_snap_obj);
|
||||
|
||||
dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
|
||||
if (ds->ds_prev->ds_phys->ds_next_clones_obj != 0) {
|
||||
if (dsl_dataset_phys(ds->ds_prev)->ds_next_clones_obj != 0) {
|
||||
dsl_dataset_remove_from_next_clones(ds->ds_prev,
|
||||
obj, tx);
|
||||
}
|
||||
|
||||
ASSERT3U(ds->ds_prev->ds_phys->ds_num_children, >, 1);
|
||||
ds->ds_prev->ds_phys->ds_num_children--;
|
||||
ASSERT3U(dsl_dataset_phys(ds->ds_prev)->ds_num_children, >, 1);
|
||||
dsl_dataset_phys(ds->ds_prev)->ds_num_children--;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -752,9 +765,9 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
* safe to ignore the deadlist contents.)
|
||||
*/
|
||||
dsl_deadlist_close(&ds->ds_deadlist);
|
||||
dsl_deadlist_free(mos, ds->ds_phys->ds_deadlist_obj, tx);
|
||||
dsl_deadlist_free(mos, dsl_dataset_phys(ds)->ds_deadlist_obj, tx);
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_deadlist_obj = 0;
|
||||
dsl_dataset_phys(ds)->ds_deadlist_obj = 0;
|
||||
|
||||
VERIFY0(dmu_objset_from_ds(ds, &os));
|
||||
|
||||
@@ -783,15 +796,16 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
scn->scn_async_destroying = B_TRUE;
|
||||
}
|
||||
|
||||
used = ds->ds_dir->dd_phys->dd_used_bytes;
|
||||
comp = ds->ds_dir->dd_phys->dd_compressed_bytes;
|
||||
uncomp = ds->ds_dir->dd_phys->dd_uncompressed_bytes;
|
||||
used = dsl_dir_phys(ds->ds_dir)->dd_used_bytes;
|
||||
comp = dsl_dir_phys(ds->ds_dir)->dd_compressed_bytes;
|
||||
uncomp = dsl_dir_phys(ds->ds_dir)->dd_uncompressed_bytes;
|
||||
|
||||
ASSERT(!DS_UNIQUE_IS_ACCURATE(ds) ||
|
||||
ds->ds_phys->ds_unique_bytes == used);
|
||||
dsl_dataset_phys(ds)->ds_unique_bytes == used);
|
||||
|
||||
bptree_add(mos, dp->dp_bptree_obj,
|
||||
&ds->ds_phys->ds_bp, ds->ds_phys->ds_prev_snap_txg,
|
||||
&dsl_dataset_phys(ds)->ds_bp,
|
||||
dsl_dataset_phys(ds)->ds_prev_snap_txg,
|
||||
used, comp, uncomp, tx);
|
||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD,
|
||||
-used, -comp, -uncomp, tx);
|
||||
@@ -802,7 +816,7 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
if (ds->ds_prev != NULL) {
|
||||
if (spa_version(dp->dp_spa) >= SPA_VERSION_DIR_CLONES) {
|
||||
VERIFY0(zap_remove_int(mos,
|
||||
ds->ds_prev->ds_dir->dd_phys->dd_clones,
|
||||
dsl_dir_phys(ds->ds_prev->ds_dir)->dd_clones,
|
||||
ds->ds_object, tx));
|
||||
}
|
||||
prevobj = ds->ds_prev->ds_object;
|
||||
@@ -821,22 +835,22 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
|
||||
|
||||
/* Erase the link in the dir */
|
||||
dmu_buf_will_dirty(ds->ds_dir->dd_dbuf, tx);
|
||||
ds->ds_dir->dd_phys->dd_head_dataset_obj = 0;
|
||||
dsl_dir_phys(ds->ds_dir)->dd_head_dataset_obj = 0;
|
||||
ddobj = ds->ds_dir->dd_object;
|
||||
ASSERT(ds->ds_phys->ds_snapnames_zapobj != 0);
|
||||
VERIFY0(zap_destroy(mos, ds->ds_phys->ds_snapnames_zapobj, tx));
|
||||
ASSERT(dsl_dataset_phys(ds)->ds_snapnames_zapobj != 0);
|
||||
VERIFY0(zap_destroy(mos,
|
||||
dsl_dataset_phys(ds)->ds_snapnames_zapobj, tx));
|
||||
|
||||
if (ds->ds_bookmarks != 0) {
|
||||
VERIFY0(zap_destroy(mos,
|
||||
ds->ds_bookmarks, tx));
|
||||
VERIFY0(zap_destroy(mos, ds->ds_bookmarks, tx));
|
||||
spa_feature_decr(dp->dp_spa, SPA_FEATURE_BOOKMARKS, tx);
|
||||
}
|
||||
|
||||
spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx);
|
||||
|
||||
ASSERT0(ds->ds_phys->ds_next_clones_obj);
|
||||
ASSERT0(ds->ds_phys->ds_props_obj);
|
||||
ASSERT0(ds->ds_phys->ds_userrefs_obj);
|
||||
ASSERT0(dsl_dataset_phys(ds)->ds_next_clones_obj);
|
||||
ASSERT0(dsl_dataset_phys(ds)->ds_props_obj);
|
||||
ASSERT0(dsl_dataset_phys(ds)->ds_userrefs_obj);
|
||||
dsl_dir_rele(ds->ds_dir, ds);
|
||||
ds->ds_dir = NULL;
|
||||
dmu_object_free_zapified(mos, obj, tx);
|
||||
@@ -874,7 +888,7 @@ dsl_destroy_head_begin_sync(void *arg, dmu_tx_t *tx)
|
||||
|
||||
/* Mark it as inconsistent on-disk, in case we crash */
|
||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||
ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT;
|
||||
dsl_dataset_phys(ds)->ds_flags |= DS_FLAG_INCONSISTENT;
|
||||
|
||||
spa_history_log_internal_ds(ds, "destroy begin", tx, "");
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
@@ -917,7 +931,8 @@ dsl_destroy_head(const char *name)
|
||||
if (error == 0) {
|
||||
uint64_t obj;
|
||||
uint64_t prev_snap_txg =
|
||||
dmu_objset_ds(os)->ds_phys->ds_prev_snap_txg;
|
||||
dsl_dataset_phys(dmu_objset_ds(os))->
|
||||
ds_prev_snap_txg;
|
||||
for (obj = 0; error == 0;
|
||||
error = dmu_object_next(os, &obj, FALSE,
|
||||
prev_snap_txg))
|
||||
|
||||
Reference in New Issue
Block a user