aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRoss Zwisler <ross.zwisler@linux.intel.com>2016-05-20 20:02:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit4589ba6d0f439e4673830fdc65099179832ddde5 (patch)
tree2c6dc6832b3fa40765038f1e37f3adfd6c41198d /lib
parent00f47b581105b91f8f18edd3074322ae609a8bc5 (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.c44
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);
831int radix_tree_tag_get(struct radix_tree_root *root, 831int 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}
874EXPORT_SYMBOL(radix_tree_tag_get); 866EXPORT_SYMBOL(radix_tree_tag_get);
875 867