aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_transport.c
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-08-13 02:11:38 -0700
committerNicholas Bellinger <nab@linux-iscsi.org>2011-08-22 19:26:27 +0000
commit525a48a21da259d00d6ebc5b60563b5bcf022c26 (patch)
tree79843b0aacbef9b130eec8f5352fe92b6422ab18 /drivers/target/target_core_transport.c
parenttarget: Add missing DATA_SG_IO transport_cmd_get_valid_sectors check (diff)
downloadlinux-dev-525a48a21da259d00d6ebc5b60563b5bcf022c26.tar.xz
linux-dev-525a48a21da259d00d6ebc5b60563b5bcf022c26.zip
target: Fix task count > 1 handling breakage and use max_sector page alignment
This patch addresses recent breakage with multiple se_task (task_count > 1) operation following backend dev->se_sub_dev->se_dev_attrib.max_sectors in new transport_allocate_data_tasks() code. The initial bug here was a bogus task->task_sg_nents assignment in transport_allocate_data_tasks() based on the passed parameter, which now uses DIV_ROUND_UP(task_size, PAGE_SIZE) to determine the proper number of per task SGL entries for the (task_count > 1) case. This also means we now need to enforce a PAGE_SIZE aligned max_sector count value for this to work as expected without bringing back the pre v3.1 transport_map_mem_to_sg() logic to handle SGL offsets across multiple tasks. So this patch adds se_dev_align_max_sectors() to round down max_sectors as necessary to ensure this alignment via se_dev_set_default_attribs() and se_dev_align_max_sectors() and keeps it simple for (task_count > 1) operation. So far this bugfix has been tested with (task_count > 1) operation using iscsi-target and iblock backends. Reported-by: Chris Boot <bootc@bootc.net> Cc: Kiran Patil <kiran.patil@intel.com> Cc: Andy Grover <agrover@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to '')
-rw-r--r--drivers/target/target_core_transport.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index ab61c5550852..efac6a9a7438 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -4126,7 +4126,11 @@ static int transport_allocate_data_tasks(
/* Update new cdb with updated lba/sectors */
cmd->transport_split_cdb(task->task_lba, task->task_sectors, cdb);
-
+ /*
+ * This now assumes that passed sg_ents are in PAGE_SIZE chunks
+ * in order to calculate the number per task SGL entries
+ */
+ task->task_sg_nents = DIV_ROUND_UP(task->task_size, PAGE_SIZE);
/*
* Check if the fabric module driver is requesting that all
* struct se_task->task_sg[] be chained together.. If so,
@@ -4136,7 +4140,6 @@ static int transport_allocate_data_tasks(
* It's so much easier and only a waste when task_count > 1.
* That is extremely rare.
*/
- task->task_sg_nents = sgl_nents;
if (cmd->se_tfo->task_sg_chaining) {
task->task_sg_nents++;
task->task_padded_sg = 1;