diff options
Diffstat (limited to 'block/genhd.c')
-rw-r--r-- | block/genhd.c | 21 |
1 files changed, 6 insertions, 15 deletions
diff --git a/block/genhd.c b/block/genhd.c index 841b3037d866..3c001fba80c7 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -411,7 +411,7 @@ static int blk_mangle_minor(int minor) | |||
411 | int blk_alloc_devt(struct hd_struct *part, dev_t *devt) | 411 | int blk_alloc_devt(struct hd_struct *part, dev_t *devt) |
412 | { | 412 | { |
413 | struct gendisk *disk = part_to_disk(part); | 413 | struct gendisk *disk = part_to_disk(part); |
414 | int idx, rc; | 414 | int idx; |
415 | 415 | ||
416 | /* in consecutive minor range? */ | 416 | /* in consecutive minor range? */ |
417 | if (part->partno < disk->minors) { | 417 | if (part->partno < disk->minors) { |
@@ -420,20 +420,11 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | /* allocate ext devt */ | 422 | /* allocate ext devt */ |
423 | do { | 423 | mutex_lock(&ext_devt_mutex); |
424 | if (!idr_pre_get(&ext_devt_idr, GFP_KERNEL)) | 424 | idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_KERNEL); |
425 | return -ENOMEM; | 425 | mutex_unlock(&ext_devt_mutex); |
426 | mutex_lock(&ext_devt_mutex); | 426 | if (idx < 0) |
427 | rc = idr_get_new(&ext_devt_idr, part, &idx); | 427 | return idx == -ENOSPC ? -EBUSY : idx; |
428 | if (!rc && idx >= NR_EXT_DEVT) { | ||
429 | idr_remove(&ext_devt_idr, idx); | ||
430 | rc = -EBUSY; | ||
431 | } | ||
432 | mutex_unlock(&ext_devt_mutex); | ||
433 | } while (rc == -EAGAIN); | ||
434 | |||
435 | if (rc) | ||
436 | return rc; | ||
437 | 428 | ||
438 | *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx)); | 429 | *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx)); |
439 | return 0; | 430 | return 0; |