Update Linux to v5.4.2
Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index bbdbf9c..1f93ea3 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config ISCSI_TARGET
tristate "Linux-iSCSI.org iSCSI Target Mode Stack"
depends on NET
diff --git a/drivers/target/iscsi/cxgbit/Kconfig b/drivers/target/iscsi/cxgbit/Kconfig
index bc6c1d5..8686dbd 100644
--- a/drivers/target/iscsi/cxgbit/Kconfig
+++ b/drivers/target/iscsi/cxgbit/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config ISCSI_TARGET_CXGB4
tristate "Chelsio iSCSI target offload driver"
depends on ISCSI_TARGET && CHELSIO_T4 && INET
diff --git a/drivers/target/iscsi/cxgbit/Makefile b/drivers/target/iscsi/cxgbit/Makefile
index d16aaae..0dcaf20 100644
--- a/drivers/target/iscsi/cxgbit/Makefile
+++ b/drivers/target/iscsi/cxgbit/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
-ccflags-y += -Idrivers/net/ethernet/chelsio/libcxgb
-ccflags-y += -Idrivers/target/iscsi
+ccflags-y := -I $(srctree)/drivers/net/ethernet/chelsio/cxgb4
+ccflags-y += -I $(srctree)/drivers/net/ethernet/chelsio/libcxgb
+ccflags-y += -I $(srctree)/drivers/target/iscsi
obj-$(CONFIG_ISCSI_TARGET_CXGB4) += cxgbit.o
diff --git a/drivers/target/iscsi/cxgbit/cxgbit.h b/drivers/target/iscsi/cxgbit/cxgbit.h
index 417b9e6..c04cd08 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit.h
+++ b/drivers/target/iscsi/cxgbit/cxgbit.h
@@ -1,9 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016 Chelsio Communications, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#ifndef __CXGBIT_H__
@@ -345,7 +342,7 @@
int cxgbit_ddp_init(struct cxgbit_device *);
int cxgbit_setup_conn_pgidx(struct cxgbit_sock *, u32);
int cxgbit_reserve_ttt(struct cxgbit_sock *, struct iscsi_cmd *);
-void cxgbit_release_cmd(struct iscsi_conn *, struct iscsi_cmd *);
+void cxgbit_unmap_cmd(struct iscsi_conn *, struct iscsi_cmd *);
static inline
struct cxgbi_ppm *cdev2ppm(struct cxgbit_device *cdev)
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
index 8de1601..a2b5c79 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016 Chelsio Communications, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/module.h>
@@ -598,9 +595,12 @@
mutex_unlock(&cdev_list_lock);
}
+static void __cxgbit_free_conn(struct cxgbit_sock *csk);
+
void cxgbit_free_np(struct iscsi_np *np)
{
struct cxgbit_np *cnp = np->np_context;
+ struct cxgbit_sock *csk, *tmp;
cnp->com.state = CSK_STATE_DEAD;
if (cnp->com.cdev)
@@ -608,6 +608,13 @@
else
cxgbit_free_all_np(cnp);
+ spin_lock_bh(&cnp->np_accept_lock);
+ list_for_each_entry_safe(csk, tmp, &cnp->np_accept_list, accept_node) {
+ list_del_init(&csk->accept_node);
+ __cxgbit_free_conn(csk);
+ }
+ spin_unlock_bh(&cnp->np_accept_lock);
+
np->np_context = NULL;
cxgbit_put_cnp(cnp);
}
@@ -631,8 +638,11 @@
static void cxgbit_arp_failure_discard(void *handle, struct sk_buff *skb)
{
+ struct cxgbit_sock *csk = handle;
+
pr_debug("%s cxgbit_device %p\n", __func__, handle);
kfree_skb(skb);
+ cxgbit_put_csk(csk);
}
static void cxgbit_abort_arp_failure(void *handle, struct sk_buff *skb)
@@ -705,9 +715,9 @@
csk->tid, 600, __func__);
}
-void cxgbit_free_conn(struct iscsi_conn *conn)
+static void __cxgbit_free_conn(struct cxgbit_sock *csk)
{
- struct cxgbit_sock *csk = conn->context;
+ struct iscsi_conn *conn = csk->conn;
bool release = false;
pr_debug("%s: state %d\n",
@@ -716,7 +726,7 @@
spin_lock_bh(&csk->lock);
switch (csk->com.state) {
case CSK_STATE_ESTABLISHED:
- if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
+ if (conn && (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)) {
csk->com.state = CSK_STATE_CLOSING;
cxgbit_send_halfclose(csk);
} else {
@@ -741,6 +751,11 @@
cxgbit_put_csk(csk);
}
+void cxgbit_free_conn(struct iscsi_conn *conn)
+{
+ __cxgbit_free_conn(conn->context);
+}
+
static void cxgbit_set_emss(struct cxgbit_sock *csk, u16 opt)
{
csk->emss = csk->com.cdev->lldi.mtus[TCPOPT_MSS_G(opt)] -
@@ -803,6 +818,7 @@
spin_unlock_bh(&cdev->cskq.lock);
cxgbit_free_skb(csk);
+ cxgbit_put_cnp(csk->cnp);
cxgbit_put_cdev(cdev);
kfree(csk);
@@ -859,10 +875,12 @@
return 0;
if (caps & DCB_CAP_DCBX_VER_IEEE) {
- iscsi_dcb_app.selector = IEEE_8021QAZ_APP_SEL_ANY;
-
+ iscsi_dcb_app.selector = IEEE_8021QAZ_APP_SEL_STREAM;
ret = dcb_ieee_getapp_mask(ndev, &iscsi_dcb_app);
-
+ if (!ret) {
+ iscsi_dcb_app.selector = IEEE_8021QAZ_APP_SEL_ANY;
+ ret = dcb_ieee_getapp_mask(ndev, &iscsi_dcb_app);
+ }
} else if (caps & DCB_CAP_DCBX_VER_CEE) {
iscsi_dcb_app.selector = DCB_APP_IDTYPE_PORTNUM;
@@ -916,8 +934,8 @@
goto out;
csk->mtu = ndev->mtu;
csk->tx_chan = cxgb4_port_chan(ndev);
- csk->smac_idx = cxgb4_tp_smt_idx(cdev->lldi.adapter_type,
- cxgb4_port_viid(ndev));
+ csk->smac_idx =
+ ((struct port_info *)netdev_priv(ndev))->smt_idx;
step = cdev->lldi.ntxq /
cdev->lldi.nchan;
csk->txq_idx = cxgb4_port_idx(ndev) * step;
@@ -952,8 +970,8 @@
port_id = cxgb4_port_idx(ndev);
csk->mtu = dst_mtu(dst);
csk->tx_chan = cxgb4_port_chan(ndev);
- csk->smac_idx = cxgb4_tp_smt_idx(cdev->lldi.adapter_type,
- cxgb4_port_viid(ndev));
+ csk->smac_idx =
+ ((struct port_info *)netdev_priv(ndev))->smt_idx;
step = cdev->lldi.ntxq /
cdev->lldi.nports;
csk->txq_idx = (port_id * step) +
@@ -1190,7 +1208,7 @@
rpl5->opt0 = cpu_to_be64(opt0);
rpl5->opt2 = cpu_to_be32(opt2);
set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->ctrlq_idx);
- t4_set_arp_err_handler(skb, NULL, cxgbit_arp_failure_discard);
+ t4_set_arp_err_handler(skb, csk, cxgbit_arp_failure_discard);
cxgbit_l2t_send(csk->com.cdev, skb, csk->l2t);
}
@@ -1351,6 +1369,7 @@
goto rel_skb;
}
+ cxgbit_get_cnp(cnp);
cxgbit_get_cdev(cdev);
spin_lock(&cdev->cskq.lock);
@@ -1812,7 +1831,7 @@
while (credits) {
struct sk_buff *p = cxgbit_sock_peek_wr(csk);
- const u32 csum = (__force u32)p->csum;
+ u32 csum;
if (unlikely(!p)) {
pr_err("csk 0x%p,%u, cr %u,%u+%u, empty.\n",
@@ -1821,6 +1840,7 @@
break;
}
+ csum = (__force u32)p->csum;
if (unlikely(credits < csum)) {
pr_warn("csk 0x%p,%u, cr %u,%u+%u, < %u.\n",
csk, csk->tid,
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_ddp.c b/drivers/target/iscsi/cxgbit/cxgbit_ddp.c
index 76a2626..54bb1eb 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_ddp.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_ddp.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016 Chelsio Communications, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include "cxgbit.h"
@@ -263,7 +260,7 @@
r2t->targ_xfer_tag = ttinfo->tag;
}
-void cxgbit_release_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
+void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);
@@ -318,8 +315,10 @@
ret = cxgbi_ppm_init(lldi->iscsi_ppm, cdev->lldi.ports[0],
cdev->lldi.pdev, &cdev->lldi, &tformat,
- ppmax, lldi->iscsi_llimit,
- lldi->vr->iscsi.start, 2);
+ lldi->vr->iscsi.size, lldi->iscsi_llimit,
+ lldi->vr->iscsi.start, 2,
+ lldi->vr->ppod_edram.start,
+ lldi->vr->ppod_edram.size);
if (ret >= 0) {
struct cxgbi_ppm *ppm = (struct cxgbi_ppm *)(*lldi->iscsi_ppm);
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_main.c b/drivers/target/iscsi/cxgbit/cxgbit_main.c
index f3f8856..e877b91 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_main.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_main.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016 Chelsio Communications, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#define DRV_NAME "cxgbit"
@@ -58,6 +55,7 @@
return ERR_PTR(-ENOMEM);
kref_init(&cdev->kref);
+ spin_lock_init(&cdev->np_lock);
cdev->lldi = *lldi;
@@ -591,7 +589,8 @@
iscsi_app = &dcb_work->dcb_app;
if (iscsi_app->dcbx & DCB_CAP_DCBX_VER_IEEE) {
- if (iscsi_app->app.selector != IEEE_8021QAZ_APP_SEL_ANY)
+ if ((iscsi_app->app.selector != IEEE_8021QAZ_APP_SEL_STREAM) &&
+ (iscsi_app->app.selector != IEEE_8021QAZ_APP_SEL_ANY))
goto out;
priority = iscsi_app->app.priority;
@@ -677,7 +676,7 @@
.iscsit_get_r2t_ttt = cxgbit_get_r2t_ttt,
.iscsit_get_rx_pdu = cxgbit_get_rx_pdu,
.iscsit_validate_params = cxgbit_validate_params,
- .iscsit_release_cmd = cxgbit_release_cmd,
+ .iscsit_unmap_cmd = cxgbit_unmap_cmd,
.iscsit_aborted_task = iscsit_aborted_task,
.iscsit_get_sup_prot_ops = cxgbit_get_sup_prot_ops,
};
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c
index 25eb389..fcdc421 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_target.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016 Chelsio Communications, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/workqueue.h>
@@ -902,9 +899,9 @@
skb_frag_t *dfrag = &ssi->frags[pdu_cb->dfrag_idx];
sg_init_table(&ccmd->sg, 1);
- sg_set_page(&ccmd->sg, dfrag->page.p, skb_frag_size(dfrag),
- dfrag->page_offset);
- get_page(dfrag->page.p);
+ sg_set_page(&ccmd->sg, skb_frag_page(dfrag),
+ skb_frag_size(dfrag), skb_frag_off(dfrag));
+ get_page(skb_frag_page(dfrag));
cmd->se_cmd.t_data_sg = &ccmd->sg;
cmd->se_cmd.t_data_nents = 1;
@@ -960,7 +957,7 @@
target_put_sess_cmd(&cmd->se_cmd);
return 0;
} else if (cmd->unsolicited_data) {
- iscsit_set_unsoliticed_dataout(cmd);
+ iscsit_set_unsolicited_dataout(cmd);
}
} else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
@@ -1406,7 +1403,8 @@
pdu_cb->ddigest, pdu_cb->frags);
for (i = 0; i < ssi->nr_frags; i++)
pr_info("skb 0x%p, frag %d, off %u, sz %u.\n",
- skb, i, ssi->frags[i].page_offset, ssi->frags[i].size);
+ skb, i, skb_frag_off(&ssi->frags[i]),
+ skb_frag_size(&ssi->frags[i]));
}
static void cxgbit_lro_hskb_reset(struct cxgbit_sock *csk)
@@ -1450,7 +1448,7 @@
hpdu_cb->frags++;
hpdu_cb->hfrag_idx = hfrag_idx;
- len = hssi->frags[hfrag_idx].size;
+ len = skb_frag_size(&hssi->frags[hfrag_idx]);
hskb->len += len;
hskb->data_len += len;
hskb->truesize += len;
@@ -1470,7 +1468,7 @@
get_page(skb_frag_page(&hssi->frags[dfrag_idx]));
- len += hssi->frags[dfrag_idx].size;
+ len += skb_frag_size(&hssi->frags[dfrag_idx]);
hssi->nr_frags++;
hpdu_cb->frags++;
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index cc756a1..d19e051 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains main functions related to the iSCSI Target Core Driver.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <crypto/hash.h>
@@ -308,9 +300,6 @@
return false;
}
-/*
- * Called with mutex np_lock held
- */
static struct iscsi_np *iscsit_get_np(
struct sockaddr_storage *sockaddr,
int network_transport)
@@ -318,6 +307,8 @@
struct iscsi_np *np;
bool match;
+ lockdep_assert_held(&np_lock);
+
list_for_each_entry(np, &g_np_list, np_list) {
spin_lock_bh(&np->np_thread_lock);
if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
@@ -574,7 +565,8 @@
return 0;
}
-static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
+static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec,
+ u32 data_offset, u32 data_length);
static void iscsit_unmap_iovec(struct iscsi_cmd *);
static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
u32, u32, u32, u8 *);
@@ -605,7 +597,8 @@
*header_digest);
}
- iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1],
+ iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[iov_count],
+ cmd->orig_iov_data_count - (iov_count + 2),
datain->offset, datain->length);
if (iov_ret < 0)
return -1;
@@ -714,7 +707,7 @@
sizeof(struct iscsi_queue_req),
__alignof__(struct iscsi_queue_req), 0, NULL);
if (!lio_qr_cache) {
- pr_err("nable to kmem_cache_create() for"
+ pr_err("Unable to kmem_cache_create() for"
" lio_qr_cache\n");
goto bitmap_out;
}
@@ -887,13 +880,10 @@
* Map some portion of the allocated scatterlist to an iovec, suitable for
* kernel sockets to copy data in/out.
*/
-static int iscsit_map_iovec(
- struct iscsi_cmd *cmd,
- struct kvec *iov,
- u32 data_offset,
- u32 data_length)
+static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec,
+ u32 data_offset, u32 data_length)
{
- u32 i = 0;
+ u32 i = 0, orig_data_length = data_length;
struct scatterlist *sg;
unsigned int page_off;
@@ -902,9 +892,12 @@
*/
u32 ent = data_offset / PAGE_SIZE;
+ if (!data_length)
+ return 0;
+
if (ent >= cmd->se_cmd.t_data_nents) {
pr_err("Initial page entry out-of-bounds\n");
- return -1;
+ goto overflow;
}
sg = &cmd->se_cmd.t_data_sg[ent];
@@ -914,7 +907,12 @@
cmd->first_data_sg_off = page_off;
while (data_length) {
- u32 cur_len = min_t(u32, data_length, sg->length - page_off);
+ u32 cur_len;
+
+ if (WARN_ON_ONCE(!sg || i >= nvec))
+ goto overflow;
+
+ cur_len = min_t(u32, data_length, sg->length - page_off);
iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
iov[i].iov_len = cur_len;
@@ -928,6 +926,16 @@
cmd->kmapped_nents = i;
return i;
+
+overflow:
+ pr_err("offset %d + length %d overflow; %d/%d; sg-list:\n",
+ data_offset, orig_data_length, i, nvec);
+ for_each_sg(cmd->se_cmd.t_data_sg, sg,
+ cmd->se_cmd.t_data_nents, i) {
+ pr_err("[%d] off %d len %d\n",
+ i, sg->offset, sg->length);
+ }
+ return -1;
}
static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
@@ -1195,7 +1203,7 @@
}
EXPORT_SYMBOL(iscsit_setup_scsi_cmd);
-void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd)
+void iscsit_set_unsolicited_dataout(struct iscsi_cmd *cmd)
{
iscsit_set_dataout_sequence_values(cmd);
@@ -1203,7 +1211,7 @@
iscsit_start_dataout_timer(cmd, cmd->conn);
spin_unlock_bh(&cmd->dataout_timeout_lock);
}
-EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout);
+EXPORT_SYMBOL(iscsit_set_unsolicited_dataout);
int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
struct iscsi_scsi_req *hdr)
@@ -1237,7 +1245,7 @@
*/
if (!cmd->immediate_data) {
if (!cmd->sense_reason && cmd->unsolicited_data)
- iscsit_set_unsoliticed_dataout(cmd);
+ iscsit_set_unsolicited_dataout(cmd);
if (!cmd->sense_reason)
return 0;
@@ -1269,27 +1277,27 @@
bool dump_payload)
{
int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
+ int rc;
+
/*
* Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
*/
- if (dump_payload)
- goto after_immediate_data;
- /*
- * Check for underflow case where both EDTL and immediate data payload
- * exceeds what is presented by CDB's TRANSFER LENGTH, and what has
- * already been set in target_cmd_size_check() as se_cmd->data_length.
- *
- * For this special case, fail the command and dump the immediate data
- * payload.
- */
- if (cmd->first_burst_len > cmd->se_cmd.data_length) {
- cmd->sense_reason = TCM_INVALID_CDB_FIELD;
- goto after_immediate_data;
+ if (dump_payload) {
+ u32 length = min(cmd->se_cmd.data_length - cmd->write_data_done,
+ cmd->first_burst_len);
+
+ pr_debug("Dumping min(%d - %d, %d) = %d bytes of immediate data\n",
+ cmd->se_cmd.data_length, cmd->write_data_done,
+ cmd->first_burst_len, length);
+ rc = iscsit_dump_data_payload(cmd->conn, length, 1);
+ pr_debug("Finished dumping immediate data\n");
+ if (rc < 0)
+ immed_ret = IMMEDIATE_DATA_CANNOT_RECOVER;
+ } else {
+ immed_ret = iscsit_handle_immediate_data(cmd, hdr,
+ cmd->first_burst_len);
}
- immed_ret = iscsit_handle_immediate_data(cmd, hdr,
- cmd->first_burst_len);
-after_immediate_data:
if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) {
/*
* A PDU/CmdSN carrying Immediate Data passed
@@ -1302,14 +1310,11 @@
return -1;
if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
- int rc;
-
- rc = iscsit_dump_data_payload(cmd->conn,
- cmd->first_burst_len, 1);
target_put_sess_cmd(&cmd->se_cmd);
- return rc;
+
+ return 0;
} else if (cmd->unsolicited_data)
- iscsit_set_unsoliticed_dataout(cmd);
+ iscsit_set_unsolicited_dataout(cmd);
} else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
/*
@@ -1493,8 +1498,6 @@
if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
iscsit_stop_dataout_timer(cmd);
- transport_check_aborted_status(se_cmd,
- (hdr->flags & ISCSI_FLAG_CMD_FINAL));
return iscsit_dump_data_payload(conn, payload_length, 1);
}
} else {
@@ -1509,12 +1512,9 @@
* TASK_ABORTED status.
*/
if (se_cmd->transport_state & CMD_T_ABORTED) {
- if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
- if (--cmd->outstanding_r2ts < 1) {
- iscsit_stop_dataout_timer(cmd);
- transport_check_aborted_status(
- se_cmd, 1);
- }
+ if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
+ --cmd->outstanding_r2ts < 1)
+ iscsit_stop_dataout_timer(cmd);
return iscsit_dump_data_payload(conn, payload_length, 1);
}
@@ -1574,14 +1574,16 @@
{
struct kvec *iov;
u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0;
- u32 payload_length = ntoh24(hdr->dlength);
+ u32 payload_length;
int iov_ret, data_crc_failed = 0;
+ payload_length = min_t(u32, cmd->se_cmd.data_length,
+ ntoh24(hdr->dlength));
rx_size += payload_length;
iov = &cmd->iov_data[0];
- iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
- payload_length);
+ iov_ret = iscsit_map_iovec(cmd, iov, cmd->orig_iov_data_count - 2,
+ be32_to_cpu(hdr->offset), payload_length);
if (iov_ret < 0)
return -1;
@@ -1601,6 +1603,7 @@
rx_size += ISCSI_CRC_LEN;
}
+ WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count);
rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
iscsit_unmap_iovec(cmd);
@@ -1866,6 +1869,7 @@
rx_size += ISCSI_CRC_LEN;
}
+ WARN_ON_ONCE(niov > ARRAY_SIZE(cmd->iov_misc));
rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size);
if (rx_got != rx_size) {
ret = -1;
@@ -2246,42 +2250,40 @@
rx_size = payload_length;
if (payload_length) {
u32 checksum = 0, data_crc = 0;
- u32 padding = 0, pad_bytes = 0;
+ u32 padding = 0;
int niov = 0, rx_got;
- struct kvec iov[3];
+ struct kvec iov[2];
- text_in = kzalloc(payload_length, GFP_KERNEL);
+ rx_size = ALIGN(payload_length, 4);
+ text_in = kzalloc(rx_size, GFP_KERNEL);
if (!text_in)
goto reject;
cmd->text_in_ptr = text_in;
- memset(iov, 0, 3 * sizeof(struct kvec));
+ memset(iov, 0, sizeof(iov));
iov[niov].iov_base = text_in;
- iov[niov++].iov_len = payload_length;
+ iov[niov++].iov_len = rx_size;
- padding = ((-payload_length) & 3);
- if (padding != 0) {
- iov[niov].iov_base = &pad_bytes;
- iov[niov++].iov_len = padding;
- rx_size += padding;
+ padding = rx_size - payload_length;
+ if (padding)
pr_debug("Receiving %u additional bytes"
" for padding.\n", padding);
- }
if (conn->conn_ops->DataDigest) {
iov[niov].iov_base = &checksum;
iov[niov++].iov_len = ISCSI_CRC_LEN;
rx_size += ISCSI_CRC_LEN;
}
+ WARN_ON_ONCE(niov > ARRAY_SIZE(iov));
rx_got = rx_data(conn, &iov[0], niov, rx_size);
if (rx_got != rx_size)
goto reject;
if (conn->conn_ops->DataDigest) {
- iscsit_do_crypto_hash_buf(conn->conn_rx_hash, text_in,
- payload_length, padding,
- &pad_bytes, &data_crc);
+ iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
+ text_in, rx_size, 0, NULL,
+ &data_crc);
if (checksum != data_crc) {
pr_err("Text data CRC32C DataDigest"
@@ -2584,14 +2586,34 @@
u32 checksum, iov_count = 0, padding = 0;
struct iscsi_conn *conn = cmd->conn;
struct kvec *iov;
+ void *overflow_buf = NULL;
- iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length);
+ BUG_ON(cmd->write_data_done > cmd->se_cmd.data_length);
+ rx_size = min(cmd->se_cmd.data_length - cmd->write_data_done, length);
+ iov_ret = iscsit_map_iovec(cmd, cmd->iov_data,
+ cmd->orig_iov_data_count - 2,
+ cmd->write_data_done, rx_size);
if (iov_ret < 0)
return IMMEDIATE_DATA_CANNOT_RECOVER;
- rx_size = length;
iov_count = iov_ret;
iov = &cmd->iov_data[0];
+ if (rx_size < length) {
+ /*
+ * Special case: length of immediate data exceeds the data
+ * buffer size derived from the CDB.
+ */
+ overflow_buf = kmalloc(length - rx_size, GFP_KERNEL);
+ if (!overflow_buf) {
+ iscsit_unmap_iovec(cmd);
+ return IMMEDIATE_DATA_CANNOT_RECOVER;
+ }
+ cmd->overflow_buf = overflow_buf;
+ iov[iov_count].iov_base = overflow_buf;
+ iov[iov_count].iov_len = length - rx_size;
+ iov_count++;
+ rx_size = length;
+ }
padding = ((-length) & 3);
if (padding != 0) {
@@ -2606,6 +2628,7 @@
rx_size += ISCSI_CRC_LEN;
}
+ WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count);
rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
iscsit_unmap_iovec(cmd);
@@ -2660,9 +2683,6 @@
return IMMEDIATE_DATA_NORMAL_OPERATION;
}
-/*
- * Called with sess->conn_lock held.
- */
/* #warning iscsi_build_conn_drop_async_message() only sends out on connections
with active network interface */
static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
@@ -2671,6 +2691,8 @@
struct iscsi_conn *conn_p;
bool found = false;
+ lockdep_assert_held(&conn->sess->conn_lock);
+
/*
* Only send a Asynchronous Message on connections whos network
* interface is still functional.
@@ -3131,6 +3153,12 @@
else
xfer_len = conn->sess->sess_ops->MaxBurstLength;
}
+
+ if ((s32)xfer_len < 0) {
+ cmd->cmd_flags |= ICF_SENT_LAST_R2T;
+ break;
+ }
+
cmd->r2t_offset += xfer_len;
if (cmd->r2t_offset == cmd->se_cmd.data_length)
@@ -4045,9 +4073,9 @@
struct se_cmd *se_cmd = &cmd->se_cmd;
if (se_cmd->se_tfo != NULL) {
- spin_lock(&se_cmd->t_state_lock);
+ spin_lock_irq(&se_cmd->t_state_lock);
se_cmd->transport_state |= CMD_T_FABRIC_STOP;
- spin_unlock(&se_cmd->t_state_lock);
+ spin_unlock_irq(&se_cmd->t_state_lock);
}
}
spin_unlock_bh(&conn->cmd_lock);
@@ -4355,7 +4383,7 @@
transport_deregister_session(sess->se_sess);
if (sess->sess_ops->ErrorRecoveryLevel == 2)
- iscsit_free_connection_recovery_entires(sess);
+ iscsit_free_connection_recovery_entries(sess);
iscsit_free_all_ooo_cmdsns(sess);
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
index 48bac0a..c95f56a 100644
--- a/drivers/target/iscsi/iscsi_target.h
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -31,7 +31,7 @@
struct iscsi_portal_group *, bool);
extern int iscsit_del_np(struct iscsi_np *);
extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *);
-extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
+extern void iscsit_set_unsolicited_dataout(struct iscsi_cmd *);
extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *);
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c
index 4e680d7..51ddca2 100644
--- a/drivers/target/iscsi/iscsi_target_auth.c
+++ b/drivers/target/iscsi/iscsi_target_auth.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file houses the main functions for the iSCSI CHAP support
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <crypto/hash.h>
@@ -89,6 +81,12 @@
return CHAP_DIGEST_UNKNOWN;
}
+static void chap_close(struct iscsi_conn *conn)
+{
+ kfree(conn->auth_protocol);
+ conn->auth_protocol = NULL;
+}
+
static struct iscsi_chap *chap_server_open(
struct iscsi_conn *conn,
struct iscsi_node_auth *auth,
@@ -126,7 +124,7 @@
case CHAP_DIGEST_UNKNOWN:
default:
pr_err("Unsupported CHAP_A value\n");
- kfree(conn->auth_protocol);
+ chap_close(conn);
return NULL;
}
@@ -141,19 +139,13 @@
* Generate Challenge.
*/
if (chap_gen_challenge(conn, 1, aic_str, aic_len) < 0) {
- kfree(conn->auth_protocol);
+ chap_close(conn);
return NULL;
}
return chap;
}
-static void chap_close(struct iscsi_conn *conn)
-{
- kfree(conn->auth_protocol);
- conn->auth_protocol = NULL;
-}
-
static int chap_server_compute_md5(
struct iscsi_conn *conn,
struct iscsi_node_auth *auth,
@@ -252,7 +244,6 @@
}
desc->tfm = tfm;
- desc->flags = 0;
ret = crypto_shash_init(desc);
if (ret < 0) {
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index 95d0a22..42b369f 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the configfs implementation for iSCSI Target mode
* from the LIO-Target Project.
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
****************************************************************************/
#include <linux/configfs.h>
@@ -1343,11 +1335,6 @@
/* Start functions for target_core_fabric_ops */
-static char *iscsi_get_fabric_name(void)
-{
- return "iSCSI";
-}
-
static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1394,18 +1381,6 @@
return 0;
}
-static int lio_write_pending_status(struct se_cmd *se_cmd)
-{
- struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
- int ret;
-
- spin_lock_bh(&cmd->istate_lock);
- ret = !(cmd->cmd_flags & ICF_GOT_LAST_DATAOUT);
- spin_unlock_bh(&cmd->istate_lock);
-
- return ret;
-}
-
static int lio_queue_status(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1549,9 +1524,9 @@
const struct target_core_fabric_ops iscsi_ops = {
.module = THIS_MODULE,
- .name = "iscsi",
+ .fabric_alias = "iscsi",
+ .fabric_name = "iSCSI",
.node_acl_size = sizeof(struct iscsi_node_acl),
- .get_fabric_name = iscsi_get_fabric_name,
.tpg_get_wwn = lio_tpg_get_endpoint_wwn,
.tpg_get_tag = lio_tpg_get_tag,
.tpg_get_default_depth = lio_tpg_get_default_depth,
@@ -1569,7 +1544,6 @@
.sess_get_index = lio_sess_get_index,
.sess_get_initiator_sid = lio_sess_get_initiator_sid,
.write_pending = lio_write_pending,
- .write_pending_status = lio_write_pending_status,
.set_default_node_attributes = lio_set_default_node_attributes,
.get_cmd_state = iscsi_get_cmd_state,
.queue_data_in = lio_queue_data_in,
@@ -1596,4 +1570,6 @@
.tfc_tpg_nacl_attrib_attrs = lio_target_nacl_attrib_attrs,
.tfc_tpg_nacl_auth_attrs = lio_target_nacl_auth_attrs,
.tfc_tpg_nacl_param_attrs = lio_target_nacl_param_attrs,
+
+ .write_pending_must_be_called = true,
};
diff --git a/drivers/target/iscsi/iscsi_target_datain_values.c b/drivers/target/iscsi/iscsi_target_datain_values.c
index 173ddd9..07a22cd 100644
--- a/drivers/target/iscsi/iscsi_target_datain_values.c
+++ b/drivers/target/iscsi/iscsi_target_datain_values.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the iSCSI Target DataIN value generation functions.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/slab.h>
diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c
index 0382fa2..8bf36ec 100644
--- a/drivers/target/iscsi/iscsi_target_device.c
+++ b/drivers/target/iscsi/iscsi_target_device.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the iSCSI Virtual Device and Disk Transport
* agnostic related functions.
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <target/target_core_base.h>
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 718fe9a..b4abd7b 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/******************************************************************************
* This file contains error recovery level zero functions used by
* the iSCSI Target driver.
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/sched/signal.h>
@@ -770,21 +762,8 @@
pr_err("Time2Retain timer expired for SID: %u, cleaning up"
" iSCSI session.\n", sess->sid);
- {
- struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
- if (tiqn) {
- spin_lock(&tiqn->sess_err_stats.lock);
- strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
- (void *)sess->sess_ops->InitiatorName);
- tiqn->sess_err_stats.last_sess_failure_type =
- ISCSI_SESS_ERR_CXN_TIMEOUT;
- tiqn->sess_err_stats.cxn_timeout_errors++;
- atomic_long_inc(&sess->conn_timeout_errors);
- spin_unlock(&tiqn->sess_err_stats.lock);
- }
- }
-
+ iscsit_fill_cxn_timeout_err_stats(sess);
spin_unlock_bh(&se_tpg->session_lock);
iscsit_close_session(sess);
}
@@ -815,14 +794,13 @@
jiffies + sess->sess_ops->DefaultTime2Retain * HZ);
}
-/*
- * Called with spin_lock_bh(&struct se_portal_group->session_lock) held
- */
int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
{
struct iscsi_portal_group *tpg = sess->tpg;
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
+ lockdep_assert_held(&se_tpg->session_lock);
+
if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)
return -1;
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 5efa42b..cd670cb 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains error recovery level one used by the iSCSI Target driver.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/list.h>
@@ -48,14 +40,20 @@
u32 buf_len,
int dump_padding_digest)
{
- char *buf, pad_bytes[4];
+ char *buf;
int ret = DATAOUT_WITHIN_COMMAND_RECOVERY, rx_got;
- u32 length, padding, offset = 0, size;
+ u32 length, offset = 0, size;
struct kvec iov;
if (conn->sess->sess_ops->RDMAExtensions)
return 0;
+ if (dump_padding_digest) {
+ buf_len = ALIGN(buf_len, 4);
+ if (conn->conn_ops->DataDigest)
+ buf_len += ISCSI_CRC_LEN;
+ }
+
length = min(buf_len, OFFLOAD_BUF_SIZE);
buf = kzalloc(length, GFP_ATOMIC);
@@ -75,41 +73,12 @@
rx_got = rx_data(conn, &iov, 1, size);
if (rx_got != size) {
ret = DATAOUT_CANNOT_RECOVER;
- goto out;
+ break;
}
offset += size;
}
- if (!dump_padding_digest)
- goto out;
-
- padding = ((-buf_len) & 3);
- if (padding != 0) {
- iov.iov_len = padding;
- iov.iov_base = pad_bytes;
-
- rx_got = rx_data(conn, &iov, 1, padding);
- if (rx_got != padding) {
- ret = DATAOUT_CANNOT_RECOVER;
- goto out;
- }
- }
-
- if (conn->conn_ops->DataDigest) {
- u32 data_crc;
-
- iov.iov_len = ISCSI_CRC_LEN;
- iov.iov_base = &data_crc;
-
- rx_got = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
- if (rx_got != ISCSI_CRC_LEN) {
- ret = DATAOUT_CANNOT_RECOVER;
- goto out;
- }
- }
-
-out:
kfree(buf);
return ret;
}
@@ -797,14 +766,14 @@
return ooo_cmdsn;
}
-/*
- * Called with sess->cmdsn_mutex held.
- */
static int iscsit_attach_ooo_cmdsn(
struct iscsi_session *sess,
struct iscsi_ooo_cmdsn *ooo_cmdsn)
{
struct iscsi_ooo_cmdsn *ooo_tail, *ooo_tmp;
+
+ lockdep_assert_held(&sess->cmdsn_mutex);
+
/*
* We attach the struct iscsi_ooo_cmdsn entry to the out of order
* list in increasing CmdSN order.
@@ -871,15 +840,14 @@
mutex_unlock(&sess->cmdsn_mutex);
}
-/*
- * Called with sess->cmdsn_mutex held.
- */
int iscsit_execute_ooo_cmdsns(struct iscsi_session *sess)
{
int ooo_count = 0;
struct iscsi_cmd *cmd = NULL;
struct iscsi_ooo_cmdsn *ooo_cmdsn, *ooo_cmdsn_tmp;
+ lockdep_assert_held(&sess->cmdsn_mutex);
+
list_for_each_entry_safe(ooo_cmdsn, ooo_cmdsn_tmp,
&sess->sess_ooo_cmdsn_list, ooo_list) {
if (ooo_cmdsn->cmdsn != sess->exp_cmd_sn)
@@ -943,20 +911,8 @@
return 0;
}
spin_unlock_bh(&cmd->istate_lock);
- /*
- * Determine if delayed TASK_ABORTED status for WRITEs
- * should be sent now if no unsolicited data out
- * payloads are expected, or if the delayed status
- * should be sent after unsolicited data out with
- * ISCSI_FLAG_CMD_FINAL set in iscsi_handle_data_out()
- */
- if (transport_check_aborted_status(se_cmd,
- (cmd->unsolicited_data == 0)) != 0)
+ if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
return 0;
- /*
- * Otherwise send CHECK_CONDITION and sense for
- * exception
- */
return transport_send_check_condition_and_sense(se_cmd,
cmd->sense_reason, 0);
}
@@ -974,13 +930,7 @@
if (!(cmd->cmd_flags &
ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
- /*
- * Send the delayed TASK_ABORTED status for
- * WRITEs if no more unsolicitied data is
- * expected.
- */
- if (transport_check_aborted_status(se_cmd, 1)
- != 0)
+ if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
return 0;
iscsit_set_dataout_sequence_values(cmd);
@@ -995,14 +945,10 @@
if ((cmd->data_direction == DMA_TO_DEVICE) &&
!(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
- /*
- * Send the delayed TASK_ABORTED status for WRITEs if
- * no more nsolicitied data is expected.
- */
- if (transport_check_aborted_status(se_cmd, 1) != 0)
+ if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
return 0;
- iscsit_set_unsoliticed_dataout(cmd);
+ iscsit_set_unsolicited_dataout(cmd);
}
return transport_handle_cdb_direct(&cmd->se_cmd);
@@ -1169,15 +1115,21 @@
na = iscsit_tpg_get_node_attrib(sess);
if (!sess->sess_ops->ErrorRecoveryLevel) {
- pr_debug("Unable to recover from DataOut timeout while"
- " in ERL=0.\n");
+ pr_err("Unable to recover from DataOut timeout while"
+ " in ERL=0, closing iSCSI connection for I_T Nexus"
+ " %s,i,0x%6phN,%s,t,0x%02x\n",
+ sess->sess_ops->InitiatorName, sess->isid,
+ sess->tpg->tpg_tiqn->tiqn, (u32)sess->tpg->tpgt);
goto failure;
}
if (++cmd->dataout_timeout_retries == na->dataout_timeout_retries) {
- pr_debug("Command ITT: 0x%08x exceeded max retries"
- " for DataOUT timeout %u, closing iSCSI connection.\n",
- cmd->init_task_tag, na->dataout_timeout_retries);
+ pr_err("Command ITT: 0x%08x exceeded max retries"
+ " for DataOUT timeout %u, closing iSCSI connection for"
+ " I_T Nexus %s,i,0x%6phN,%s,t,0x%02x\n",
+ cmd->init_task_tag, na->dataout_timeout_retries,
+ sess->sess_ops->InitiatorName, sess->isid,
+ sess->tpg->tpg_tiqn->tiqn, (u32)sess->tpg->tpgt);
goto failure;
}
@@ -1224,6 +1176,7 @@
failure:
spin_unlock_bh(&cmd->dataout_timeout_lock);
+ iscsit_fill_cxn_timeout_err_stats(sess);
iscsit_cause_connection_reinstatement(conn, 0);
iscsit_dec_conn_usage_count(conn);
}
@@ -1247,9 +1200,6 @@
spin_unlock_bh(&cmd->dataout_timeout_lock);
}
-/*
- * Called with cmd->dataout_timeout_lock held.
- */
void iscsit_start_dataout_timer(
struct iscsi_cmd *cmd,
struct iscsi_conn *conn)
@@ -1257,6 +1207,8 @@
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
+ lockdep_assert_held(&cmd->dataout_timeout_lock);
+
if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING)
return;
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c
index 8df9c90..b1b7db9 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.c
+++ b/drivers/target/iscsi/iscsi_target_erl2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains error recovery level two functions used by
* the iSCSI Target driver.
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/slab.h>
@@ -125,7 +117,7 @@
return NULL;
}
-void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
+void iscsit_free_connection_recovery_entries(struct iscsi_session *sess)
{
struct iscsi_cmd *cmd, *cmd_tmp;
struct iscsi_conn_recovery *cr, *cr_tmp;
diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h
index 93e180d..a39b0ca 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.h
+++ b/drivers/target/iscsi/iscsi_target_erl2.h
@@ -13,7 +13,7 @@
extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *);
extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
struct iscsi_session *, u16);
-extern void iscsit_free_connection_recovery_entires(struct iscsi_session *);
+extern void iscsit_free_connection_recovery_entries(struct iscsi_session *);
extern int iscsit_remove_active_connection_recovery_entry(
struct iscsi_conn_recovery *, struct iscsi_session *);
extern int iscsit_remove_cmd_from_connection_recovery(struct iscsi_cmd *,
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index bb90c80..f533308 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the login functions used by the iSCSI Target driver.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <crypto/hash.h>
@@ -578,7 +570,7 @@
}
/*
- * Check for any connection recovery entires containing CID.
+ * Check for any connection recovery entries containing CID.
* We use the original ExpStatSN sent in the first login request
* to acknowledge commands for the failed connection.
*
@@ -883,9 +875,6 @@
return -EINVAL;
}
- np->np_ip_proto = IPPROTO_TCP;
- np->np_sock_type = SOCK_STREAM;
-
ret = sock_create(sockaddr->ss_family, np->np_sock_type,
np->np_ip_proto, &sock);
if (ret < 0) {
@@ -1159,13 +1148,13 @@
if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
pr_err("Unable to allocate conn->conn_cpumask\n");
- goto free_mask;
+ goto free_conn_ops;
}
return conn;
-free_mask:
- free_cpumask_var(conn->conn_cpumask);
+free_conn_ops:
+ kfree(conn->conn_ops);
put_transport:
iscsit_put_transport(conn->conn_transport);
free_conn:
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 8a5e8d1..685d771 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains main functions related to iSCSI Parameter negotiation.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/ctype.h>
@@ -160,22 +152,11 @@
if (strstr("None", authtype))
return 1;
-#ifdef CANSRP
- else if (strstr("SRP", authtype))
- return srp_main_loop(conn, auth, in_buf, out_buf,
- &in_length, out_length);
-#endif
else if (strstr("CHAP", authtype))
return chap_main_loop(conn, auth, in_buf, out_buf,
&in_length, out_length);
- else if (strstr("SPKM1", authtype))
- return 2;
- else if (strstr("SPKM2", authtype))
- return 2;
- else if (strstr("KRB5", authtype))
- return 2;
- else
- return 2;
+ /* SRP, SPKM1, SPKM2 and KRB5 are unsupported */
+ return 2;
}
static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
diff --git a/drivers/target/iscsi/iscsi_target_nodeattrib.c b/drivers/target/iscsi/iscsi_target_nodeattrib.c
index 208cca8..e3ac247 100644
--- a/drivers/target/iscsi/iscsi_target_nodeattrib.c
+++ b/drivers/target/iscsi/iscsi_target_nodeattrib.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the main functions related to Initiator Node Attributes.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <target/target_core_base.h>
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 29a37b2..7a461fb 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains main functions related to iSCSI Parameter negotiation.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/slab.h>
diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
index f65e5e5..ea2b02a 100644
--- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
+++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains main functions related to iSCSI DataSequenceInOrder=No
* and DataPDUInOrder=No.
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/slab.h>
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c
index df0a398..35e75a3 100644
--- a/drivers/target/iscsi/iscsi_target_stat.c
+++ b/drivers/target/iscsi/iscsi_target_stat.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* Modern ConfigFS group context specific iSCSI statistics based on original
* iscsi_target_mib.c code
@@ -6,15 +7,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/configfs.h>
@@ -328,10 +320,10 @@
{
struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
struct iscsi_login_stats *lstat = &tiqn->login_stats;
- unsigned char buf[224];
+ unsigned char buf[ISCSI_IQN_LEN];
spin_lock(&lstat->lock);
- snprintf(buf, 224, "%s", lstat->last_intr_fail_name[0] ?
+ snprintf(buf, ISCSI_IQN_LEN, "%s", lstat->last_intr_fail_name[0] ?
lstat->last_intr_fail_name : NONE);
spin_unlock(&lstat->lock);
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index cb231c9..7d618db 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the iSCSI Target specific Task Management functions.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <asm/unaligned.h>
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c
index 101d621..8075f60 100644
--- a/drivers/target/iscsi/iscsi_target_tpg.c
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains iSCSI Target Portal Group related functions.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/slab.h>
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 49be1e4..89183b3 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
* This file contains the iSCSI Target specific utility functions.
*
@@ -5,15 +6,6 @@
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
******************************************************************************/
#include <linux/list.h>
@@ -56,9 +48,6 @@
extern struct list_head g_tiqn_list;
extern spinlock_t tiqn_lock;
-/*
- * Called with cmd->r2t_lock held.
- */
int iscsit_add_r2t_to_list(
struct iscsi_cmd *cmd,
u32 offset,
@@ -68,6 +57,10 @@
{
struct iscsi_r2t *r2t;
+ lockdep_assert_held(&cmd->r2t_lock);
+
+ WARN_ON_ONCE((s32)xfer_len < 0);
+
r2t = kmem_cache_zalloc(lio_r2t_cache, GFP_ATOMIC);
if (!r2t) {
pr_err("Unable to allocate memory for struct iscsi_r2t.\n");
@@ -128,11 +121,10 @@
return NULL;
}
-/*
- * Called with cmd->r2t_lock held.
- */
void iscsit_free_r2t(struct iscsi_r2t *r2t, struct iscsi_cmd *cmd)
{
+ lockdep_assert_held(&cmd->r2t_lock);
+
list_del(&r2t->r2t_list);
kmem_cache_free(lio_r2t_cache, r2t);
}
@@ -150,24 +142,26 @@
static int iscsit_wait_for_tag(struct se_session *se_sess, int state, int *cpup)
{
int tag = -1;
- DEFINE_WAIT(wait);
+ DEFINE_SBQ_WAIT(wait);
struct sbq_wait_state *ws;
+ struct sbitmap_queue *sbq;
if (state == TASK_RUNNING)
return tag;
- ws = &se_sess->sess_tag_pool.ws[0];
+ sbq = &se_sess->sess_tag_pool;
+ ws = &sbq->ws[0];
for (;;) {
- prepare_to_wait_exclusive(&ws->wait, &wait, state);
+ sbitmap_prepare_to_wait(sbq, ws, &wait, state);
if (signal_pending_state(state, current))
break;
- tag = sbitmap_queue_get(&se_sess->sess_tag_pool, cpup);
+ tag = sbitmap_queue_get(sbq, cpup);
if (tag >= 0)
break;
schedule();
}
- finish_wait(&ws->wait, &wait);
+ sbitmap_finish_wait(sbq, ws, &wait);
return tag;
}
@@ -735,6 +729,7 @@
kfree(cmd->pdu_list);
kfree(cmd->seq_list);
kfree(cmd->tmr_req);
+ kfree(cmd->overflow_buf);
kfree(cmd->iov_data);
kfree(cmd->text_in_ptr);
@@ -760,8 +755,8 @@
iscsit_remove_cmd_from_response_queue(cmd, conn);
}
- if (conn && conn->conn_transport->iscsit_release_cmd)
- conn->conn_transport->iscsit_release_cmd(conn, cmd);
+ if (conn && conn->conn_transport->iscsit_unmap_cmd)
+ conn->conn_transport->iscsit_unmap_cmd(conn, cmd);
}
void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
@@ -769,6 +764,8 @@
struct se_cmd *se_cmd = cmd->se_cmd.se_tfo ? &cmd->se_cmd : NULL;
int rc;
+ WARN_ON(!list_empty(&cmd->i_conn_node));
+
__iscsit_free_cmd(cmd, shutdown);
if (se_cmd) {
rc = transport_generic_free_cmd(se_cmd, shutdown);
@@ -915,6 +912,7 @@
void iscsit_handle_nopin_response_timeout(struct timer_list *t)
{
struct iscsi_conn *conn = from_timer(conn, t, nopin_response_timer);
+ struct iscsi_session *sess = conn->sess;
iscsit_inc_conn_usage_count(conn);
@@ -925,28 +923,14 @@
return;
}
- pr_debug("Did not receive response to NOPIN on CID: %hu on"
- " SID: %u, failing connection.\n", conn->cid,
- conn->sess->sid);
+ pr_err("Did not receive response to NOPIN on CID: %hu, failing"
+ " connection for I_T Nexus %s,i,0x%6phN,%s,t,0x%02x\n",
+ conn->cid, sess->sess_ops->InitiatorName, sess->isid,
+ sess->tpg->tpg_tiqn->tiqn, (u32)sess->tpg->tpgt);
conn->nopin_response_timer_flags &= ~ISCSI_TF_RUNNING;
spin_unlock_bh(&conn->nopin_timer_lock);
- {
- struct iscsi_portal_group *tpg = conn->sess->tpg;
- struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
-
- if (tiqn) {
- spin_lock_bh(&tiqn->sess_err_stats.lock);
- strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
- conn->sess->sess_ops->InitiatorName);
- tiqn->sess_err_stats.last_sess_failure_type =
- ISCSI_SESS_ERR_CXN_TIMEOUT;
- tiqn->sess_err_stats.cxn_timeout_errors++;
- atomic_long_inc(&conn->sess->conn_timeout_errors);
- spin_unlock_bh(&tiqn->sess_err_stats.lock);
- }
- }
-
+ iscsit_fill_cxn_timeout_err_stats(sess);
iscsit_cause_connection_reinstatement(conn, 0);
iscsit_dec_conn_usage_count(conn);
}
@@ -967,9 +951,6 @@
spin_unlock_bh(&conn->nopin_timer_lock);
}
-/*
- * Called with conn->nopin_timer_lock held.
- */
void iscsit_start_nopin_response_timer(struct iscsi_conn *conn)
{
struct iscsi_session *sess = conn->sess;
@@ -1027,13 +1008,13 @@
iscsit_dec_conn_usage_count(conn);
}
-/*
- * Called with conn->nopin_timer_lock held.
- */
void __iscsit_start_nopin_timer(struct iscsi_conn *conn)
{
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
+
+ lockdep_assert_held(&conn->nopin_timer_lock);
+
/*
* NOPIN timeout is disabled.
*/
@@ -1258,8 +1239,7 @@
return -1;
memset(&msg, 0, sizeof(struct msghdr));
- iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC,
- count->iov, count->iov_count, data);
+ iov_iter_kvec(&msg.msg_iter, READ, count->iov, count->iov_count, data);
while (msg_data_left(&msg)) {
rx_loop = sock_recvmsg(conn->sock, &msg, MSG_WAITALL);
@@ -1315,8 +1295,7 @@
memset(&msg, 0, sizeof(struct msghdr));
- iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC,
- iov, iov_count, data);
+ iov_iter_kvec(&msg.msg_iter, WRITE, iov, iov_count, data);
while (msg_data_left(&msg)) {
int tx_loop = sock_sendmsg(conn->sock, &msg);
@@ -1405,3 +1384,22 @@
return tpg->tpg_tiqn;
}
+
+void iscsit_fill_cxn_timeout_err_stats(struct iscsi_session *sess)
+{
+ struct iscsi_portal_group *tpg = sess->tpg;
+ struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
+
+ if (!tiqn)
+ return;
+
+ spin_lock_bh(&tiqn->sess_err_stats.lock);
+ strlcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
+ sess->sess_ops->InitiatorName,
+ sizeof(tiqn->sess_err_stats.last_sess_fail_rem_name));
+ tiqn->sess_err_stats.last_sess_failure_type =
+ ISCSI_SESS_ERR_CXN_TIMEOUT;
+ tiqn->sess_err_stats.cxn_timeout_errors++;
+ atomic_long_inc(&sess->conn_timeout_errors);
+ spin_unlock_bh(&tiqn->sess_err_stats.lock);
+}
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
index d66dfc2..68e8480 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -67,5 +67,6 @@
extern int tx_data(struct iscsi_conn *, struct kvec *, int, int);
extern void iscsit_collect_login_stats(struct iscsi_conn *, u8, u8);
extern struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *);
+extern void iscsit_fill_cxn_timeout_err_stats(struct iscsi_session *);
#endif /*** ISCSI_TARGET_UTIL_H ***/