From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 23 Aug 2010 02:55:14 +0000 (-0700)
Subject: Merge branch 'radix-tree' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/xfsdev
X-Git-Tag: firefly_0821_release~9833^2~678
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9ee47476d6734c9deb9ae9ab05d963302f6b6150;p=firefly-linux-kernel-4.4.55.git

Merge branch 'radix-tree' of git://git./linux/kernel/git/dgc/xfsdev

* 'radix-tree' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/xfsdev:
  radix-tree: radix_tree_range_tag_if_tagged() can set incorrect tags
  radix-tree: clear all tags in radix_tree_node_rcu_free
---

9ee47476d6734c9deb9ae9ab05d963302f6b6150
diff --cc lib/radix-tree.c
index 5b7d4623f0b7,e0ee8cb37e41..efd16fa80b1c
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@@ -623,10 -625,15 +625,17 @@@ EXPORT_SYMBOL(radix_tree_tag_get)
   * also settag. The function stops either after tagging nr_to_tag items or
   * after reaching last_index.
   *
+  * The tags must be set from the leaf level only and propagated back up the
+  * path to the root. We must do this so that we resolve the full path before
+  * setting any tags on intermediate nodes. If we set tags as we descend, then
+  * we can get to the leaf node and find that the index that has the iftag
+  * set is outside the range we are scanning. This reults in dangling tags and
+  * can lead to problems with later tag operations (e.g. livelocks on lookups).
+  *
   * The function returns number of leaves where the tag was set and sets
   * *first_indexp to the first unscanned index.
 + * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must
 + * be prepared to handle that.
   */
  unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
  		unsigned long *first_indexp, unsigned long last_index,