From: Greg Kroah-Hartman Date: Tue, 31 Dec 2013 06:00:21 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.76~63 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53391b30c58839f881db8e255b0a875b10a62563;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: aio-fix-kioctx-leak-introduced-by-aio-fix-a-trinity-splat.patch iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch iscsi-target-fix-up-all-zero-data-length-cdbs-with-r-w_bit-set.patch iser-target-fix-error-return-code-in-isert_create_device_ib_res.patch iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch qla2xxx-fix-schedule_delayed_work-for-target-timeout-calculations.patch selinux-fix-broken-peer-recv-check.patch selinux-selinux_setprocattr-ptrace_parent-needs-rcu_read_lock.patch target-file-update-hw_max_sectors-based-on-current-block_size.patch --- diff --git a/queue-3.12/aio-fix-kioctx-leak-introduced-by-aio-fix-a-trinity-splat.patch b/queue-3.12/aio-fix-kioctx-leak-introduced-by-aio-fix-a-trinity-splat.patch new file mode 100644 index 00000000000..f7b6dcd61f8 --- /dev/null +++ b/queue-3.12/aio-fix-kioctx-leak-introduced-by-aio-fix-a-trinity-splat.patch @@ -0,0 +1,33 @@ +From 1881686f842065d2f92ec9c6424830ffc17d23b0 Mon Sep 17 00:00:00 2001 +From: Benjamin LaHaise +Date: Sat, 21 Dec 2013 15:49:28 -0500 +Subject: aio: fix kioctx leak introduced by "aio: Fix a trinity splat" + +From: Benjamin LaHaise + +commit 1881686f842065d2f92ec9c6424830ffc17d23b0 upstream. + +e34ecee2ae791df674dfb466ce40692ca6218e43 reworked the percpu reference +counting to correct a bug trinity found. Unfortunately, the change lead +to kioctxes being leaked because there was no final reference count to +put. Add that reference count back in to fix things. + +Signed-off-by: Benjamin LaHaise +Signed-off-by: Greg Kroah-Hartman + +--- + fs/aio.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -652,7 +652,8 @@ static struct kioctx *ioctx_alloc(unsign + aio_nr += ctx->max_reqs; + spin_unlock(&aio_nr_lock); + +- percpu_ref_get(&ctx->users); /* io_setup() will drop this ref */ ++ percpu_ref_get(&ctx->users); /* io_setup() will drop this ref */ ++ percpu_ref_get(&ctx->reqs); /* free_ioctx_users() will drop this */ + + err = ioctx_add_table(ctx, mm); + if (err) diff --git a/queue-3.12/iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch b/queue-3.12/iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch new file mode 100644 index 00000000000..8b185889c2b --- /dev/null +++ b/queue-3.12/iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch @@ -0,0 +1,61 @@ +From db6077fd0b7dd41dc6ff18329cec979379071f87 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 11 Dec 2013 15:45:32 -0800 +Subject: iscsi-target: Fix incorrect np->np_thread NULL assignment + +From: Nicholas Bellinger + +commit db6077fd0b7dd41dc6ff18329cec979379071f87 upstream. + +When shutting down a target there is a race condition between +iscsit_del_np() and __iscsi_target_login_thread(). +The latter sets the thread pointer to NULL, and the former +tries to issue kthread_stop() on that pointer without any +synchronization. + +This patch moves the np->np_thread NULL assignment into +iscsit_del_np(), after kthread_stop() has completed. It also +removes the signal_pending() + np_state check, and only +exits when kthread_should_stop() is true. + +Reported-by: Hannes Reinecke +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 1 + + drivers/target/iscsi/iscsi_target_login.c | 6 ------ + 2 files changed, 1 insertion(+), 6 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -465,6 +465,7 @@ int iscsit_del_np(struct iscsi_np *np) + */ + send_sig(SIGINT, np->np_thread, 1); + kthread_stop(np->np_thread); ++ np->np_thread = NULL; + } + + np->np_transport->iscsit_free_np(np); +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -1404,11 +1404,6 @@ old_sess_out: + + out: + stop = kthread_should_stop(); +- if (!stop && signal_pending(current)) { +- spin_lock_bh(&np->np_thread_lock); +- stop = (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN); +- spin_unlock_bh(&np->np_thread_lock); +- } + /* Wait for another socket.. */ + if (!stop) + return 1; +@@ -1416,7 +1411,6 @@ exit: + iscsi_stop_login_thread_timer(np); + spin_lock_bh(&np->np_thread_lock); + np->np_thread_state = ISCSI_NP_THREAD_EXIT; +- np->np_thread = NULL; + spin_unlock_bh(&np->np_thread_lock); + + return 0; diff --git a/queue-3.12/iscsi-target-fix-up-all-zero-data-length-cdbs-with-r-w_bit-set.patch b/queue-3.12/iscsi-target-fix-up-all-zero-data-length-cdbs-with-r-w_bit-set.patch new file mode 100644 index 00000000000..17f883699be --- /dev/null +++ b/queue-3.12/iscsi-target-fix-up-all-zero-data-length-cdbs-with-r-w_bit-set.patch @@ -0,0 +1,70 @@ +From 4454b66cb67f14c33cd70ddcf0ff4985b26324b7 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 25 Nov 2013 14:53:57 -0800 +Subject: iscsi-target: Fix-up all zero data-length CDBs with R/W_BIT set + +From: Nicholas Bellinger + +commit 4454b66cb67f14c33cd70ddcf0ff4985b26324b7 upstream. + +This patch changes special case handling for ISCSI_OP_SCSI_CMD +where an initiator sends a zero length Expected Data Transfer +Length (EDTL), but still sets the WRITE and/or READ flag bits +when no payload transfer is requested. + +Many, many moons ago two special cases where added for an ancient +version of ESX that has long since been fixed, so instead of adding +a new special case for the reported bug with a Broadcom 57800 NIC, +go ahead and always strip off the incorrect WRITE + READ flag bits. + +Also, avoid sending a reject here, as RFC-3720 does mandate this +case be handled without protocol error. + +Reported-by: Witold Bazakbal <865perl@wp.pl> +Tested-by: Witold Bazakbal <865perl@wp.pl> +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -830,24 +830,22 @@ int iscsit_setup_scsi_cmd(struct iscsi_c + if (((hdr->flags & ISCSI_FLAG_CMD_READ) || + (hdr->flags & ISCSI_FLAG_CMD_WRITE)) && !hdr->data_length) { + /* +- * Vmware ESX v3.0 uses a modified Cisco Initiator (v3.4.2) +- * that adds support for RESERVE/RELEASE. There is a bug +- * add with this new functionality that sets R/W bits when +- * neither CDB carries any READ or WRITE datapayloads. ++ * From RFC-3720 Section 10.3.1: ++ * ++ * "Either or both of R and W MAY be 1 when either the ++ * Expected Data Transfer Length and/or Bidirectional Read ++ * Expected Data Transfer Length are 0" ++ * ++ * For this case, go ahead and clear the unnecssary bits ++ * to avoid any confusion with ->data_direction. + */ +- if ((hdr->cdb[0] == 0x16) || (hdr->cdb[0] == 0x17)) { +- hdr->flags &= ~ISCSI_FLAG_CMD_READ; +- hdr->flags &= ~ISCSI_FLAG_CMD_WRITE; +- goto done; +- } ++ hdr->flags &= ~ISCSI_FLAG_CMD_READ; ++ hdr->flags &= ~ISCSI_FLAG_CMD_WRITE; + +- pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" ++ pr_warn("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" + " set when Expected Data Transfer Length is 0 for" +- " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); +- return iscsit_add_reject_cmd(cmd, +- ISCSI_REASON_BOOKMARK_INVALID, buf); ++ " CDB: 0x%02x, Fixing up flags\n", hdr->cdb[0]); + } +-done: + + if (!(hdr->flags & ISCSI_FLAG_CMD_READ) && + !(hdr->flags & ISCSI_FLAG_CMD_WRITE) && (hdr->data_length != 0)) { diff --git a/queue-3.12/iser-target-fix-error-return-code-in-isert_create_device_ib_res.patch b/queue-3.12/iser-target-fix-error-return-code-in-isert_create_device_ib_res.patch new file mode 100644 index 00000000000..6dd18a0d53d --- /dev/null +++ b/queue-3.12/iser-target-fix-error-return-code-in-isert_create_device_ib_res.patch @@ -0,0 +1,56 @@ +From 94a7111043d99819cd0a72d9b3174c7054adb2a0 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Tue, 29 Oct 2013 09:56:34 +0800 +Subject: iser-target: fix error return code in isert_create_device_ib_res() + +From: Wei Yongjun + +commit 94a7111043d99819cd0a72d9b3174c7054adb2a0 upstream. + +Fix to return a negative error code from the error handling +case instead of 0, as done elsewhere in this function. + +Signed-off-by: Wei Yongjun +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -263,21 +263,29 @@ isert_create_device_ib_res(struct isert_ + isert_cq_event_callback, + (void *)&cq_desc[i], + ISER_MAX_RX_CQ_LEN, i); +- if (IS_ERR(device->dev_rx_cq[i])) ++ if (IS_ERR(device->dev_rx_cq[i])) { ++ ret = PTR_ERR(device->dev_rx_cq[i]); ++ device->dev_rx_cq[i] = NULL; + goto out_cq; ++ } + + device->dev_tx_cq[i] = ib_create_cq(device->ib_device, + isert_cq_tx_callback, + isert_cq_event_callback, + (void *)&cq_desc[i], + ISER_MAX_TX_CQ_LEN, i); +- if (IS_ERR(device->dev_tx_cq[i])) ++ if (IS_ERR(device->dev_tx_cq[i])) { ++ ret = PTR_ERR(device->dev_tx_cq[i]); ++ device->dev_tx_cq[i] = NULL; + goto out_cq; ++ } + +- if (ib_req_notify_cq(device->dev_rx_cq[i], IB_CQ_NEXT_COMP)) ++ ret = ib_req_notify_cq(device->dev_rx_cq[i], IB_CQ_NEXT_COMP); ++ if (ret) + goto out_cq; + +- if (ib_req_notify_cq(device->dev_tx_cq[i], IB_CQ_NEXT_COMP)) ++ ret = ib_req_notify_cq(device->dev_tx_cq[i], IB_CQ_NEXT_COMP); ++ if (ret) + goto out_cq; + } + diff --git a/queue-3.12/iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch b/queue-3.12/iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch new file mode 100644 index 00000000000..8835834f224 --- /dev/null +++ b/queue-3.12/iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch @@ -0,0 +1,69 @@ +From 2853c2b6671509591be09213954d7249ca6ff224 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Wed, 11 Dec 2013 16:20:13 -0800 +Subject: iser-target: Move INIT_WORK setup into isert_create_device_ib_res + +From: Nicholas Bellinger + +commit 2853c2b6671509591be09213954d7249ca6ff224 upstream. + +This patch moves INIT_WORK setup for cq_desc->cq_[rx,tx]_work into +isert_create_device_ib_res(), instead of being done each callback +invocation in isert_cq_[rx,tx]_callback(). + +This also fixes a 'INFO: trying to register non-static key' warning +when cancel_work_sync() is called before INIT_WORK has setup the +struct work_struct. + +Reported-by: Or Gerlitz +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/isert/ib_isert.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -206,7 +206,9 @@ isert_free_rx_descriptors(struct isert_c + isert_conn->conn_rx_descs = NULL; + } + ++static void isert_cq_tx_work(struct work_struct *); + static void isert_cq_tx_callback(struct ib_cq *, void *); ++static void isert_cq_rx_work(struct work_struct *); + static void isert_cq_rx_callback(struct ib_cq *, void *); + + static int +@@ -258,6 +260,7 @@ isert_create_device_ib_res(struct isert_ + cq_desc[i].device = device; + cq_desc[i].cq_index = i; + ++ INIT_WORK(&cq_desc[i].cq_rx_work, isert_cq_rx_work); + device->dev_rx_cq[i] = ib_create_cq(device->ib_device, + isert_cq_rx_callback, + isert_cq_event_callback, +@@ -269,6 +272,7 @@ isert_create_device_ib_res(struct isert_ + goto out_cq; + } + ++ INIT_WORK(&cq_desc[i].cq_tx_work, isert_cq_tx_work); + device->dev_tx_cq[i] = ib_create_cq(device->ib_device, + isert_cq_tx_callback, + isert_cq_event_callback, +@@ -1694,7 +1698,6 @@ isert_cq_tx_callback(struct ib_cq *cq, v + { + struct isert_cq_desc *cq_desc = (struct isert_cq_desc *)context; + +- INIT_WORK(&cq_desc->cq_tx_work, isert_cq_tx_work); + queue_work(isert_comp_wq, &cq_desc->cq_tx_work); + } + +@@ -1738,7 +1741,6 @@ isert_cq_rx_callback(struct ib_cq *cq, v + { + struct isert_cq_desc *cq_desc = (struct isert_cq_desc *)context; + +- INIT_WORK(&cq_desc->cq_rx_work, isert_cq_rx_work); + queue_work(isert_rx_wq, &cq_desc->cq_rx_work); + } + diff --git a/queue-3.12/qla2xxx-fix-schedule_delayed_work-for-target-timeout-calculations.patch b/queue-3.12/qla2xxx-fix-schedule_delayed_work-for-target-timeout-calculations.patch new file mode 100644 index 00000000000..7be1ea2fbb5 --- /dev/null +++ b/queue-3.12/qla2xxx-fix-schedule_delayed_work-for-target-timeout-calculations.patch @@ -0,0 +1,58 @@ +From 63832aabec12a28a41a221773ab3819d30ba0a67 Mon Sep 17 00:00:00 2001 +From: Shivaram Upadhyayula +Date: Tue, 10 Dec 2013 16:06:40 +0530 +Subject: qla2xxx: Fix schedule_delayed_work() for target timeout calculations + +From: Shivaram Upadhyayula + +commit 63832aabec12a28a41a221773ab3819d30ba0a67 upstream. + +This patch fixes two cases in qla_target.c code where the +schedule_delayed_work() value was being incorrectly calculated +from sess->expires - jiffies. + +Signed-off-by: Shivaram U +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_target.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -471,7 +471,7 @@ static void qlt_schedule_sess_for_deleti + schedule_delayed_work(&tgt->sess_del_work, 0); + else + schedule_delayed_work(&tgt->sess_del_work, +- jiffies - sess->expires); ++ sess->expires - jiffies); + } + + /* ha->hardware_lock supposed to be held on entry */ +@@ -550,13 +550,14 @@ static void qlt_del_sess_work_fn(struct + struct scsi_qla_host *vha = tgt->vha; + struct qla_hw_data *ha = vha->hw; + struct qla_tgt_sess *sess; +- unsigned long flags; ++ unsigned long flags, elapsed; + + spin_lock_irqsave(&ha->hardware_lock, flags); + while (!list_empty(&tgt->del_sess_list)) { + sess = list_entry(tgt->del_sess_list.next, typeof(*sess), + del_list_entry); +- if (time_after_eq(jiffies, sess->expires)) { ++ elapsed = jiffies; ++ if (time_after_eq(elapsed, sess->expires)) { + qlt_undelete_sess(sess); + + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, +@@ -566,7 +567,7 @@ static void qlt_del_sess_work_fn(struct + ha->tgt.tgt_ops->put_sess(sess); + } else { + schedule_delayed_work(&tgt->sess_del_work, +- jiffies - sess->expires); ++ sess->expires - elapsed); + break; + } + } diff --git a/queue-3.12/selinux-fix-broken-peer-recv-check.patch b/queue-3.12/selinux-fix-broken-peer-recv-check.patch new file mode 100644 index 00000000000..1bf87420928 --- /dev/null +++ b/queue-3.12/selinux-fix-broken-peer-recv-check.patch @@ -0,0 +1,35 @@ +From 46d01d63221c3508421dd72ff9c879f61053cffc Mon Sep 17 00:00:00 2001 +From: Chad Hanson +Date: Mon, 23 Dec 2013 17:45:01 -0500 +Subject: selinux: fix broken peer recv check + +From: Chad Hanson + +commit 46d01d63221c3508421dd72ff9c879f61053cffc upstream. + +Fix a broken networking check. Return an error if peer recv fails. If +secmark is active and the packet recv succeeds the peer recv error is +ignored. + +Signed-off-by: Chad Hanson +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/hooks.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -4297,8 +4297,10 @@ static int selinux_socket_sock_rcv_skb(s + } + err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, + PEER__RECV, &ad); +- if (err) ++ if (err) { + selinux_netlbl_err(skb, err, 0); ++ return err; ++ } + } + + if (secmark_active) { diff --git a/queue-3.12/selinux-selinux_setprocattr-ptrace_parent-needs-rcu_read_lock.patch b/queue-3.12/selinux-selinux_setprocattr-ptrace_parent-needs-rcu_read_lock.patch new file mode 100644 index 00000000000..5f0096ae092 --- /dev/null +++ b/queue-3.12/selinux-selinux_setprocattr-ptrace_parent-needs-rcu_read_lock.patch @@ -0,0 +1,43 @@ +From c0c1439541f5305b57a83d599af32b74182933fe Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 23 Dec 2013 17:45:01 -0500 +Subject: selinux: selinux_setprocattr()->ptrace_parent() needs rcu_read_lock() + +From: Oleg Nesterov + +commit c0c1439541f5305b57a83d599af32b74182933fe upstream. + +selinux_setprocattr() does ptrace_parent(p) under task_lock(p), +but task_struct->alloc_lock doesn't pin ->parent or ->ptrace, +this looks confusing and triggers the "suspicious RCU usage" +warning because ptrace_parent() does rcu_dereference_check(). + +And in theory this is wrong, spin_lock()->preempt_disable() +doesn't necessarily imply rcu_read_lock() we need to access +the ->parent. + +Reported-by: Evan McNabb +Signed-off-by: Oleg Nesterov +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/hooks.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -5523,11 +5523,11 @@ static int selinux_setprocattr(struct ta + /* Check for ptracing, and update the task SID if ok. + Otherwise, leave SID unchanged and fail. */ + ptsid = 0; +- task_lock(p); ++ rcu_read_lock(); + tracer = ptrace_parent(p); + if (tracer) + ptsid = task_sid(tracer); +- task_unlock(p); ++ rcu_read_unlock(); + + if (tracer) { + error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, diff --git a/queue-3.12/series b/queue-3.12/series index 71f281a4f0a..82556f72e39 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -28,3 +28,12 @@ usb-chipidea-host-only-disable-the-vbus-regulator-if-it-is-not-null.patch usb-chipidea-fix-nobody-cared-irq-when-booting-with-host-role.patch usb-musb-core-call-dma_controller_destroy-in-error-path-only-once.patch usb-musb-only-cancel-work-if-it-is-initialized.patch +selinux-fix-broken-peer-recv-check.patch +selinux-selinux_setprocattr-ptrace_parent-needs-rcu_read_lock.patch +aio-fix-kioctx-leak-introduced-by-aio-fix-a-trinity-splat.patch +qla2xxx-fix-schedule_delayed_work-for-target-timeout-calculations.patch +iser-target-fix-error-return-code-in-isert_create_device_ib_res.patch +iscsi-target-fix-up-all-zero-data-length-cdbs-with-r-w_bit-set.patch +iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch +iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch +target-file-update-hw_max_sectors-based-on-current-block_size.patch diff --git a/queue-3.12/target-file-update-hw_max_sectors-based-on-current-block_size.patch b/queue-3.12/target-file-update-hw_max_sectors-based-on-current-block_size.patch new file mode 100644 index 00000000000..d3d1a339aad --- /dev/null +++ b/queue-3.12/target-file-update-hw_max_sectors-based-on-current-block_size.patch @@ -0,0 +1,93 @@ +From 95cadace8f3959282e76ebf8b382bd0930807d2c Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 12 Dec 2013 12:24:11 -0800 +Subject: target/file: Update hw_max_sectors based on current block_size + +From: Nicholas Bellinger + +commit 95cadace8f3959282e76ebf8b382bd0930807d2c upstream. + +This patch allows FILEIO to update hw_max_sectors based on the current +max_bytes_per_io. 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. + +(v2: Use max_bytes_per_io instead of ->update_hw_max_sectors) + +Reported-by: Henrik Goldman +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 5 +++++ + drivers/target/target_core_file.c | 8 ++++---- + drivers/target/target_core_file.h | 5 ++++- + include/target/target_core_base.h | 1 + + 4 files changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -1107,6 +1107,11 @@ int se_dev_set_block_size(struct se_devi + dev->dev_attrib.block_size = block_size; + pr_debug("dev[%p]: SE Device block_size changed to %u\n", + dev, block_size); ++ ++ if (dev->dev_attrib.max_bytes_per_io) ++ dev->dev_attrib.hw_max_sectors = ++ dev->dev_attrib.max_bytes_per_io / block_size; ++ + return 0; + } + +--- 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 * + 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,8 @@ static int fd_configure_device(struct se + } + + dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; +- dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; ++ dev->dev_attrib.max_bytes_per_io = FD_MAX_BYTES; ++ dev->dev_attrib.hw_max_sectors = FD_MAX_BYTES / fd_dev->fd_block_size; + dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; + + if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { +--- 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 ++/* ++ * Limited by the number of iovecs (2048) per vfs_[writev,readv] call ++ */ ++#define FD_MAX_BYTES 8388608 + + #define RRF_EMULATE_CDB 0x01 + #define RRF_GOT_LBA 0x02 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -624,6 +624,7 @@ struct se_dev_attrib { + u32 unmap_granularity; + u32 unmap_granularity_alignment; + u32 max_write_same_len; ++ u32 max_bytes_per_io; + struct se_device *da_dev; + struct config_group da_group; + };