diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_erl0.c')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 128 |
1 files changed, 67 insertions, 61 deletions
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 1a02016ecda..0d1e6ee3e99 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -2,9 +2,7 @@ * This file contains error recovery level zero functions used by * the iSCSI Target driver. * - * \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> * @@ -48,9 +46,9 @@ void iscsit_set_dataout_sequence_values( if (cmd->unsolicited_data) { cmd->seq_start_offset = cmd->write_data_done; cmd->seq_end_offset = (cmd->write_data_done + - (cmd->se_cmd.data_length > - conn->sess->sess_ops->FirstBurstLength) ? - conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length); + ((cmd->se_cmd.data_length > + conn->sess->sess_ops->FirstBurstLength) ? + conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length)); return; } @@ -95,14 +93,15 @@ static int iscsit_dataout_within_command_recovery_check( */ if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) && - (cmd->write_data_done != hdr->offset)) + cmd->write_data_done != be32_to_cpu(hdr->offset)) goto dump; cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY; } else { struct iscsi_seq *seq; - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -111,15 +110,15 @@ static int iscsit_dataout_within_command_recovery_check( cmd->seq_ptr = seq; if (conn->sess->sess_ops->DataPDUInOrder) { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - ((seq->offset != hdr->offset) || - (seq->data_sn != hdr->datasn))) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + (seq->offset != be32_to_cpu(hdr->offset) || + seq->data_sn != be32_to_cpu(hdr->datasn))) goto dump; } else { - if ((seq->status == - DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) && - (seq->data_sn != hdr->datasn)) + if (seq->status == + DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY && + seq->data_sn != be32_to_cpu(hdr->datasn)) goto dump; } @@ -148,12 +147,12 @@ static int iscsit_dataout_check_unsolicited_sequence( u32 payload_length = ntoh24(hdr->dlength); - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Unsolicited Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); return DATAOUT_CANNOT_RECOVER; } @@ -236,12 +235,12 @@ static int iscsit_dataout_check_sequence( * fullfilling an Recovery R2T, it's best to just dump the * payload here, instead of erroring out. */ - if ((hdr->offset < cmd->seq_start_offset) || - ((hdr->offset + payload_length) > cmd->seq_end_offset)) { + if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) || + ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) { pr_err("Command ITT: 0x%08x with Offset: %u," " Length: %u outside of Sequence %u:%u while" " DataSequenceInOrder=Yes.\n", cmd->init_task_tag, - hdr->offset, payload_length, cmd->seq_start_offset, + be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset, cmd->seq_end_offset); if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) @@ -251,7 +250,8 @@ static int iscsit_dataout_check_sequence( next_burst_len = (cmd->next_burst_len + payload_length); } else { - seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length); + seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!seq) return DATAOUT_CANNOT_RECOVER; /* @@ -366,16 +366,16 @@ static int iscsit_dataout_check_datasn( data_sn = seq->data_sn; } - if (hdr->datasn > data_sn) { + if (be32_to_cpu(hdr->datasn) > data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " higher than expected 0x%08x.\n", cmd->init_task_tag, - hdr->datasn, data_sn); + be32_to_cpu(hdr->datasn), data_sn); recovery = 1; goto recover; - } else if (hdr->datasn < data_sn) { + } else if (be32_to_cpu(hdr->datasn) < data_sn) { pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x" " lower than expected 0x%08x, discarding payload.\n", - cmd->init_task_tag, hdr->datasn, data_sn); + cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn); dump = 1; goto dump; } @@ -408,33 +408,34 @@ static int iscsit_dataout_pre_datapduinorder_yes( /* * For DataSequenceInOrder=Yes: If the offset is greater than the global * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has - * occured and fail the connection. + * occurred and fail the connection. * * For DataSequenceInOrder=No: If the offset is greater than the per * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol - * error has occured and fail the connection. + * error has occurred and fail the connection. */ if (conn->sess->sess_ops->DataSequenceInOrder) { - if (hdr->offset != cmd->write_data_done) { + if (be32_to_cpu(hdr->offset) != cmd->write_data_done) { pr_err("Command ITT: 0x%08x, received offset" " %u different than expected %u.\n", cmd->init_task_tag, - hdr->offset, cmd->write_data_done); + be32_to_cpu(hdr->offset), cmd->write_data_done); recovery = 1; goto recover; } } else { struct iscsi_seq *seq = cmd->seq_ptr; - if (hdr->offset > seq->offset) { + if (be32_to_cpu(hdr->offset) > seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u greater than expected %u.\n", cmd->init_task_tag, - hdr->offset, seq->offset); + be32_to_cpu(hdr->offset), seq->offset); recovery = 1; goto recover; - } else if (hdr->offset < seq->offset) { + } else if (be32_to_cpu(hdr->offset) < seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u less than expected %u, discarding payload.\n", - cmd->init_task_tag, hdr->offset, seq->offset); + cmd->init_task_tag, be32_to_cpu(hdr->offset), + seq->offset); dump = 1; goto dump; } @@ -453,7 +454,7 @@ dump: return DATAOUT_CANNOT_RECOVER; return (recovery) ? iscsit_recover_dataout_sequence(cmd, - hdr->offset, payload_length) : + be32_to_cpu(hdr->offset), payload_length) : (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL; } @@ -465,7 +466,8 @@ static int iscsit_dataout_pre_datapduinorder_no( struct iscsi_data *hdr = (struct iscsi_data *) buf; u32 payload_length = ntoh24(hdr->dlength); - pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length); + pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset), + payload_length); if (!pdu) return DATAOUT_CANNOT_RECOVER; @@ -479,7 +481,7 @@ static int iscsit_dataout_pre_datapduinorder_no( case ISCSI_PDU_RECEIVED_OK: pr_err("Command ITT: 0x%08x received already gotten" " Offset: %u, Length: %u\n", cmd->init_task_tag, - hdr->offset, payload_length); + be32_to_cpu(hdr->offset), payload_length); return iscsit_dump_data_payload(cmd->conn, payload_length, 1); default: return DATAOUT_CANNOT_RECOVER; @@ -553,7 +555,7 @@ static int iscsit_dataout_post_crc_passed( if (cmd->unsolicited_data) { if ((cmd->first_burst_len + payload_length) == conn->sess->sess_ops->FirstBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -561,7 +563,8 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no(cmd, - hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL)); + be32_to_cpu(hdr->datasn), + (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; } @@ -586,7 +589,8 @@ static int iscsit_dataout_post_crc_passed( if (conn->sess->sess_ops->DataSequenceInOrder) { if ((cmd->next_burst_len + payload_length) == conn->sess->sess_ops->MaxBurstLength) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -594,7 +598,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -610,7 +614,8 @@ static int iscsit_dataout_post_crc_passed( if ((seq->next_burst_len + payload_length) == seq->xfer_len) { - if (iscsit_dataout_update_r2t(cmd, hdr->offset, + if (iscsit_dataout_update_r2t(cmd, + be32_to_cpu(hdr->offset), payload_length) < 0) return DATAOUT_CANNOT_RECOVER; send_r2t = 1; @@ -618,7 +623,7 @@ static int iscsit_dataout_post_crc_passed( if (!conn->sess->sess_ops->DataPDUInOrder) { ret = iscsit_dataout_update_datapduinorder_no( - cmd, hdr->datasn, + cmd, be32_to_cpu(hdr->datasn), (hdr->flags & ISCSI_FLAG_CMD_FINAL)); if (ret == DATAOUT_CANNOT_RECOVER) return ret; @@ -678,14 +683,15 @@ static int iscsit_dataout_post_crc_failed( } recover: - return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length); + return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset), + payload_length); } /* * Called from iscsit_handle_data_out() before DataOUT Payload is received * and CRC computed. */ -extern int iscsit_check_pre_dataout( +int iscsit_check_pre_dataout( struct iscsi_cmd *cmd, unsigned char *buf) { @@ -738,13 +744,12 @@ int iscsit_check_post_dataout( if (!conn->sess->sess_ops->ErrorRecoveryLevel) { pr_err("Unable to recover from DataOUT CRC" " failure while ERL=0, closing session.\n"); - iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, - 1, 0, buf, cmd); + iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, + buf); return DATAOUT_CANNOT_RECOVER; } - iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, - 0, 0, buf, cmd); + iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf); return iscsit_dataout_post_crc_failed(cmd, buf); } } @@ -752,7 +757,7 @@ int iscsit_check_post_dataout( static void iscsit_handle_time2retain_timeout(unsigned long data) { struct iscsi_session *sess = (struct iscsi_session *) data; - struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); + struct iscsi_portal_group *tpg = sess->tpg; struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; spin_lock_bh(&se_tpg->session_lock); @@ -780,7 +785,7 @@ static void iscsit_handle_time2retain_timeout(unsigned long data) tiqn->sess_err_stats.last_sess_failure_type = ISCSI_SESS_ERR_CXN_TIMEOUT; tiqn->sess_err_stats.cxn_timeout_errors++; - sess->conn_timeout_errors++; + atomic_long_inc(&sess->conn_timeout_errors); spin_unlock(&tiqn->sess_err_stats.lock); } } @@ -789,16 +794,16 @@ static void iscsit_handle_time2retain_timeout(unsigned long data) target_put_session(sess->se_sess); } -extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) +void iscsit_start_time2retain_handler(struct iscsi_session *sess) { int tpg_active; /* - * Only start Time2Retain timer when the assoicated TPG is still in + * Only start Time2Retain timer when the associated TPG is still in * an ACTIVE (eg: not disabled or shutdown) state. */ - spin_lock(&ISCSI_TPG_S(sess)->tpg_state_lock); - tpg_active = (ISCSI_TPG_S(sess)->tpg_state == TPG_STATE_ACTIVE); - spin_unlock(&ISCSI_TPG_S(sess)->tpg_state_lock); + spin_lock(&sess->tpg->tpg_state_lock); + tpg_active = (sess->tpg->tpg_state == TPG_STATE_ACTIVE); + spin_unlock(&sess->tpg->tpg_state_lock); if (!tpg_active) return; @@ -822,9 +827,9 @@ extern void iscsit_start_time2retain_handler(struct iscsi_session *sess) /* * Called with spin_lock_bh(&struct se_portal_group->session_lock) held */ -extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess) +int iscsit_stop_time2retain_timer(struct iscsi_session *sess) { - struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); + struct iscsi_portal_group *tpg = sess->tpg; struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED) @@ -834,11 +839,11 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess) return 0; sess->time2retain_timer_flags |= ISCSI_TF_STOP; - spin_unlock_bh(&se_tpg->session_lock); + spin_unlock(&se_tpg->session_lock); del_timer_sync(&sess->time2retain_timer); - spin_lock_bh(&se_tpg->session_lock); + spin_lock(&se_tpg->session_lock); sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; pr_debug("Stopped Time2Retain Timer for SID: %u\n", sess->sid); @@ -901,6 +906,7 @@ void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep) wait_for_completion(&conn->conn_wait_comp); complete(&conn->conn_post_wait_comp); } +EXPORT_SYMBOL(iscsit_cause_connection_reinstatement); void iscsit_fall_back_to_erl0(struct iscsi_session *sess) { @@ -926,7 +932,7 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn) } } -extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) +void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn) { spin_lock_bh(&conn->state_lock); if (atomic_read(&conn->connection_exit)) { |
