diff options
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r-- | drivers/scsi/sg.c | 43 |
1 files changed, 17 insertions, 26 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index be2c9a6561ff..9f0c46547459 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1391,24 +1391,23 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1391 | return ERR_PTR(-ENOMEM); | 1391 | return ERR_PTR(-ENOMEM); |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) { | 1394 | idr_preload(GFP_KERNEL); |
1395 | printk(KERN_WARNING "idr expansion Sg_device failure\n"); | ||
1396 | error = -ENOMEM; | ||
1397 | goto out; | ||
1398 | } | ||
1399 | |||
1400 | write_lock_irqsave(&sg_index_lock, iflags); | 1395 | write_lock_irqsave(&sg_index_lock, iflags); |
1401 | 1396 | ||
1402 | error = idr_get_new(&sg_index_idr, sdp, &k); | 1397 | error = idr_alloc(&sg_index_idr, sdp, 0, SG_MAX_DEVS, GFP_NOWAIT); |
1403 | if (error) { | 1398 | if (error < 0) { |
1404 | write_unlock_irqrestore(&sg_index_lock, iflags); | 1399 | if (error == -ENOSPC) { |
1405 | printk(KERN_WARNING "idr allocation Sg_device failure: %d\n", | 1400 | sdev_printk(KERN_WARNING, scsidp, |
1406 | error); | 1401 | "Unable to attach sg device type=%d, minor number exceeds %d\n", |
1407 | goto out; | 1402 | scsidp->type, SG_MAX_DEVS - 1); |
1403 | error = -ENODEV; | ||
1404 | } else { | ||
1405 | printk(KERN_WARNING | ||
1406 | "idr allocation Sg_device failure: %d\n", error); | ||
1407 | } | ||
1408 | goto out_unlock; | ||
1408 | } | 1409 | } |
1409 | 1410 | k = error; | |
1410 | if (unlikely(k >= SG_MAX_DEVS)) | ||
1411 | goto overflow; | ||
1412 | 1411 | ||
1413 | SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); | 1412 | SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); |
1414 | sprintf(disk->disk_name, "sg%d", k); | 1413 | sprintf(disk->disk_name, "sg%d", k); |
@@ -1420,25 +1419,17 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1420 | sdp->sg_tablesize = queue_max_segments(q); | 1419 | sdp->sg_tablesize = queue_max_segments(q); |
1421 | sdp->index = k; | 1420 | sdp->index = k; |
1422 | kref_init(&sdp->d_ref); | 1421 | kref_init(&sdp->d_ref); |
1422 | error = 0; | ||
1423 | 1423 | ||
1424 | out_unlock: | ||
1424 | write_unlock_irqrestore(&sg_index_lock, iflags); | 1425 | write_unlock_irqrestore(&sg_index_lock, iflags); |
1426 | idr_preload_end(); | ||
1425 | 1427 | ||
1426 | error = 0; | ||
1427 | out: | ||
1428 | if (error) { | 1428 | if (error) { |
1429 | kfree(sdp); | 1429 | kfree(sdp); |
1430 | return ERR_PTR(error); | 1430 | return ERR_PTR(error); |
1431 | } | 1431 | } |
1432 | return sdp; | 1432 | return sdp; |
1433 | |||
1434 | overflow: | ||
1435 | idr_remove(&sg_index_idr, k); | ||
1436 | write_unlock_irqrestore(&sg_index_lock, iflags); | ||
1437 | sdev_printk(KERN_WARNING, scsidp, | ||
1438 | "Unable to attach sg device type=%d, minor " | ||
1439 | "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); | ||
1440 | error = -ENODEV; | ||
1441 | goto out; | ||
1442 | } | 1433 | } |
1443 | 1434 | ||
1444 | static int | 1435 | static int |