diff options
author | Ross Zwisler <ross.zwisler@linux.intel.com> | 2016-05-20 20:02:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-20 20:58:30 -0400 |
commit | 4589ba6d0f439e4673830fdc65099179832ddde5 (patch) | |
tree | 2c6dc6832b3fa40765038f1e37f3adfd6c41198d /lib | |
parent | 00f47b581105b91f8f18edd3074322ae609a8bc5 (diff) |
radix-tree: rewrite radix_tree_tag_get
Use the new multi-order support functions to rewrite
radix_tree_tag_get()
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Signed-off-by: Matthew Wilcox <willy@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 | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index ee56562e0a2d..b1ca74489bc2 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -831,45 +831,37 @@ EXPORT_SYMBOL(radix_tree_tag_clear); | |||
831 | int radix_tree_tag_get(struct radix_tree_root *root, | 831 | int radix_tree_tag_get(struct radix_tree_root *root, |
832 | unsigned long index, unsigned int tag) | 832 | unsigned long index, unsigned int tag) |
833 | { | 833 | { |
834 | unsigned int height, shift; | 834 | struct radix_tree_node *node, *parent; |
835 | struct radix_tree_node *node; | 835 | unsigned long maxindex; |
836 | unsigned int shift; | ||
836 | 837 | ||
837 | /* check the root's tag bit */ | ||
838 | if (!root_tag_get(root, tag)) | 838 | if (!root_tag_get(root, tag)) |
839 | return 0; | 839 | return 0; |
840 | 840 | ||
841 | node = rcu_dereference_raw(root->rnode); | 841 | shift = radix_tree_load_root(root, &node, &maxindex); |
842 | if (index > maxindex) | ||
843 | return 0; | ||
842 | if (node == NULL) | 844 | if (node == NULL) |
843 | return 0; | 845 | return 0; |
844 | 846 | ||
845 | if (!radix_tree_is_indirect_ptr(node)) | 847 | while (radix_tree_is_indirect_ptr(node)) { |
846 | return (index == 0); | 848 | int offset; |
847 | node = indirect_to_ptr(node); | ||
848 | |||
849 | height = node->path & RADIX_TREE_HEIGHT_MASK; | ||
850 | if (index > radix_tree_maxindex(height)) | ||
851 | return 0; | ||
852 | 849 | ||
853 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 850 | shift -= RADIX_TREE_MAP_SHIFT; |
851 | offset = (index >> shift) & RADIX_TREE_MAP_MASK; | ||
854 | 852 | ||
855 | for ( ; ; ) { | 853 | parent = indirect_to_ptr(node); |
856 | int offset; | 854 | offset = radix_tree_descend(parent, &node, offset); |
857 | 855 | ||
858 | if (node == NULL) | 856 | if (!node) |
859 | return 0; | 857 | return 0; |
860 | node = indirect_to_ptr(node); | 858 | if (!tag_get(parent, tag, offset)) |
861 | |||
862 | offset = (index >> shift) & RADIX_TREE_MAP_MASK; | ||
863 | if (!tag_get(node, tag, offset)) | ||
864 | return 0; | 859 | return 0; |
865 | if (height == 1) | 860 | if (node == RADIX_TREE_RETRY) |
866 | return 1; | 861 | break; |
867 | node = rcu_dereference_raw(node->slots[offset]); | ||
868 | if (!radix_tree_is_indirect_ptr(node)) | ||
869 | return 1; | ||
870 | shift -= RADIX_TREE_MAP_SHIFT; | ||
871 | height--; | ||
872 | } | 862 | } |
863 | |||
864 | return 1; | ||
873 | } | 865 | } |
874 | EXPORT_SYMBOL(radix_tree_tag_get); | 866 | EXPORT_SYMBOL(radix_tree_tag_get); |
875 | 867 | ||