aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-07-14 01:59:30 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-26 15:14:50 -0400
commitf27bac2761cab5a2e212dea602d22457a9aa6943 (patch)
treef2ebed0b9d35298697c96ac8896ec34ba2a07a78 /drivers/scsi
parentecefe8a97577d6c1a68d14ab6fb19bce99448af2 (diff)
[SCSI] sd: update index allocation and use ida instead of idr
Update index allocation as follows. * sd_index_idr is used only for ID allocation and mapping functionality is not used. Use more memory efficient ida instead. * idr and ida have their own locks inside them and don't need them for operation. Drop it. * index wasn't freed if probing failed after index allocation. fix it. * ida allocation should be repeated if it fails with -EAGAIN. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sd.c27
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);
99static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 99static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
100static void sd_print_result(struct scsi_disk *, int); 100static void sd_print_result(struct scsi_disk *, int);
101 101
102static DEFINE_IDR(sd_index_idr); 102static DEFINE_IDA(sd_index_ida);
103static 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);