diff options
author | Rob Evers <revers@redhat.com> | 2014-12-16 11:01:20 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-01-09 09:44:16 -0500 |
commit | acd6d73826224c20c44f505f56b0503f022d695c (patch) | |
tree | bb68748e8a5fe87ad511b543f92a08d6a21bebce /drivers/scsi | |
parent | 2a904e5dd9b832fe70d86b70ce6e273d67e94389 (diff) |
scsi: retry report-luns when reported LU count requres more memory
Update scsi_report_lun_scan to initially always report up to 511 LUs,
as the previous default max_report_luns did. Retry in a loop if not
enough memory is available for the number of LUs reported. Parameter
max_report_luns is removed as it is no longer used.
Signed-off-by: Rob Evers <revers@redhat.com>
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 41 |
1 files changed, 11 insertions, 30 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index b7948d20c23b..0deb385ad4d6 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -99,20 +99,6 @@ char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT; | |||
99 | module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO); | 99 | module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO); |
100 | MODULE_PARM_DESC(scan, "sync, async or none"); | 100 | MODULE_PARM_DESC(scan, "sync, async or none"); |
101 | 101 | ||
102 | /* | ||
103 | * max_scsi_report_luns: the maximum number of LUNS that will be | ||
104 | * returned from the REPORT LUNS command. 8 times this value must | ||
105 | * be allocated. In theory this could be up to an 8 byte value, but | ||
106 | * in practice, the maximum number of LUNs suppored by any device | ||
107 | * is about 16k. | ||
108 | */ | ||
109 | static unsigned int max_scsi_report_luns = 511; | ||
110 | |||
111 | module_param_named(max_report_luns, max_scsi_report_luns, uint, S_IRUGO|S_IWUSR); | ||
112 | MODULE_PARM_DESC(max_report_luns, | ||
113 | "REPORT LUNS maximum number of LUNS received (should be" | ||
114 | " between 1 and 16384)"); | ||
115 | |||
116 | static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18; | 102 | static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18; |
117 | 103 | ||
118 | module_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR); | 104 | module_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR); |
@@ -1407,15 +1393,11 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | |||
1407 | 1393 | ||
1408 | /* | 1394 | /* |
1409 | * Allocate enough to hold the header (the same size as one scsi_lun) | 1395 | * Allocate enough to hold the header (the same size as one scsi_lun) |
1410 | * plus the max number of luns we are requesting. | 1396 | * plus the number of luns we are requesting. 511 was the default |
1411 | * | 1397 | * value of the now removed max_report_luns parameter. |
1412 | * Reallocating and trying again (with the exact amount we need) | ||
1413 | * would be nice, but then we need to somehow limit the size | ||
1414 | * allocated based on the available memory and the limits of | ||
1415 | * kmalloc - we don't want a kmalloc() failure of a huge value to | ||
1416 | * prevent us from finding any LUNs on this target. | ||
1417 | */ | 1398 | */ |
1418 | length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun); | 1399 | length = (511 + 1) * sizeof(struct scsi_lun); |
1400 | retry: | ||
1419 | lun_data = kmalloc(length, GFP_KERNEL | | 1401 | lun_data = kmalloc(length, GFP_KERNEL | |
1420 | (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); | 1402 | (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); |
1421 | if (!lun_data) { | 1403 | if (!lun_data) { |
@@ -1481,17 +1463,16 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | |||
1481 | /* | 1463 | /* |
1482 | * Get the length from the first four bytes of lun_data. | 1464 | * Get the length from the first four bytes of lun_data. |
1483 | */ | 1465 | */ |
1466 | if (get_unaligned_be32(lun_data->scsi_lun) + | ||
1467 | sizeof(struct scsi_lun) > length) { | ||
1468 | length = get_unaligned_be32(lun_data->scsi_lun) + | ||
1469 | sizeof(struct scsi_lun); | ||
1470 | kfree(lun_data); | ||
1471 | goto retry; | ||
1472 | } | ||
1484 | length = get_unaligned_be32(lun_data->scsi_lun); | 1473 | length = get_unaligned_be32(lun_data->scsi_lun); |
1485 | 1474 | ||
1486 | num_luns = (length / sizeof(struct scsi_lun)); | 1475 | num_luns = (length / sizeof(struct scsi_lun)); |
1487 | if (num_luns > max_scsi_report_luns) { | ||
1488 | sdev_printk(KERN_WARNING, sdev, | ||
1489 | "Only %d (max_scsi_report_luns)" | ||
1490 | " of %d luns reported, try increasing" | ||
1491 | " max_scsi_report_luns.\n", | ||
1492 | max_scsi_report_luns, num_luns); | ||
1493 | num_luns = max_scsi_report_luns; | ||
1494 | } | ||
1495 | 1476 | ||
1496 | SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, | 1477 | SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, |
1497 | "scsi scan: REPORT LUN scan\n")); | 1478 | "scsi scan: REPORT LUN scan\n")); |