diff --git a/[refs] b/[refs] index 37cb29f911fa..3fc17aa9367c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dc0afa8388972a9ed7c2203cc46d8df1a4713f65 +refs/heads/master: 7aae6dd80e265aa9402ed507caaff4a5dba55069 diff --git a/trunk/lib/idr.c b/trunk/lib/idr.c index 305117ca2d41..7b5a59caa989 100644 --- a/trunk/lib/idr.c +++ b/trunk/lib/idr.c @@ -100,10 +100,11 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id) int n, m, sh; struct idr_layer *p, *new; struct idr_layer *pa[MAX_LEVEL]; - int l, id; + int l, id, oid; long bm; id = *starting_id; + restart: p = idp->top; l = idp->layers; pa[l--] = NULL; @@ -117,12 +118,23 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id) if (m == IDR_SIZE) { /* no space available go back to previous layer. */ l++; + oid = id; id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; + + /* if already at the top layer, we need to grow */ if (!(p = pa[l])) { *starting_id = id; return -2; } - continue; + + /* If we need to go up one layer, continue the + * loop; otherwise, restart from the top. + */ + sh = IDR_BITS * (l + 1); + if (oid >> sh == id >> sh) + continue; + else + goto restart; } if (m != n) { sh = IDR_BITS*l;