mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
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 <alex@delphix.com> Reviewed by: George Wilson <george@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: Paul Dagnelie <paul.dagnelie@delphix.com> Reviewed by: Basil Crow <basil.crow@delphix.com> Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Robert Mustacchi <rm@joyent.com> 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 <chris@onthe.net.au> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
committed by
Brian Behlendorf
parent
58c4aa00c6
commit
8951cb8dfb
@@ -23,6 +23,10 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* AVL - generic AVL tree implementation for kernel use
|
||||
*
|
||||
@@ -85,6 +89,12 @@
|
||||
* is a modified "avl_node_t *". The bottom bit (normally 0 for a
|
||||
* pointer) is set to indicate if that the new node has a value greater
|
||||
* than the value of the indicated "avl_node_t *".
|
||||
*
|
||||
* Note - in addition to userland (e.g. libavl and libutil) and the kernel
|
||||
* (e.g. genunix), avl.c is compiled into ld.so and kmdb's genunix module,
|
||||
* which each have their own compilation environments and subsequent
|
||||
* requirements. Each of these environments must be considered when adding
|
||||
* dependencies from avl.c.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -863,6 +873,24 @@ avl_update(avl_tree_t *t, void *obj)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
avl_swap(avl_tree_t *tree1, avl_tree_t *tree2)
|
||||
{
|
||||
avl_node_t *temp_node;
|
||||
ulong_t temp_numnodes;
|
||||
|
||||
ASSERT3P(tree1->avl_compar, ==, tree2->avl_compar);
|
||||
ASSERT3U(tree1->avl_offset, ==, tree2->avl_offset);
|
||||
ASSERT3U(tree1->avl_size, ==, tree2->avl_size);
|
||||
|
||||
temp_node = tree1->avl_root;
|
||||
temp_numnodes = tree1->avl_numnodes;
|
||||
tree1->avl_root = tree2->avl_root;
|
||||
tree1->avl_numnodes = tree2->avl_numnodes;
|
||||
tree2->avl_root = temp_node;
|
||||
tree2->avl_numnodes = temp_numnodes;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize a new AVL tree
|
||||
*/
|
||||
@@ -1058,6 +1086,8 @@ EXPORT_SYMBOL(avl_first);
|
||||
EXPORT_SYMBOL(avl_last);
|
||||
EXPORT_SYMBOL(avl_nearest);
|
||||
EXPORT_SYMBOL(avl_add);
|
||||
EXPORT_SYMBOL(avl_swap);
|
||||
EXPORT_SYMBOL(avl_is_empty);
|
||||
EXPORT_SYMBOL(avl_remove);
|
||||
EXPORT_SYMBOL(avl_numnodes);
|
||||
EXPORT_SYMBOL(avl_destroy_nodes);
|
||||
|
||||
Reference in New Issue
Block a user