From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> This patch allows FILEIO to update hw_max_sectors based on the current block_size. This is required because vfs_[writev,readv]() can accept a maximum of 2048 iovecs per call, so the enforced hw_max_sectors really needs to be calculated based on block_size. This addresses a >= v3.5 bug where block_size=512 was rejecting > 1M sized I/O requests, because FD_MAX_SECTORS was hardcoded to 2048 for the block_size=4096 case. Reported-by: Henrik Goldman <hg@xxxxxxxxxxxxxxx> Cc: Henrik Goldman <hg@xxxxxxxxxxxxxxx> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> --- drivers/target/target_core_device.c | 4 ++++ drivers/target/target_core_file.c | 33 +++++++++++++++++++++++++++++---- drivers/target/target_core_file.h | 5 ++++- include/target/target_core_backend.h | 1 + 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 207b340..3d70ef6 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1106,6 +1106,10 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size) dev->dev_attrib.block_size = block_size; pr_debug("dev[%p]: SE Device block_size changed to %u\n", dev, block_size); + + if (dev->transport->update_hw_max_sectors) + dev->transport->update_hw_max_sectors(dev); + return 0; } diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 0e34cda..c1238ba 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -66,9 +66,8 @@ static int fd_attach_hba(struct se_hba *hba, u32 host_id) pr_debug("CORE_HBA[%d] - TCM FILEIO HBA Driver %s on Generic" " Target Core Stack %s\n", hba->hba_id, FD_VERSION, TARGET_CORE_MOD_VERSION); - pr_debug("CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic" - " MaxSectors: %u\n", - hba->hba_id, fd_host->fd_host_id, FD_MAX_SECTORS); + pr_debug("CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic\n", + hba->hba_id, fd_host->fd_host_id); return 0; } @@ -220,7 +219,7 @@ static int fd_configure_device(struct se_device *dev) } dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; - dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; + dev->transport->update_hw_max_sectors(dev); dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { @@ -708,6 +707,31 @@ static struct sbc_ops fd_sbc_ops = { .execute_unmap = fd_execute_unmap, }; +static void fd_update_hw_max_sectors(struct se_device *dev) +{ + u32 hw_max_sectors; + + switch (dev->dev_attrib.block_size) { + case 4096: + hw_max_sectors = FD_MAX_SECTORS_4K; + break; + case 2048: + hw_max_sectors = FD_MAX_SECTORS_2k; + break; + case 1024: + hw_max_sectors = FD_MAX_SECTORS_1K; + break; + case 512: + default: + hw_max_sectors = FD_MAX_SECTORS_512; + break; + } + + dev->dev_attrib.hw_max_sectors = hw_max_sectors; + pr_debug("FILEIO: Updated hw_max_sectors to %u\n", + dev->dev_attrib.hw_max_sectors); +} + static sense_reason_t fd_parse_cdb(struct se_cmd *cmd) { @@ -730,6 +754,7 @@ static struct se_subsystem_api fileio_template = { .show_configfs_dev_params = fd_show_configfs_dev_params, .get_device_type = sbc_get_device_type, .get_blocks = fd_get_blocks, + .update_hw_max_sectors = fd_update_hw_max_sectors, }; static int __init fileio_module_init(void) diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index 37ffc5b..e847430 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h @@ -7,7 +7,10 @@ #define FD_DEVICE_QUEUE_DEPTH 32 #define FD_MAX_DEVICE_QUEUE_DEPTH 128 #define FD_BLOCKSIZE 512 -#define FD_MAX_SECTORS 2048 +#define FD_MAX_SECTORS_4K 2048 +#define FD_MAX_SECTORS_2k 4096 +#define FD_MAX_SECTORS_1K 8192 +#define FD_MAX_SECTORS_512 16384 #define RRF_EMULATE_CDB 0x01 #define RRF_GOT_LBA 0x02 diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 39e0114..c68e46d 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -39,6 +39,7 @@ struct se_subsystem_api { unsigned int (*get_lbppbe)(struct se_device *); unsigned int (*get_io_min)(struct se_device *); unsigned int (*get_io_opt)(struct se_device *); + void (*update_hw_max_sectors)(struct se_device *); unsigned char *(*get_sense_buffer)(struct se_cmd *); bool (*get_write_cache)(struct se_device *); }; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html