diff options
author | Dave Kleikamp <shaggy@austin.ibm.com> | 2004-11-15 04:06:16 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-15 04:06:16 -0800 |
commit | d9f868c4656ae0903dcdcfd257b35d4cf7e80f05 (patch) | |
tree | 87eea0e8d845d8b29b226dcfd1890901d292c3f2 /lib | |
parent | 4062e12b2ba22fc5302d1d501a14c40ab4d89676 (diff) | |
download | history-d9f868c4656ae0903dcdcfd257b35d4cf7e80f05.tar.gz |
[PATCH] radix_tree_delete() fix
I was looking through the radix tree code and came across what I think
is a bug in radix_tree_delete.
for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
if (pathp[0].node->tags[tag][idx]) {
tags[tag] = 1;
nr_cleared_tags--;
break;
}
}
The above loop should only be executed if tags[tag] is zero. Otherwise,
when walking up the tree, we can decrement nr_cleared_tags twice or more
for the same value of tag, thus potentially exiting the outer loop too
early.
Ensure that nr_cleared_tags is only decremented once for each tag.
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/radix-tree.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index a0a0902614e7c0..04d664377f2c62 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -701,8 +701,10 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) for (tag = 0; tag < RADIX_TREE_TAGS; tag++) { int idx; - if (!tags[tag]) - tag_clear(pathp[0].node, tag, pathp[0].offset); + if (tags[tag]) + continue; + + tag_clear(pathp[0].node, tag, pathp[0].offset); for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { if (pathp[0].node->tags[tag][idx]) { |