diff options
Diffstat (limited to 'lib/idr.c')
| -rw-r--r-- | lib/idr.c | 16 |
1 files changed, 12 insertions, 4 deletions
| @@ -48,15 +48,21 @@ static struct idr_layer *alloc_layer(struct idr *idp) | |||
| 48 | return(p); | 48 | return(p); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /* only called when idp->lock is held */ | ||
| 52 | static void __free_layer(struct idr *idp, struct idr_layer *p) | ||
| 53 | { | ||
| 54 | p->ary[0] = idp->id_free; | ||
| 55 | idp->id_free = p; | ||
| 56 | idp->id_free_cnt++; | ||
| 57 | } | ||
| 58 | |||
| 51 | static void free_layer(struct idr *idp, struct idr_layer *p) | 59 | static void free_layer(struct idr *idp, struct idr_layer *p) |
| 52 | { | 60 | { |
| 53 | /* | 61 | /* |
| 54 | * Depends on the return element being zeroed. | 62 | * Depends on the return element being zeroed. |
| 55 | */ | 63 | */ |
| 56 | spin_lock(&idp->lock); | 64 | spin_lock(&idp->lock); |
| 57 | p->ary[0] = idp->id_free; | 65 | __free_layer(idp, p); |
| 58 | idp->id_free = p; | ||
| 59 | idp->id_free_cnt++; | ||
| 60 | spin_unlock(&idp->lock); | 66 | spin_unlock(&idp->lock); |
| 61 | } | 67 | } |
| 62 | 68 | ||
| @@ -184,12 +190,14 @@ build_up: | |||
| 184 | * The allocation failed. If we built part of | 190 | * The allocation failed. If we built part of |
| 185 | * the structure tear it down. | 191 | * the structure tear it down. |
| 186 | */ | 192 | */ |
| 193 | spin_lock(&idp->lock); | ||
| 187 | for (new = p; p && p != idp->top; new = p) { | 194 | for (new = p; p && p != idp->top; new = p) { |
| 188 | p = p->ary[0]; | 195 | p = p->ary[0]; |
| 189 | new->ary[0] = NULL; | 196 | new->ary[0] = NULL; |
| 190 | new->bitmap = new->count = 0; | 197 | new->bitmap = new->count = 0; |
| 191 | free_layer(idp, new); | 198 | __free_layer(idp, new); |
| 192 | } | 199 | } |
| 200 | spin_unlock(&idp->lock); | ||
| 193 | return -1; | 201 | return -1; |
| 194 | } | 202 | } |
| 195 | new->ary[0] = p; | 203 | new->ary[0] = p; |
