radix-tree: fix contiguous iterator
This patch fixes bug in macro radix_tree_for_each_contig(). If radix_tree_next_slot() sees NULL in next slot it returns NULL, but following radix_tree_next_chunk() switches iterating into next chunk. As result iterating becomes non-contiguous and breaks vfs "splice" and all its users. Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org> Reported-and-bisected-by: Hans de Bruin <jmdebruin@xmsnet.nl> Reported-and-bisected-by: Ondrej Zary <linux@rainbow-software.org> Reported-bisected-and-tested-by: Toralf Förster <toralf.foerster@gmx.de> Link: https://lkml.org/lkml/2012/6/5/64 Cc: stable <stable@vger.kernel.org> # 3.4.x Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f9ba7179ce
commit
fffaee365f
|
@ -368,10 +368,13 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
|
|||
iter->index++;
|
||||
if (likely(*slot))
|
||||
return slot;
|
||||
if (flags & RADIX_TREE_ITER_CONTIG)
|
||||
if (flags & RADIX_TREE_ITER_CONTIG) {
|
||||
/* forbid switching to the next chunk */
|
||||
iter->next_index = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -686,6 +686,9 @@ void **radix_tree_next_chunk(struct radix_tree_root *root,
|
|||
* during iterating; it can be zero only at the beginning.
|
||||
* And we cannot overflow iter->next_index in a single step,
|
||||
* because RADIX_TREE_MAP_SHIFT < BITS_PER_LONG.
|
||||
*
|
||||
* This condition also used by radix_tree_next_slot() to stop
|
||||
* contiguous iterating, and forbid swithing to the next chunk.
|
||||
*/
|
||||
index = iter->next_index;
|
||||
if (!index && iter->index)
|
||||
|
|
Loading…
Reference in New Issue