aboutsummaryrefslogtreecommitdiff
path: root/drivers/target/iscsi/iscsi_target_tmr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_tmr.c')
-rw-r--r--drivers/target/iscsi/iscsi_target_tmr.c98
1 files changed, 49 insertions, 49 deletions
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index e01da9d2b37..78404b1cc0b 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -1,9 +1,7 @@
/*******************************************************************************
* This file contains the iSCSI Target specific Task Management functions.
*
- * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
- *
- * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
+ * (c) Copyright 2007-2013 Datera, Inc.
*
* Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
*
@@ -19,9 +17,11 @@
******************************************************************************/
#include <asm/unaligned.h>
+#include <scsi/scsi_device.h>
#include <scsi/iscsi_proto.h>
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>
+#include <target/iscsi/iscsi_transport.h>
#include "iscsi_target_core.h"
#include "iscsi_target_seq_pdu_list.h"
@@ -49,21 +49,20 @@ u8 iscsit_tmr_abort_task(
if (!ref_cmd) {
pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
" %hu.\n", hdr->rtt, conn->cid);
- return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
- (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
+ return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) &&
+ iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ?
ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
}
- if (ref_cmd->cmd_sn != hdr->refcmdsn) {
+ if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
pr_err("RefCmdSN 0x%08x does not equal"
" task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
hdr->refcmdsn, ref_cmd->cmd_sn);
return ISCSI_TMF_RSP_REJECTED;
}
- se_tmr->ref_task_tag = hdr->rtt;
- se_tmr->ref_cmd = &ref_cmd->se_cmd;
- tmr_req->ref_cmd_sn = hdr->refcmdsn;
- tmr_req->exp_data_sn = hdr->exp_datasn;
+ se_tmr->ref_task_tag = (__force u32)hdr->rtt;
+ tmr_req->ref_cmd = ref_cmd;
+ tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
return ISCSI_TMF_RSP_COMPLETE;
}
@@ -78,10 +77,7 @@ int iscsit_tmr_task_warm_reset(
{
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
-#if 0
- struct iscsi_init_task_mgt_cmnd *hdr =
- (struct iscsi_init_task_mgt_cmnd *) buf;
-#endif
+
if (!na->tmr_warm_reset) {
pr_err("TMR Opcode TARGET_WARM_RESET authorization"
" failed for Initiator Node: %s\n",
@@ -124,7 +120,7 @@ u8 iscsit_tmr_task_reassign(
struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
- int ret;
+ int ret, ref_lun;
pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x,"
" RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n",
@@ -148,7 +144,7 @@ u8 iscsit_tmr_task_reassign(
}
/*
* Temporary check to prevent connection recovery for
- * connections with a differing MaxRecvDataSegmentLength.
+ * connections with a differing Max*DataSegmentLength.
*/
if (cr->maxrecvdatasegmentlength !=
conn->conn_ops->MaxRecvDataSegmentLength) {
@@ -157,12 +153,25 @@ u8 iscsit_tmr_task_reassign(
" TMR TASK_REASSIGN.\n");
return ISCSI_TMF_RSP_REJECTED;
}
+ if (cr->maxxmitdatasegmentlength !=
+ conn->conn_ops->MaxXmitDataSegmentLength) {
+ pr_err("Unable to perform connection recovery for"
+ " differing MaxXmitDataSegmentLength, rejecting"
+ " TMR TASK_REASSIGN.\n");
+ return ISCSI_TMF_RSP_REJECTED;
+ }
+
+ ref_lun = scsilun_to_int(&hdr->lun);
+ if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) {
+ pr_err("Unable to perform connection recovery for"
+ " differing ref_lun: %d ref_cmd orig_fe_lun: %u\n",
+ ref_lun, ref_cmd->se_cmd.orig_fe_lun);
+ return ISCSI_TMF_RSP_REJECTED;
+ }
- se_tmr->ref_task_tag = hdr->rtt;
- se_tmr->ref_cmd = &ref_cmd->se_cmd;
- se_tmr->ref_task_lun = get_unaligned_le64(&hdr->lun);
- tmr_req->ref_cmd_sn = hdr->refcmdsn;
- tmr_req->exp_data_sn = hdr->exp_datasn;
+ se_tmr->ref_task_tag = (__force u32)hdr->rtt;
+ tmr_req->ref_cmd = ref_cmd;
+ tmr_req->exp_data_sn = be32_to_cpu(hdr->exp_datasn);
tmr_req->conn_recovery = cr;
tmr_req->task_reassign = 1;
/*
@@ -194,9 +203,7 @@ static int iscsit_task_reassign_complete_nop_out(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
- struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
- struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+ struct iscsi_cmd *cmd = tmr_req->ref_cmd;
struct iscsi_conn_recovery *cr;
if (!cmd->cr) {
@@ -216,7 +223,7 @@ static int iscsit_task_reassign_complete_nop_out(
iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
spin_lock_bh(&conn->cmd_lock);
- list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
+ list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
cmd->i_state = ISTATE_SEND_NOPIN;
@@ -254,7 +261,8 @@ static int iscsit_task_reassign_complete_write(
pr_debug("WRITE ITT: 0x%08x: t_state: %d"
" never sent to transport\n",
cmd->init_task_tag, cmd->se_cmd.t_state);
- return transport_generic_handle_data(se_cmd);
+ target_execute_cmd(se_cmd);
+ return 0;
}
cmd->i_state = ISTATE_SEND_STATUS;
@@ -272,9 +280,9 @@ static int iscsit_task_reassign_complete_write(
offset = cmd->next_burst_len = cmd->write_data_done;
if ((conn->sess->sess_ops->FirstBurstLength - offset) >=
- cmd->data_length) {
+ cmd->se_cmd.data_length) {
no_build_r2ts = 1;
- length = (cmd->data_length - offset);
+ length = (cmd->se_cmd.data_length - offset);
} else
length = (conn->sess->sess_ops->FirstBurstLength - offset);
@@ -292,7 +300,7 @@ static int iscsit_task_reassign_complete_write(
/*
* iscsit_build_r2ts_for_cmd() can handle the rest from here.
*/
- return iscsit_build_r2ts_for_cmd(cmd, conn, 2);
+ return conn->conn_transport->iscsit_get_dataout(conn, cmd, true);
}
static int iscsit_task_reassign_complete_read(
@@ -363,9 +371,7 @@ static int iscsit_task_reassign_complete_scsi_cmnd(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
- struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
- struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+ struct iscsi_cmd *cmd = tmr_req->ref_cmd;
struct iscsi_conn_recovery *cr;
if (!cmd->cr) {
@@ -385,10 +391,10 @@ static int iscsit_task_reassign_complete_scsi_cmnd(
iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
spin_lock_bh(&conn->cmd_lock);
- list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
+ list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
- if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
+ if (cmd->se_cmd.se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
cmd->i_state = ISTATE_SEND_STATUS;
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
return 0;
@@ -414,17 +420,14 @@ static int iscsit_task_reassign_complete(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
- struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
- struct se_cmd *se_cmd;
struct iscsi_cmd *cmd;
int ret = 0;
- if (!se_tmr->ref_cmd) {
+ if (!tmr_req->ref_cmd) {
pr_err("TMR Request is missing a RefCmd struct iscsi_cmd.\n");
return -1;
}
- se_cmd = se_tmr->ref_cmd;
- cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+ cmd = tmr_req->ref_cmd;
cmd->conn = conn;
@@ -456,7 +459,7 @@ static int iscsit_task_reassign_complete(
* Right now the only one that its really needed for is
* connection recovery releated TASK_REASSIGN.
*/
-extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
+int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
{
struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
@@ -467,11 +470,12 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *con
return 0;
}
+EXPORT_SYMBOL(iscsit_tmr_post_handler);
/*
* Nothing to do here, but leave it for good measure. :-)
*/
-int iscsit_task_reassign_prepare_read(
+static int iscsit_task_reassign_prepare_read(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
@@ -546,13 +550,11 @@ static void iscsit_task_reassign_prepare_unsolicited_dataout(
}
}
-int iscsit_task_reassign_prepare_write(
+static int iscsit_task_reassign_prepare_write(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
- struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
- struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+ struct iscsi_cmd *cmd = tmr_req->ref_cmd;
struct iscsi_pdu *pdu = NULL;
struct iscsi_r2t *r2t = NULL, *r2t_tmp;
int first_incomplete_r2t = 1, i = 0;
@@ -785,14 +787,12 @@ int iscsit_check_task_reassign_expdatasn(
struct iscsi_tmr_req *tmr_req,
struct iscsi_conn *conn)
{
- struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
- struct se_cmd *se_cmd = se_tmr->ref_cmd;
- struct iscsi_cmd *ref_cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
+ struct iscsi_cmd *ref_cmd = tmr_req->ref_cmd;
if (ref_cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD)
return 0;
- if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
+ if (ref_cmd->se_cmd.se_cmd_flags & SCF_SENT_CHECK_CONDITION)
return 0;
if (ref_cmd->data_direction == DMA_NONE)