diff options
-rw-r--r-- | drivers/scsi/sd.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0c63947d8a9d..99dddcae7851 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -99,8 +99,7 @@ static void scsi_disk_release(struct device *cdev); | |||
99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | 99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); |
100 | static void sd_print_result(struct scsi_disk *, int); | 100 | static void sd_print_result(struct scsi_disk *, int); |
101 | 101 | ||
102 | static DEFINE_IDR(sd_index_idr); | 102 | static DEFINE_IDA(sd_index_ida); |
103 | static DEFINE_SPINLOCK(sd_index_lock); | ||
104 | 103 | ||
105 | /* This semaphore is used to mediate the 0->1 reference get in the | 104 | /* This semaphore is used to mediate the 0->1 reference get in the |
106 | * face of object destruction (i.e. we can't allow a get on an | 105 | * face of object destruction (i.e. we can't allow a get on an |
@@ -1643,18 +1642,20 @@ static int sd_probe(struct device *dev) | |||
1643 | if (!gd) | 1642 | if (!gd) |
1644 | goto out_free; | 1643 | goto out_free; |
1645 | 1644 | ||
1646 | if (!idr_pre_get(&sd_index_idr, GFP_KERNEL)) | 1645 | do { |
1647 | goto out_put; | 1646 | if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) |
1647 | goto out_put; | ||
1648 | 1648 | ||
1649 | spin_lock(&sd_index_lock); | 1649 | error = ida_get_new(&sd_index_ida, &index); |
1650 | error = idr_get_new(&sd_index_idr, NULL, &index); | 1650 | } while (error == -EAGAIN); |
1651 | spin_unlock(&sd_index_lock); | ||
1652 | 1651 | ||
1653 | if (index >= SD_MAX_DISKS) | ||
1654 | error = -EBUSY; | ||
1655 | if (error) | 1652 | if (error) |
1656 | goto out_put; | 1653 | goto out_put; |
1657 | 1654 | ||
1655 | error = -EBUSY; | ||
1656 | if (index >= SD_MAX_DISKS) | ||
1657 | goto out_free_index; | ||
1658 | |||
1658 | sdkp->device = sdp; | 1659 | sdkp->device = sdp; |
1659 | sdkp->driver = &sd_template; | 1660 | sdkp->driver = &sd_template; |
1660 | sdkp->disk = gd; | 1661 | sdkp->disk = gd; |
@@ -1675,7 +1676,7 @@ static int sd_probe(struct device *dev) | |||
1675 | strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); | 1676 | strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); |
1676 | 1677 | ||
1677 | if (device_add(&sdkp->dev)) | 1678 | if (device_add(&sdkp->dev)) |
1678 | goto out_put; | 1679 | goto out_free_index; |
1679 | 1680 | ||
1680 | get_device(&sdp->sdev_gendev); | 1681 | get_device(&sdp->sdev_gendev); |
1681 | 1682 | ||
@@ -1717,6 +1718,8 @@ static int sd_probe(struct device *dev) | |||
1717 | 1718 | ||
1718 | return 0; | 1719 | return 0; |
1719 | 1720 | ||
1721 | out_free_index: | ||
1722 | ida_remove(&sd_index_ida, index); | ||
1720 | out_put: | 1723 | out_put: |
1721 | put_disk(gd); | 1724 | put_disk(gd); |
1722 | out_free: | 1725 | out_free: |
@@ -1766,9 +1769,7 @@ static void scsi_disk_release(struct device *dev) | |||
1766 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 1769 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
1767 | struct gendisk *disk = sdkp->disk; | 1770 | struct gendisk *disk = sdkp->disk; |
1768 | 1771 | ||
1769 | spin_lock(&sd_index_lock); | 1772 | ida_remove(&sd_index_ida, sdkp->index); |
1770 | idr_remove(&sd_index_idr, sdkp->index); | ||
1771 | spin_unlock(&sd_index_lock); | ||
1772 | 1773 | ||
1773 | disk->private_data = NULL; | 1774 | disk->private_data = NULL; |
1774 | put_disk(disk); | 1775 | put_disk(disk); |