summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2016-12-14 18:08:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-14 19:04:10 -0500
commit9498d2bb34b0866829c313569df35e77a83f12eb (patch)
treedb19aaa39dc04f8ad77335a06623a2443717a872 /lib
parent91d9c05ac6c788531136888d31ef18c6a0ec160f (diff)
radix-tree: create node_tag_set()
Similar to node_tag_clear(), factor node_tag_set() out of radix_tree_range_tag_if_tagged(). Link: http://lkml.kernel.org/r/1480369871-5271-51-git-send-email-mawilcox@linuxonhyperv.com Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Matthew Wilcox <mawilcox@microsoft.com> 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.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 8c5911eae5e2..a90a4371deb8 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -991,6 +991,22 @@ static void node_tag_clear(struct radix_tree_root *root,
991 root_tag_clear(root, tag); 991 root_tag_clear(root, tag);
992} 992}
993 993
994static void node_tag_set(struct radix_tree_root *root,
995 struct radix_tree_node *node,
996 unsigned int tag, unsigned int offset)
997{
998 while (node) {
999 if (tag_get(node, tag, offset))
1000 return;
1001 tag_set(node, tag, offset);
1002 offset = node->offset;
1003 node = node->parent;
1004 }
1005
1006 if (!root_tag_get(root, tag))
1007 root_tag_set(root, tag);
1008}
1009
994/** 1010/**
995 * radix_tree_tag_clear - clear a tag on a radix tree node 1011 * radix_tree_tag_clear - clear a tag on a radix tree node
996 * @root: radix tree root 1012 * @root: radix tree root
@@ -1229,7 +1245,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1229 unsigned long nr_to_tag, 1245 unsigned long nr_to_tag,
1230 unsigned int iftag, unsigned int settag) 1246 unsigned int iftag, unsigned int settag)
1231{ 1247{
1232 struct radix_tree_node *parent, *node, *child; 1248 struct radix_tree_node *node, *child;
1233 unsigned long maxindex; 1249 unsigned long maxindex;
1234 unsigned long tagged = 0; 1250 unsigned long tagged = 0;
1235 unsigned long index = *first_indexp; 1251 unsigned long index = *first_indexp;
@@ -1264,22 +1280,8 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1264 continue; 1280 continue;
1265 } 1281 }
1266 1282
1267 /* tag the leaf */
1268 tagged++; 1283 tagged++;
1269 tag_set(node, settag, offset); 1284 node_tag_set(root, node, settag, offset);
1270
1271 /* walk back up the path tagging interior nodes */
1272 parent = node;
1273 for (;;) {
1274 offset = parent->offset;
1275 parent = parent->parent;
1276 if (!parent)
1277 break;
1278 /* stop if we find a node with the tag already set */
1279 if (tag_get(parent, settag, offset))
1280 break;
1281 tag_set(parent, settag, offset);
1282 }
1283 next: 1285 next:
1284 /* Go to next entry in node */ 1286 /* Go to next entry in node */
1285 index = ((index >> node->shift) + 1) << node->shift; 1287 index = ((index >> node->shift) + 1) << node->shift;
@@ -1301,12 +1303,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
1301 if (tagged >= nr_to_tag) 1303 if (tagged >= nr_to_tag)
1302 break; 1304 break;
1303 } 1305 }
1304 /* 1306
1305 * We need not to tag the root tag if there is no tag which is set with
1306 * settag within the range from *first_indexp to last_index.
1307 */
1308 if (tagged > 0)
1309 root_tag_set(root, settag);
1310 *first_indexp = index; 1307 *first_indexp = index;
1311 1308
1312 return tagged; 1309 return tagged;