aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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