Commit 82bc9d04f4281276b8941b09a9306e15d4dc53f6

Authored by Nicholas Bellinger
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