History

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.

Konstantin Khlebnikov committed 14 years ago

Commit fffaee31 parent f9ba7172 files · +7 −1Browse files

Unified · Split

2 files
  1. include/linux/radix-tree.h +4 −1
  2. lib/radix-tree.c +3 −0
include/linux/radix-tree.h+4−1
@@ -368,8 +368,11 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags) · 367 unmodified lines
368368 iter->index++;
369369 if (likely(*slot))
370370 return slot;
371− if (flags & RADIX_TREE_ITER_CONTIG)
371+ if (flags & RADIX_TREE_ITER_CONTIG) {
372+ /* forbid switching to the next chunk */
373+ iter->next_index = 0;
372374 break;
375+ }
373376 }
374377 }
375378 return NULL;
lib/radix-tree.c+3−0
@@ -686,6 +686,9 @@ void **radix_tree_next_chunk(struct radix_tree_root *root, · 685 unmodified lines
686686 * during iterating; it can be zero only at the beginning.
687687 * And we cannot overflow iter->next_index in a single step,
688688 * because RADIX_TREE_MAP_SHIFT < BITS_PER_LONG.
689+ *
690+ * This condition also used by radix_tree_next_slot() to stop
691+ * contiguous iterating, and forbid swithing to the next chunk.
689692 */
690693 index = iter->next_index;
691694 if (!index && iter->index)