summaryrefslogtreecommitdiffstats
path: root/module/zfs/dnode_sync.c
diff options
context:
space:
mode:
authorAlex Reece <[email protected]>2015-04-03 14:14:28 +1100
committerBrian Behlendorf <[email protected]>2015-04-28 16:24:03 -0700
commit8951cb8dfb8dcf410a237656c1f9c9767e4a9e6c (patch)
treee057d73086a975a0e22eae721ddb332ec5c81e6b /module/zfs/dnode_sync.c
parent58c4aa00c65e09f254de0b939b2c1aa720c204a1 (diff)
Illumos 4873 - zvol unmap calls can take a very long time for larger datasets
4873 zvol unmap calls can take a very long time for larger datasets Author: Alex Reece <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Paul Dagnelie <[email protected]> Reviewed by: Basil Crow <[email protected]> Reviewed by: Dan McDonald <[email protected]> Approved by: Robert Mustacchi <[email protected]> References: https://www.illumos.org/issues/4873 https://github.com/illumos/illumos-gate/commit/0f6d88a Porting Notes: dbuf_free_range(): - reduce stack usage using kmem_alloc() - the sorted AVL tree will handle the spill block case correctly without all the special handling in the for() loop Ported-by: Chris Dunlop <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module/zfs/dnode_sync.c')
-rw-r--r--module/zfs/dnode_sync.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/module/zfs/dnode_sync.c b/module/zfs/dnode_sync.c
index 9779c51ef..4e613dd76 100644
--- a/module/zfs/dnode_sync.c
+++ b/module/zfs/dnode_sync.c
@@ -406,16 +406,13 @@ dnode_evict_dbufs(dnode_t *dn)
int pass = 0;
do {
- dmu_buf_impl_t *db, marker;
+ dmu_buf_impl_t *db, *db_next;
int evicting = FALSE;
progress = FALSE;
mutex_enter(&dn->dn_dbufs_mtx);
- list_insert_tail(&dn->dn_dbufs, &marker);
- db = list_head(&dn->dn_dbufs);
- for (; db != &marker; db = list_head(&dn->dn_dbufs)) {
- list_remove(&dn->dn_dbufs, db);
- list_insert_tail(&dn->dn_dbufs, db);
+ for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) {
+ db_next = AVL_NEXT(&dn->dn_dbufs, db);
#ifdef DEBUG
DB_DNODE_ENTER(db);
ASSERT3P(DB_DNODE(db), ==, dn);
@@ -435,7 +432,6 @@ dnode_evict_dbufs(dnode_t *dn)
}
}
- list_remove(&dn->dn_dbufs, &marker);
/*
* NB: we need to drop dn_dbufs_mtx between passes so
* that any DB_EVICTING dbufs can make progress.
@@ -516,7 +512,7 @@ dnode_sync_free(dnode_t *dn, dmu_tx_t *tx)
dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]);
dnode_evict_dbufs(dn);
- ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
+ ASSERT(avl_is_empty(&dn->dn_dbufs));
ASSERT3P(dn->dn_bonus, ==, NULL);
/*