mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-26 04:07:45 +03:00
OpenZFS 7254 - ztest failed assertion in ztest_dataset_dirobj_verify: dirobjs + 1 == usedobjs
Authored by: Paul Dagnelie <pcd@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Steve Gonczi <steve.gonczi@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Ported-by: George Melikov <mail@gmelikov.ru> OpenZFS-issue: https://www.illumos.org/issues/7254 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/c166b69 Closes #5670
This commit is contained in:
committed by
Brian Behlendorf
parent
687e612f9a
commit
cc9bb3e58e
+29
-6
@@ -1583,10 +1583,18 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
* objects may be dirtied in syncing context, but only if they
|
||||
* were already pre-dirtied in open context.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL) {
|
||||
rrw_enter(&dn->dn_objset->os_dsl_dataset->ds_bp_rwlock,
|
||||
RW_READER, FTAG);
|
||||
}
|
||||
ASSERT(!dmu_tx_is_syncing(tx) ||
|
||||
BP_IS_HOLE(dn->dn_objset->os_rootbp) ||
|
||||
DMU_OBJECT_IS_SPECIAL(dn->dn_object) ||
|
||||
dn->dn_objset->os_dsl_dataset == NULL);
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL)
|
||||
rrw_exit(&dn->dn_objset->os_dsl_dataset->ds_bp_rwlock, FTAG);
|
||||
#endif
|
||||
/*
|
||||
* We make this assert for private objects as well, but after we
|
||||
* check if we're already dirty. They are allowed to re-dirty
|
||||
@@ -1611,12 +1619,21 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
* Don't set dirtyctx to SYNC if we're just modifying this as we
|
||||
* initialize the objset.
|
||||
*/
|
||||
if (dn->dn_dirtyctx == DN_UNDIRTIED &&
|
||||
!BP_IS_HOLE(dn->dn_objset->os_rootbp)) {
|
||||
dn->dn_dirtyctx =
|
||||
(dmu_tx_is_syncing(tx) ? DN_DIRTY_SYNC : DN_DIRTY_OPEN);
|
||||
ASSERT(dn->dn_dirtyctx_firstset == NULL);
|
||||
dn->dn_dirtyctx_firstset = kmem_alloc(1, KM_SLEEP);
|
||||
if (dn->dn_dirtyctx == DN_UNDIRTIED) {
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL) {
|
||||
rrw_enter(&dn->dn_objset->os_dsl_dataset->ds_bp_rwlock,
|
||||
RW_READER, FTAG);
|
||||
}
|
||||
if (!BP_IS_HOLE(dn->dn_objset->os_rootbp)) {
|
||||
dn->dn_dirtyctx = (dmu_tx_is_syncing(tx) ?
|
||||
DN_DIRTY_SYNC : DN_DIRTY_OPEN);
|
||||
ASSERT(dn->dn_dirtyctx_firstset == NULL);
|
||||
dn->dn_dirtyctx_firstset = kmem_alloc(1, KM_SLEEP);
|
||||
}
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL) {
|
||||
rrw_exit(&dn->dn_objset->os_dsl_dataset->ds_bp_rwlock,
|
||||
FTAG);
|
||||
}
|
||||
}
|
||||
mutex_exit(&dn->dn_mtx);
|
||||
|
||||
@@ -1661,8 +1678,14 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
||||
* this assertion only if we're not already dirty.
|
||||
*/
|
||||
os = dn->dn_objset;
|
||||
#ifdef DEBUG
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL)
|
||||
rrw_enter(&os->os_dsl_dataset->ds_bp_rwlock, RW_READER, FTAG);
|
||||
ASSERT(!dmu_tx_is_syncing(tx) || DMU_OBJECT_IS_SPECIAL(dn->dn_object) ||
|
||||
os->os_dsl_dataset == NULL || BP_IS_HOLE(os->os_rootbp));
|
||||
if (dn->dn_objset->os_dsl_dataset != NULL)
|
||||
rrw_exit(&os->os_dsl_dataset->ds_bp_rwlock, FTAG);
|
||||
#endif
|
||||
ASSERT(db->db.db_size != 0);
|
||||
|
||||
dprintf_dbuf(db, "size=%llx\n", (u_longlong_t)db->db.db_size);
|
||||
|
||||
Reference in New Issue
Block a user