--- /dev/null
+From 79d59d08082dd0a0a18f8ceb78c99f9f321d72aa Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Thu, 29 May 2014 13:32:30 -0700
+Subject: iscsi-target: Fix wrong buffer / buffer overrun in iscsi_change_param_value()
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 79d59d08082dd0a0a18f8ceb78c99f9f321d72aa upstream.
+
+In non-leading connection login, iscsi_login_non_zero_tsih_s1() calls
+iscsi_change_param_value() with the buffer it uses to hold the login
+PDU, not a temporary buffer. This leads to the login header getting
+corrupted and login failing for non-leading connections in MC/S.
+
+Fix this by adding a wrapper iscsi_change_param_sprintf() that handles
+the temporary buffer itself to avoid confusion. Also handle sending a
+reject in case of failure in the wrapper, which lets the calling code
+get quite a bit smaller and easier to read.
+
+Finally, bump the size of the temporary buffer from 32 to 64 bytes to be
+safe, since "MaxRecvDataSegmentLength=" by itself is 25 bytes; with a
+trailing NUL, a value >= 1M will lead to a buffer overrun. (This isn't
+the default but we don't need to run right at the ragged edge here)
+
+(Fix up context changes for v3.10.y - nab)
+
+Reported-by: Santosh Kulkarni <santosh.kulkarni@calsoftinc.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/iscsi/iscsi_target_login.c | 50 ++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 23 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -250,6 +250,28 @@ static void iscsi_login_set_conn_values(
+ mutex_unlock(&auth_id_lock);
+ }
+
++static __printf(2, 3) int iscsi_change_param_sprintf(
++ struct iscsi_conn *conn,
++ const char *fmt, ...)
++{
++ va_list args;
++ unsigned char buf[64];
++
++ memset(buf, 0, sizeof buf);
++
++ va_start(args, fmt);
++ vsnprintf(buf, sizeof buf, fmt, args);
++ va_end(args);
++
++ if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
++ ISCSI_LOGIN_STATUS_NO_RESOURCES);
++ return -1;
++ }
++
++ return 0;
++}
++
+ /*
+ * This is the leading connection of a new session,
+ * or session reinstatement.
+@@ -339,7 +361,6 @@ static int iscsi_login_zero_tsih_s2(
+ {
+ struct iscsi_node_attrib *na;
+ struct iscsi_session *sess = conn->sess;
+- unsigned char buf[32];
+ bool iser = false;
+
+ sess->tpg = conn->tpg;
+@@ -380,26 +401,16 @@ static int iscsi_login_zero_tsih_s2(
+ *
+ * In our case, we have already located the struct iscsi_tiqn at this point.
+ */
+- memset(buf, 0, 32);
+- sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
+- if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+- iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+- ISCSI_LOGIN_STATUS_NO_RESOURCES);
++ if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt))
+ return -1;
+- }
+
+ /*
+ * Workaround for Initiators that have broken connection recovery logic.
+ *
+ * "We would really like to get rid of this." Linux-iSCSI.org team
+ */
+- memset(buf, 0, 32);
+- sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
+- if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+- iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+- ISCSI_LOGIN_STATUS_NO_RESOURCES);
++ if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", na->default_erl))
+ return -1;
+- }
+
+ if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
+ return -1;
+@@ -411,12 +422,9 @@ static int iscsi_login_zero_tsih_s2(
+ unsigned long mrdsl, off;
+ int rc;
+
+- sprintf(buf, "RDMAExtensions=Yes");
+- if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+- iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+- ISCSI_LOGIN_STATUS_NO_RESOURCES);
++ if (iscsi_change_param_sprintf(conn, "RDMAExtensions=Yes"))
+ return -1;
+- }
++
+ /*
+ * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
+ * Immediate Data + Unsolicitied Data-OUT if necessary..
+@@ -446,12 +454,8 @@ static int iscsi_login_zero_tsih_s2(
+ pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down"
+ " to PAGE_SIZE\n", mrdsl);
+
+- sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl);
+- if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
+- iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+- ISCSI_LOGIN_STATUS_NO_RESOURCES);
++ if (iscsi_change_param_sprintf(conn, "MaxRecvDataSegmentLength=%lu\n", mrdsl))
+ return -1;
+- }
+ }
+
+ return 0;
--- /dev/null
+From 2363d196686e44c0158929e7cf96c8589a24a81b Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Tue, 3 Jun 2014 18:27:52 -0700
+Subject: iser-target: Fix multi network portal shutdown regression
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 2363d196686e44c0158929e7cf96c8589a24a81b upstream.
+
+This patch fixes a iser-target specific regression introduced in
+v3.15-rc6 with:
+
+commit 14f4b54fe38f3a8f8392a50b951c8aa43b63687a
+Author: Sagi Grimberg <sagig@mellanox.com>
+Date: Tue Apr 29 13:13:47 2014 +0300
+
+ Target/iscsi,iser: Avoid accepting transport connections during stop stage
+
+where the change to set iscsi_np->enabled = false within
+iscsit_clear_tpg_np_login_thread() meant that a iscsi_np with
+two iscsi_tpg_np exports would have it's parent iscsi_np set
+to a disabled state, even if other iscsi_tpg_np exports still
+existed.
+
+This patch changes iscsit_clear_tpg_np_login_thread() to only
+set iscsi_np->enabled = false when shutdown = true, and also
+changes iscsit_del_np() to set iscsi_np->enabled = true when
+iscsi_np->np_exports is non zero.
+
+(Fix up context changes for v3.10.y - nab)
+
+Cc: Sagi Grimberg <sagig@dev.mellanox.co.il>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/iscsi/iscsi_target.c | 1 +
+ drivers/target/iscsi/iscsi_target_tpg.c | 10 ++++++----
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -460,6 +460,7 @@ int iscsit_del_np(struct iscsi_np *np)
+ spin_lock_bh(&np->np_thread_lock);
+ np->np_exports--;
+ if (np->np_exports) {
++ np->enabled = true;
+ spin_unlock_bh(&np->np_thread_lock);
+ return 0;
+ }
+--- a/drivers/target/iscsi/iscsi_target_tpg.c
++++ b/drivers/target/iscsi/iscsi_target_tpg.c
+@@ -175,14 +175,16 @@ void iscsit_put_tpg(struct iscsi_portal_
+
+ static void iscsit_clear_tpg_np_login_thread(
+ struct iscsi_tpg_np *tpg_np,
+- struct iscsi_portal_group *tpg)
++ struct iscsi_portal_group *tpg,
++ bool shutdown)
+ {
+ if (!tpg_np->tpg_np) {
+ pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
+ return;
+ }
+
+- tpg_np->tpg_np->enabled = false;
++ if (shutdown)
++ tpg_np->tpg_np->enabled = false;
+ iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg);
+ }
+
+@@ -198,7 +200,7 @@ void iscsit_clear_tpg_np_login_threads(
+ continue;
+ }
+ spin_unlock(&tpg->tpg_np_lock);
+- iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
++ iscsit_clear_tpg_np_login_thread(tpg_np, tpg, false);
+ spin_lock(&tpg->tpg_np_lock);
+ }
+ spin_unlock(&tpg->tpg_np_lock);
+@@ -521,7 +523,7 @@ static int iscsit_tpg_release_np(
+ struct iscsi_portal_group *tpg,
+ struct iscsi_np *np)
+ {
+- iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
++ iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
+
+ pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
+ tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
arm-mvebu-fix-nor-bus-width-in-armada-xp-gp-device-tree.patch
arm-mvebu-fix-nor-bus-width-in-armada-xp-openblocks-ax3-device-tree.patch
netfilter-ipv4-defrag-set-local_df-flag-on-defragmented-skb.patch
+target-iscsi-iser-avoid-accepting-transport-connections-during-stop-stage.patch
+iser-target-fix-multi-network-portal-shutdown-regression.patch
+iscsi-target-fix-wrong-buffer-buffer-overrun-in-iscsi_change_param_value.patch
+target-allow-read_capacity-opcode-in-alua-standby-access-state.patch
+target-fix-alua_access_state-attribute-oops-for-un-configured-devices.patch
--- /dev/null
+From e7810c2d2c37fa8e58dda74b00790dab60fe6fba Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Thu, 5 Jun 2014 23:37:00 -0700
+Subject: target: Allow READ_CAPACITY opcode in ALUA Standby access state
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit e7810c2d2c37fa8e58dda74b00790dab60fe6fba upstream.
+
+This patch allows READ_CAPACITY + SAI_READ_CAPACITY_16 opcode
+processing to occur while the associated ALUA group is in Standby
+access state.
+
+This is required to avoid host side LUN probe failures during the
+initial scan if an ALUA group has already implicitly changed into
+Standby access state.
+
+This addresses a bug reported by Chris + Philip using dm-multipath
++ ESX hosts configured with ALUA multipath.
+
+(Drop v3.15 specific set_ascq usage - nab)
+
+Reported-by: Chris Boot <crb@tiger-computing.co.uk>
+Reported-by: Philip Gaw <pgaw@darktech.org.uk>
+Cc: Chris Boot <crb@tiger-computing.co.uk>
+Cc: Philip Gaw <pgaw@darktech.org.uk>
+Cc: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_alua.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/target/target_core_alua.c
++++ b/drivers/target/target_core_alua.c
+@@ -409,7 +409,16 @@ static inline int core_alua_state_standb
+ case REPORT_LUNS:
+ case RECEIVE_DIAGNOSTIC:
+ case SEND_DIAGNOSTIC:
++ case READ_CAPACITY:
+ return 0;
++ case SERVICE_ACTION_IN:
++ switch (cdb[1] & 0x1f) {
++ case SAI_READ_CAPACITY_16:
++ return 0;
++ default:
++ *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
++ return 1;
++ }
+ case MAINTENANCE_IN:
+ switch (cdb[1] & 0x1f) {
+ case MI_REPORT_TARGET_PGS:
--- /dev/null
+From f1453773514bb8b0bba0716301e8c8f17f8d39c7 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 6 Jun 2014 00:52:57 -0700
+Subject: target: Fix alua_access_state attribute OOPs for un-configured devices
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit f1453773514bb8b0bba0716301e8c8f17f8d39c7 upstream.
+
+This patch fixes a OOPs where an attempt to write to the per-device
+alua_access_state configfs attribute at:
+
+ /sys/kernel/config/target/core/$HBA/$DEV/alua/$TG_PT_GP/alua_access_state
+
+results in an NULL pointer dereference when the backend device has not
+yet been configured.
+
+This patch adds an explicit check for DF_CONFIGURED, and fails with
+-ENODEV to avoid this case.
+
+Reported-by: Chris Boot <crb@tiger-computing.co.uk>
+Reported-by: Philip Gaw <pgaw@darktech.org.uk>
+Cc: Chris Boot <crb@tiger-computing.co.uk>
+Cc: Philip Gaw <pgaw@darktech.org.uk>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/target_core_configfs.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/target/target_core_configfs.c
++++ b/drivers/target/target_core_configfs.c
+@@ -2034,6 +2034,11 @@ static ssize_t target_core_alua_tg_pt_gp
+ " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id);
+ return -EINVAL;
+ }
++ if (!(dev->dev_flags & DF_CONFIGURED)) {
++ pr_err("Unable to set alua_access_state while device is"
++ " not configured\n");
++ return -ENODEV;
++ }
+
+ ret = strict_strtoul(page, 0, &tmp);
+ if (ret < 0) {
--- /dev/null
+From 14f4b54fe38f3a8f8392a50b951c8aa43b63687a Mon Sep 17 00:00:00 2001
+From: Sagi Grimberg <sagig@mellanox.com>
+Date: Tue, 29 Apr 2014 13:13:47 +0300
+Subject: Target/iscsi,iser: Avoid accepting transport connections during stop stage
+
+From: Sagi Grimberg <sagig@mellanox.com>
+
+commit 14f4b54fe38f3a8f8392a50b951c8aa43b63687a upstream.
+
+When the target is in stop stage, iSER transport initiates RDMA disconnects.
+The iSER initiator may wish to establish a new connection over the
+still existing network portal. In this case iSER transport should not
+accept and resume new RDMA connections. In order to learn that, iscsi_np
+is added with enabled flag so the iSER transport can check when deciding
+weather to accept and resume a new connection request.
+
+The iscsi_np is enabled after successful transport setup, and disabled
+before iscsi_np login threads are cleaned up.
+
+(Fix up context changes for v3.10.y - nab)
+
+Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/ulp/isert/ib_isert.c | 8 ++++++++
+ drivers/target/iscsi/iscsi_target_core.h | 1 +
+ drivers/target/iscsi/iscsi_target_login.c | 1 +
+ drivers/target/iscsi/iscsi_target_tpg.c | 1 +
+ 4 files changed, 11 insertions(+)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -382,6 +382,14 @@ isert_connect_request(struct rdma_cm_id
+ struct ib_device *ib_dev = cma_id->device;
+ int ret = 0;
+
++ spin_lock_bh(&np->np_thread_lock);
++ if (!np->enabled) {
++ spin_unlock_bh(&np->np_thread_lock);
++ pr_debug("iscsi_np is not enabled, reject connect request\n");
++ return rdma_reject(cma_id, NULL, 0);
++ }
++ spin_unlock_bh(&np->np_thread_lock);
++
+ pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n",
+ cma_id, cma_id->context);
+
+--- a/drivers/target/iscsi/iscsi_target_core.h
++++ b/drivers/target/iscsi/iscsi_target_core.h
+@@ -760,6 +760,7 @@ struct iscsi_np {
+ int np_ip_proto;
+ int np_sock_type;
+ enum np_thread_state_table np_thread_state;
++ bool enabled;
+ enum iscsi_timer_flags_table np_login_timer_flags;
+ u32 np_exports;
+ enum np_flags_table np_flags;
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -984,6 +984,7 @@ int iscsi_target_setup_login_socket(
+ }
+
+ np->np_transport = t;
++ np->enabled = true;
+ return 0;
+ }
+
+--- a/drivers/target/iscsi/iscsi_target_tpg.c
++++ b/drivers/target/iscsi/iscsi_target_tpg.c
+@@ -182,6 +182,7 @@ static void iscsit_clear_tpg_np_login_th
+ return;
+ }
+
++ tpg_np->tpg_np->enabled = false;
+ iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg);
+ }
+