summaryrefslogtreecommitdiffstats
path: root/lib/radix-tree.c
diff options
context:
space:
mode:
authorRoss Zwisler <ross.zwisler@linux.intel.com>2016-05-20 20:02:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit00f47b581105b91f8f18edd3074322ae609a8bc5 (patch)
tree4b3306cb5ca32ba6851db8bc618d6c41371312c7 /lib/radix-tree.c
parentfb969909dd18930ad68d8f8b8e7895816cf74b0a (diff)
radix-tree: rewrite radix_tree_tag_clear
Use the new multi-order support functions to rewrite radix_tree_tag_clear() 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/radix-tree.c')
-rw-r--r--lib/radix-tree.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 5234a95024a3..ee56562e0a2d 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -768,44 +768,40 @@ EXPORT_SYMBOL(radix_tree_tag_set);
768void *radix_tree_tag_clear(struct radix_tree_root *root, 768void *radix_tree_tag_clear(struct radix_tree_root *root,
769 unsigned long index, unsigned int tag) 769 unsigned long index, unsigned int tag)
770{ 770{
771 struct radix_tree_node *node = NULL; 771 struct radix_tree_node *node, *parent;
772 struct radix_tree_node *slot = NULL; 772 unsigned long maxindex;
773 unsigned int height, shift; 773 unsigned int shift;
774 int uninitialized_var(offset); 774 int uninitialized_var(offset);
775 775
776 height = root->height; 776 shift = radix_tree_load_root(root, &node, &maxindex);
777 if (index > radix_tree_maxindex(height)) 777 if (index > maxindex)
778 goto out; 778 return NULL;
779
780 shift = height * RADIX_TREE_MAP_SHIFT;
781 slot = root->rnode;
782 779
783 while (shift) { 780 parent = NULL;
784 if (slot == NULL)
785 goto out;
786 if (!radix_tree_is_indirect_ptr(slot))
787 break;
788 slot = indirect_to_ptr(slot);
789 781
782 while (radix_tree_is_indirect_ptr(node)) {
790 shift -= RADIX_TREE_MAP_SHIFT; 783 shift -= RADIX_TREE_MAP_SHIFT;
791 offset = (index >> shift) & RADIX_TREE_MAP_MASK; 784 offset = (index >> shift) & RADIX_TREE_MAP_MASK;
792 node = slot; 785
793 slot = slot->slots[offset]; 786 parent = indirect_to_ptr(node);
787 offset = radix_tree_descend(parent, &node, offset);
794 } 788 }
795 789
796 if (slot == NULL) 790 if (node == NULL)
797 goto out; 791 goto out;
798 792
799 while (node) { 793 index >>= shift;
800 if (!tag_get(node, tag, offset)) 794
795 while (parent) {
796 if (!tag_get(parent, tag, offset))
801 goto out; 797 goto out;
802 tag_clear(node, tag, offset); 798 tag_clear(parent, tag, offset);
803 if (any_tag_set(node, tag)) 799 if (any_tag_set(parent, tag))
804 goto out; 800 goto out;
805 801
806 index >>= RADIX_TREE_MAP_SHIFT; 802 index >>= RADIX_TREE_MAP_SHIFT;
807 offset = index & RADIX_TREE_MAP_MASK; 803 offset = index & RADIX_TREE_MAP_MASK;
808 node = node->parent; 804 parent = parent->parent;
809 } 805 }
810 806
811 /* clear the root's tag bit */ 807 /* clear the root's tag bit */
@@ -813,7 +809,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
813 root_tag_clear(root, tag); 809 root_tag_clear(root, tag);
814 810
815out: 811out:
816 return slot; 812 return node;
817} 813}
818EXPORT_SYMBOL(radix_tree_tag_clear); 814EXPORT_SYMBOL(radix_tree_tag_clear);
819 815