diff options
-rw-r--r-- | lib/idr.c | 30 |
1 files changed, 12 insertions, 18 deletions
@@ -278,24 +278,15 @@ build_up: | |||
278 | return(v); | 278 | return(v); |
279 | } | 279 | } |
280 | 280 | ||
281 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | 281 | /* |
282 | * @id and @pa are from a successful allocation from idr_get_empty_slot(). | ||
283 | * Install the user pointer @ptr and mark the slot full. | ||
284 | */ | ||
285 | static void idr_fill_slot(void *ptr, int id, struct idr_layer **pa) | ||
282 | { | 286 | { |
283 | struct idr_layer *pa[MAX_IDR_LEVEL]; | 287 | rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr); |
284 | int id; | 288 | pa[0]->count++; |
285 | 289 | idr_mark_full(pa, id); | |
286 | id = idr_get_empty_slot(idp, starting_id, pa); | ||
287 | if (id >= 0) { | ||
288 | /* | ||
289 | * Successfully found an empty slot. Install the user | ||
290 | * pointer and mark the slot full. | ||
291 | */ | ||
292 | rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], | ||
293 | (struct idr_layer *)ptr); | ||
294 | pa[0]->count++; | ||
295 | idr_mark_full(pa, id); | ||
296 | } | ||
297 | |||
298 | return id; | ||
299 | } | 290 | } |
300 | 291 | ||
301 | /** | 292 | /** |
@@ -318,11 +309,14 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | |||
318 | */ | 309 | */ |
319 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id) | 310 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id) |
320 | { | 311 | { |
312 | struct idr_layer *pa[MAX_IDR_LEVEL]; | ||
321 | int rv; | 313 | int rv; |
322 | 314 | ||
323 | rv = idr_get_new_above_int(idp, ptr, starting_id); | 315 | rv = idr_get_empty_slot(idp, starting_id, pa); |
324 | if (rv < 0) | 316 | if (rv < 0) |
325 | return rv == -ENOMEM ? -EAGAIN : rv; | 317 | return rv == -ENOMEM ? -EAGAIN : rv; |
318 | |||
319 | idr_fill_slot(ptr, rv, pa); | ||
326 | *id = rv; | 320 | *id = rv; |
327 | return 0; | 321 | return 0; |
328 | } | 322 | } |