diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-12-13 09:12:51 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-12-13 09:12:51 +0000 |
commit | 72aaf09fda49f5919d98d65d35e5179f3acb0497 (patch) | |
tree | 5fd25748f7f5640f8ee8efb86ddca88d12840791 /lib | |
parent | 67fbc2312312095acc2f19a0b601bac10f84cf9d (diff) | |
parent | 58c2467355ed3154a12ee49d8f8236547145c9d3 (diff) | |
download | op-kernel-dev-72aaf09fda49f5919d98d65d35e5179f3acb0497.zip op-kernel-dev-72aaf09fda49f5919d98d65d35e5179f3acb0497.tar.gz |
Merge git://git.marvell.com/orion into devel
Diffstat (limited to 'lib')
-rw-r--r-- | lib/idr.c | 14 |
1 files changed, 12 insertions, 2 deletions
@@ -185,6 +185,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) new = get_from_free_list(idp); if (!new) return -1; + new->layer = l-1; rcu_assign_pointer(p->ary[m], new); p->count++; } @@ -210,6 +211,7 @@ build_up: if (unlikely(!p)) { if (!(p = get_from_free_list(idp))) return -1; + p->layer = 0; layers = 1; } /* @@ -237,6 +239,7 @@ build_up: } new->ary[0] = p; new->count = 1; + new->layer = layers-1; if (p->bitmap == IDR_FULL) __set_bit(0, &new->bitmap); p = new; @@ -493,17 +496,21 @@ void *idr_find(struct idr *idp, int id) int n; struct idr_layer *p; - n = idp->layers * IDR_BITS; p = rcu_dereference(idp->top); + if (!p) + return NULL; + n = (p->layer+1) * IDR_BITS; /* Mask off upper bits we don't use for the search. */ id &= MAX_ID_MASK; if (id >= (1 << n)) return NULL; + BUG_ON(n == 0); while (n > 0 && p) { n -= IDR_BITS; + BUG_ON(n != p->layer*IDR_BITS); p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); } return((void *)p); @@ -582,8 +589,11 @@ void *idr_replace(struct idr *idp, void *ptr, int id) int n; struct idr_layer *p, *old_p; - n = idp->layers * IDR_BITS; p = idp->top; + if (!p) + return ERR_PTR(-EINVAL); + + n = (p->layer+1) * IDR_BITS; id &= MAX_ID_MASK; |