Commit 82bc9d04f4281276b8941b09a9306e15d4dc53f6
Committed by
Greg Kroah-Hartman
1 parent
e7b2033159
target: Drop arbitrary maximum I/O size limit
commit 046ba64285a4389ae5e9a7dfa253c6bff3d7c341 upstream. This patch drops the arbitrary maximum I/O size limit in sbc_parse_cdb(), which currently for fabric_max_sectors is hardcoded to 8192 (4 MB for 512 byte sector devices), and for hw_max_sectors is a backend driver dependent value. This limit is problematic because Linux initiators have only recently started to honor block limits MAXIMUM TRANSFER LENGTH, and other non-Linux based initiators (eg: MSFT Fibre Channel) can also generate I/Os larger than 4 MB in size. Currently when this happens, the following message will appear on the target resulting in I/Os being returned with non recoverable status: SCSI OP 28h with too big sectors 16384 exceeds fabric_max_sectors: 8192 Instead, drop both [fabric,hw]_max_sector checks in sbc_parse_cdb(), and convert the existing hw_max_sectors into a purely informational attribute used to represent the granuality that backend driver and/or subsystem code is splitting I/Os upon. Also, update FILEIO with an explicit FD_MAX_BYTES check in fd_execute_rw() to deal with the one special iovec limitiation case. v2 changes: - Drop hw_max_sectors check in sbc_parse_cdb() Reported-by: Lance Gropper <lance.gropper@qosserver.com> Reported-by: Stefan Priebe <s.priebe@profihost.ag> Cc: Christoph Hellwig <hch@lst.de> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 5 changed files with 16 additions and 25 deletions Side-by-side Diff
drivers/target/target_core_device.c
... | ... | @@ -1169,10 +1169,10 @@ |
1169 | 1169 | " changed for TCM/pSCSI\n", dev); |
1170 | 1170 | return -EINVAL; |
1171 | 1171 | } |
1172 | - if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { | |
1172 | + if (optimal_sectors > dev->dev_attrib.hw_max_sectors) { | |
1173 | 1173 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" |
1174 | - " greater than fabric_max_sectors: %u\n", dev, | |
1175 | - optimal_sectors, dev->dev_attrib.fabric_max_sectors); | |
1174 | + " greater than hw_max_sectors: %u\n", dev, | |
1175 | + optimal_sectors, dev->dev_attrib.hw_max_sectors); | |
1176 | 1176 | return -EINVAL; |
1177 | 1177 | } |
1178 | 1178 | |
... | ... | @@ -1572,7 +1572,6 @@ |
1572 | 1572 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; |
1573 | 1573 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; |
1574 | 1574 | dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; |
1575 | - dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; | |
1576 | 1575 | |
1577 | 1576 | xcopy_lun = &dev->xcopy_lun; |
1578 | 1577 | xcopy_lun->lun_se_dev = dev; |
... | ... | @@ -1613,6 +1612,7 @@ |
1613 | 1612 | dev->dev_attrib.hw_max_sectors = |
1614 | 1613 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, |
1615 | 1614 | dev->dev_attrib.hw_block_size); |
1615 | + dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; | |
1616 | 1616 | |
1617 | 1617 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); |
1618 | 1618 | dev->creation_time = get_jiffies_64(); |
drivers/target/target_core_file.c
... | ... | @@ -620,7 +620,16 @@ |
620 | 620 | struct fd_prot fd_prot; |
621 | 621 | sense_reason_t rc; |
622 | 622 | int ret = 0; |
623 | - | |
623 | + /* | |
624 | + * We are currently limited by the number of iovecs (2048) per | |
625 | + * single vfs_[writev,readv] call. | |
626 | + */ | |
627 | + if (cmd->data_length > FD_MAX_BYTES) { | |
628 | + pr_err("FILEIO: Not able to process I/O of %u bytes due to" | |
629 | + "FD_MAX_BYTES: %u iovec count limitiation\n", | |
630 | + cmd->data_length, FD_MAX_BYTES); | |
631 | + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | |
632 | + } | |
624 | 633 | /* |
625 | 634 | * Call vectorized fileio functions to map struct scatterlist |
626 | 635 | * physical memory addresses to struct iovec virtual memory. |
drivers/target/target_core_iblock.c
... | ... | @@ -123,7 +123,7 @@ |
123 | 123 | q = bdev_get_queue(bd); |
124 | 124 | |
125 | 125 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); |
126 | - dev->dev_attrib.hw_max_sectors = UINT_MAX; | |
126 | + dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); | |
127 | 127 | dev->dev_attrib.hw_queue_depth = q->nr_requests; |
128 | 128 | |
129 | 129 | /* |
drivers/target/target_core_sbc.c
... | ... | @@ -953,21 +953,6 @@ |
953 | 953 | |
954 | 954 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
955 | 955 | unsigned long long end_lba; |
956 | - | |
957 | - if (sectors > dev->dev_attrib.fabric_max_sectors) { | |
958 | - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | |
959 | - " big sectors %u exceeds fabric_max_sectors:" | |
960 | - " %u\n", cdb[0], sectors, | |
961 | - dev->dev_attrib.fabric_max_sectors); | |
962 | - return TCM_INVALID_CDB_FIELD; | |
963 | - } | |
964 | - if (sectors > dev->dev_attrib.hw_max_sectors) { | |
965 | - printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | |
966 | - " big sectors %u exceeds backend hw_max_sectors:" | |
967 | - " %u\n", cdb[0], sectors, | |
968 | - dev->dev_attrib.hw_max_sectors); | |
969 | - return TCM_INVALID_CDB_FIELD; | |
970 | - } | |
971 | 956 | check_lba: |
972 | 957 | end_lba = dev->transport->get_blocks(dev) + 1; |
973 | 958 | if (cmd->t_task_lba + sectors > end_lba) { |
drivers/target/target_core_spc.c
... | ... | @@ -505,7 +505,6 @@ |
505 | 505 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) |
506 | 506 | { |
507 | 507 | struct se_device *dev = cmd->se_dev; |
508 | - u32 max_sectors; | |
509 | 508 | int have_tp = 0; |
510 | 509 | int opt, min; |
511 | 510 | |
... | ... | @@ -539,9 +538,7 @@ |
539 | 538 | /* |
540 | 539 | * Set MAXIMUM TRANSFER LENGTH |
541 | 540 | */ |
542 | - max_sectors = min(dev->dev_attrib.fabric_max_sectors, | |
543 | - dev->dev_attrib.hw_max_sectors); | |
544 | - put_unaligned_be32(max_sectors, &buf[8]); | |
541 | + put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); | |
545 | 542 | |
546 | 543 | /* |
547 | 544 | * Set OPTIMAL TRANSFER LENGTH |