radix-tree: fix race in gang lookup
authorMatthew Wilcox <willy@linux.intel.com>
Wed, 3 Feb 2016 00:57:52 +0000 (16:57 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Feb 2016 20:01:23 +0000 (12:01 -0800)
commitf4595e0081495b677a98c780e9ec1ab68ce89488
tree969674b2a1fb46c713b01ead74279c939456c315
parent262139f0244b3ade149b785dc820118c4265cdb1
radix-tree: fix race in gang lookup

commit 46437f9a554fbe3e110580ca08ab703b59f2f95a upstream.

If the indirect_ptr bit is set on a slot, that indicates we need to redo
the lookup.  Introduce a new function radix_tree_iter_retry() which
forces the loop to retry the lookup by setting 'slot' to NULL and
turning the iterator back to point at the problematic entry.

This is a pretty rare problem to hit at the moment; the lookup has to
race with a grow of the radix tree from a height of 0.  The consequences
of hitting this race are that gang lookup could return a pointer to a
radix_tree_node instead of a pointer to whatever the user had inserted
in the tree.

Fixes: cebbd29e1c2f ("radix-tree: rewrite gang lookup using iterator")
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ohad Ben-Cohen <ohad@wizery.com>
Cc: Konstantin Khlebnikov <khlebnikov@openvz.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/radix-tree.h
lib/radix-tree.c