diff options
author | Justin T. Gibbs <[email protected]> | 2015-10-13 14:09:45 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-10-13 14:12:02 -0700 |
commit | bc4501f75a04ddf9c04cef8332d12b41c35863d5 (patch) | |
tree | 9d75f16d15f9331825e40bf55ae64158b1706d3d /module/zfs/dnode_sync.c | |
parent | 33df62d052bad11a1ebb220810672fcfba2a8d86 (diff) |
Illumos 6267 - dn_bonus evicted too early
6267 dn_bonus evicted too early
Reviewed by: Richard Yao <[email protected]>
Reviewed by: Xin LI <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Approved by: Richard Lowe <[email protected]>
References:
https://www.illumos.org/issues/6267
https://github.com/illumos/illumos-gate/commit/d205810
Signed-off-by: Brian Behlendorf <[email protected]>
Ported-by: Ned Bass [email protected]
Issue #3865
Issue #3443
Diffstat (limited to 'module/zfs/dnode_sync.c')
-rw-r--r-- | module/zfs/dnode_sync.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/module/zfs/dnode_sync.c b/module/zfs/dnode_sync.c index a8fa9a952..df5c8e4ee 100644 --- a/module/zfs/dnode_sync.c +++ b/module/zfs/dnode_sync.c @@ -432,6 +432,7 @@ dnode_evict_dbufs(dnode_t *dn) db_next = AVL_NEXT(&dn->dn_dbufs, db_marker); avl_remove(&dn->dn_dbufs, db_marker); } else { + db->db_pending_evict = TRUE; mutex_exit(&db->db_mtx); db_next = AVL_NEXT(&dn->dn_dbufs, db); } @@ -447,10 +448,14 @@ void dnode_evict_bonus(dnode_t *dn) { rw_enter(&dn->dn_struct_rwlock, RW_WRITER); - if (dn->dn_bonus && refcount_is_zero(&dn->dn_bonus->db_holds)) { - mutex_enter(&dn->dn_bonus->db_mtx); - dbuf_evict(dn->dn_bonus); - dn->dn_bonus = NULL; + if (dn->dn_bonus != NULL) { + if (refcount_is_zero(&dn->dn_bonus->db_holds)) { + mutex_enter(&dn->dn_bonus->db_mtx); + dbuf_evict(dn->dn_bonus); + dn->dn_bonus = NULL; + } else { + dn->dn_bonus->db_pending_evict = TRUE; + } } rw_exit(&dn->dn_struct_rwlock); } @@ -502,7 +507,6 @@ dnode_sync_free(dnode_t *dn, dmu_tx_t *tx) dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]); dnode_evict_dbufs(dn); - ASSERT(avl_is_empty(&dn->dn_dbufs)); /* * XXX - It would be nice to assert this, but we may still |