diff options
author | Matthew Wilcox <willy@linux.intel.com> | 2016-05-20 20:02:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 20:58:30 -0400 |
commit | 858299544efcf2577511bb018b9e73637ac71a2f (patch) | |
tree | 83572e5d6287b5dce72aad2caf48f4dfc1ffefa5 /lib | |
parent | afe0e395b6d1817fa5393f1ad6fcbf71406b016d (diff) |
radix-tree: rewrite __radix_tree_lookup
Use the new multi-order support functions to rewrite __radix_tree_lookup()
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kirill Shutemov <kirill.shutemov@linux.intel.com>
Cc: Jan Kara <jack@suse.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/radix-tree.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index a1ba41730071..f14ada9830ca 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -634,44 +634,28 @@ void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index, | |||
634 | struct radix_tree_node **nodep, void ***slotp) | 634 | struct radix_tree_node **nodep, void ***slotp) |
635 | { | 635 | { |
636 | struct radix_tree_node *node, *parent; | 636 | struct radix_tree_node *node, *parent; |
637 | unsigned int height, shift; | 637 | unsigned long maxindex; |
638 | unsigned int shift; | ||
638 | void **slot; | 639 | void **slot; |
639 | 640 | ||
640 | node = rcu_dereference_raw(root->rnode); | 641 | restart: |
641 | if (node == NULL) | 642 | parent = NULL; |
642 | return NULL; | 643 | slot = (void **)&root->rnode; |
643 | 644 | shift = radix_tree_load_root(root, &node, &maxindex); | |
644 | if (!radix_tree_is_indirect_ptr(node)) { | 645 | if (index > maxindex) |
645 | if (index > 0) | ||
646 | return NULL; | ||
647 | |||
648 | if (nodep) | ||
649 | *nodep = NULL; | ||
650 | if (slotp) | ||
651 | *slotp = (void **)&root->rnode; | ||
652 | return node; | ||
653 | } | ||
654 | node = indirect_to_ptr(node); | ||
655 | |||
656 | height = node->path & RADIX_TREE_HEIGHT_MASK; | ||
657 | if (index > radix_tree_maxindex(height)) | ||
658 | return NULL; | 646 | return NULL; |
659 | 647 | ||
660 | shift = (height-1) * RADIX_TREE_MAP_SHIFT; | 648 | while (radix_tree_is_indirect_ptr(node)) { |
661 | 649 | unsigned offset; | |
662 | do { | ||
663 | parent = node; | ||
664 | slot = node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK); | ||
665 | node = rcu_dereference_raw(*slot); | ||
666 | if (node == NULL) | ||
667 | return NULL; | ||
668 | if (!radix_tree_is_indirect_ptr(node)) | ||
669 | break; | ||
670 | node = indirect_to_ptr(node); | ||
671 | 650 | ||
651 | if (node == RADIX_TREE_RETRY) | ||
652 | goto restart; | ||
653 | parent = indirect_to_ptr(node); | ||
672 | shift -= RADIX_TREE_MAP_SHIFT; | 654 | shift -= RADIX_TREE_MAP_SHIFT; |
673 | height--; | 655 | offset = (index >> shift) & RADIX_TREE_MAP_MASK; |
674 | } while (height > 0); | 656 | offset = radix_tree_descend(parent, &node, offset); |
657 | slot = parent->slots + offset; | ||
658 | } | ||
675 | 659 | ||
676 | if (nodep) | 660 | if (nodep) |
677 | *nodep = parent; | 661 | *nodep = parent; |