diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2008-12-10 18:17:06 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-12-18 09:13:36 -0800 |
commit | b543708755a23b1de7ba140061b93bb17a5e22e4 (patch) | |
tree | bfe2e33afc90576cd412f6f2eddaf980b4293108 /lib | |
parent | feb374144807f9d83d48930c3bae32005441230f (diff) | |
download | lwn-b543708755a23b1de7ba140061b93bb17a5e22e4.tar.gz lwn-b543708755a23b1de7ba140061b93bb17a5e22e4.zip |
lib/idr.c: Fix bug introduced by RCU fix
commit 711a49a07f84f914aac26a52143f6e7526571143 upstream.
The last patch to lib/idr.c caused a bug if idr_get_new_above() was
called on an empty idr.
Usually, nodes stay on the same layer. New layers are added to the top
of the tree.
The exception is idr_get_new_above() on an empty tree: In this case, the
new root node is first added on layer 0, then moved upwards. p->layer
was not updated.
As usual: You shall never rely on the source code comments, they will
only mislead you.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/idr.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/lib/idr.c b/lib/idr.c index 7a785a0c2ea0..1c4f9281f412 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -220,8 +220,14 @@ build_up: */ while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { layers++; - if (!p->count) + if (!p->count) { + /* special case: if the tree is currently empty, + * then we grow the tree by moving the top node + * upwards. + */ + p->layer++; continue; + } if (!(new = get_from_free_list(idp))) { /* * The allocation failed. If we built part of |