aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c43
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
1424out_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
1444static int 1435static int