Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /******************************************************************************
0003  * This file contains error recovery level zero functions used by
0004  * the iSCSI Target driver.
0005  *
0006  * (c) Copyright 2007-2013 Datera, Inc.
0007  *
0008  * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
0009  *
0010  ******************************************************************************/
0011 
0012 #include <linux/sched/signal.h>
0013 
0014 #include <scsi/iscsi_proto.h>
0015 #include <target/target_core_base.h>
0016 #include <target/target_core_fabric.h>
0017 
0018 #include <target/iscsi/iscsi_target_core.h>
0019 #include "iscsi_target_seq_pdu_list.h"
0020 #include "iscsi_target_erl0.h"
0021 #include "iscsi_target_erl1.h"
0022 #include "iscsi_target_erl2.h"
0023 #include "iscsi_target_util.h"
0024 #include "iscsi_target.h"
0025 
0026 /*
0027  *  Used to set values in struct iscsit_cmd that iscsit_dataout_check_sequence()
0028  *  checks against to determine a PDU's Offset+Length is within the current
0029  *  DataOUT Sequence.  Used for DataSequenceInOrder=Yes only.
0030  */
0031 void iscsit_set_dataout_sequence_values(
0032     struct iscsit_cmd *cmd)
0033 {
0034     struct iscsit_conn *conn = cmd->conn;
0035     /*
0036      * Still set seq_start_offset and seq_end_offset for Unsolicited
0037      * DataOUT, even if DataSequenceInOrder=No.
0038      */
0039     if (cmd->unsolicited_data) {
0040         cmd->seq_start_offset = cmd->write_data_done;
0041         cmd->seq_end_offset = min(cmd->se_cmd.data_length,
0042                     conn->sess->sess_ops->FirstBurstLength);
0043         return;
0044     }
0045 
0046     if (!conn->sess->sess_ops->DataSequenceInOrder)
0047         return;
0048 
0049     if (!cmd->seq_start_offset && !cmd->seq_end_offset) {
0050         cmd->seq_start_offset = cmd->write_data_done;
0051         cmd->seq_end_offset = (cmd->se_cmd.data_length >
0052             conn->sess->sess_ops->MaxBurstLength) ?
0053             (cmd->write_data_done +
0054             conn->sess->sess_ops->MaxBurstLength) : cmd->se_cmd.data_length;
0055     } else {
0056         cmd->seq_start_offset = cmd->seq_end_offset;
0057         cmd->seq_end_offset = ((cmd->seq_end_offset +
0058             conn->sess->sess_ops->MaxBurstLength) >=
0059             cmd->se_cmd.data_length) ? cmd->se_cmd.data_length :
0060             (cmd->seq_end_offset +
0061              conn->sess->sess_ops->MaxBurstLength);
0062     }
0063 }
0064 
0065 static int iscsit_dataout_within_command_recovery_check(
0066     struct iscsit_cmd *cmd,
0067     unsigned char *buf)
0068 {
0069     struct iscsit_conn *conn = cmd->conn;
0070     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0071     u32 payload_length = ntoh24(hdr->dlength);
0072 
0073     /*
0074      * We do the within-command recovery checks here as it is
0075      * the first function called in iscsi_check_pre_dataout().
0076      * Basically, if we are in within-command recovery and
0077      * the PDU does not contain the offset the sequence needs,
0078      * dump the payload.
0079      *
0080      * This only applies to DataPDUInOrder=Yes, for
0081      * DataPDUInOrder=No we only re-request the failed PDU
0082      * and check that all PDUs in a sequence are received
0083      * upon end of sequence.
0084      */
0085     if (conn->sess->sess_ops->DataSequenceInOrder) {
0086         if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
0087             cmd->write_data_done != be32_to_cpu(hdr->offset))
0088             goto dump;
0089 
0090         cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
0091     } else {
0092         struct iscsi_seq *seq;
0093 
0094         seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
0095                         payload_length);
0096         if (!seq)
0097             return DATAOUT_CANNOT_RECOVER;
0098         /*
0099          * Set the struct iscsi_seq pointer to reuse later.
0100          */
0101         cmd->seq_ptr = seq;
0102 
0103         if (conn->sess->sess_ops->DataPDUInOrder) {
0104             if (seq->status ==
0105                 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
0106                (seq->offset != be32_to_cpu(hdr->offset) ||
0107                 seq->data_sn != be32_to_cpu(hdr->datasn)))
0108                 goto dump;
0109         } else {
0110             if (seq->status ==
0111                  DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
0112                 seq->data_sn != be32_to_cpu(hdr->datasn))
0113                 goto dump;
0114         }
0115 
0116         if (seq->status == DATAOUT_SEQUENCE_COMPLETE)
0117             goto dump;
0118 
0119         if (seq->status != DATAOUT_SEQUENCE_COMPLETE)
0120             seq->status = 0;
0121     }
0122 
0123     return DATAOUT_NORMAL;
0124 
0125 dump:
0126     pr_err("Dumping DataOUT PDU Offset: %u Length: %d DataSN:"
0127         " 0x%08x\n", hdr->offset, payload_length, hdr->datasn);
0128     return iscsit_dump_data_payload(conn, payload_length, 1);
0129 }
0130 
0131 static int iscsit_dataout_check_unsolicited_sequence(
0132     struct iscsit_cmd *cmd,
0133     unsigned char *buf)
0134 {
0135     u32 first_burst_len;
0136     struct iscsit_conn *conn = cmd->conn;
0137     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0138     u32 payload_length = ntoh24(hdr->dlength);
0139 
0140 
0141     if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
0142        ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
0143         pr_err("Command ITT: 0x%08x with Offset: %u,"
0144         " Length: %u outside of Unsolicited Sequence %u:%u while"
0145         " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
0146         be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
0147             cmd->seq_end_offset);
0148         return DATAOUT_CANNOT_RECOVER;
0149     }
0150 
0151     first_burst_len = (cmd->first_burst_len + payload_length);
0152 
0153     if (first_burst_len > conn->sess->sess_ops->FirstBurstLength) {
0154         pr_err("Total %u bytes exceeds FirstBurstLength: %u"
0155             " for this Unsolicited DataOut Burst.\n",
0156             first_burst_len, conn->sess->sess_ops->FirstBurstLength);
0157         transport_send_check_condition_and_sense(&cmd->se_cmd,
0158                 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
0159         return DATAOUT_CANNOT_RECOVER;
0160     }
0161 
0162     /*
0163      * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
0164      * checks for the current Unsolicited DataOUT Sequence.
0165      */
0166     if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
0167         /*
0168          * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
0169          * sequence checks are handled in
0170          * iscsit_dataout_datapduinorder_no_fbit().
0171          */
0172         if (!conn->sess->sess_ops->DataPDUInOrder)
0173             goto out;
0174 
0175         if ((first_burst_len != cmd->se_cmd.data_length) &&
0176             (first_burst_len != conn->sess->sess_ops->FirstBurstLength)) {
0177             pr_err("Unsolicited non-immediate data"
0178             " received %u does not equal FirstBurstLength: %u, and"
0179             " does not equal ExpXferLen %u.\n", first_burst_len,
0180                 conn->sess->sess_ops->FirstBurstLength,
0181                 cmd->se_cmd.data_length);
0182             transport_send_check_condition_and_sense(&cmd->se_cmd,
0183                     TCM_INCORRECT_AMOUNT_OF_DATA, 0);
0184             return DATAOUT_CANNOT_RECOVER;
0185         }
0186     } else {
0187         if (first_burst_len == conn->sess->sess_ops->FirstBurstLength) {
0188             pr_err("Command ITT: 0x%08x reached"
0189             " FirstBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
0190                 " error.\n", cmd->init_task_tag,
0191                 conn->sess->sess_ops->FirstBurstLength);
0192             return DATAOUT_CANNOT_RECOVER;
0193         }
0194         if (first_burst_len == cmd->se_cmd.data_length) {
0195             pr_err("Command ITT: 0x%08x reached"
0196             " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
0197             " error.\n", cmd->init_task_tag, cmd->se_cmd.data_length);
0198             return DATAOUT_CANNOT_RECOVER;
0199         }
0200     }
0201 
0202 out:
0203     return DATAOUT_NORMAL;
0204 }
0205 
0206 static int iscsit_dataout_check_sequence(
0207     struct iscsit_cmd *cmd,
0208     unsigned char *buf)
0209 {
0210     u32 next_burst_len;
0211     struct iscsit_conn *conn = cmd->conn;
0212     struct iscsi_seq *seq = NULL;
0213     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0214     u32 payload_length = ntoh24(hdr->dlength);
0215 
0216     /*
0217      * For DataSequenceInOrder=Yes: Check that the offset and offset+length
0218      * is within range as defined by iscsi_set_dataout_sequence_values().
0219      *
0220      * For DataSequenceInOrder=No: Check that an struct iscsi_seq exists for
0221      * offset+length tuple.
0222      */
0223     if (conn->sess->sess_ops->DataSequenceInOrder) {
0224         /*
0225          * Due to possibility of recovery DataOUT sent by the initiator
0226          * fullfilling an Recovery R2T, it's best to just dump the
0227          * payload here, instead of erroring out.
0228          */
0229         if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
0230            ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
0231             pr_err("Command ITT: 0x%08x with Offset: %u,"
0232             " Length: %u outside of Sequence %u:%u while"
0233             " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
0234             be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
0235                 cmd->seq_end_offset);
0236 
0237             if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
0238                 return DATAOUT_CANNOT_RECOVER;
0239             return DATAOUT_WITHIN_COMMAND_RECOVERY;
0240         }
0241 
0242         next_burst_len = (cmd->next_burst_len + payload_length);
0243     } else {
0244         seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
0245                         payload_length);
0246         if (!seq)
0247             return DATAOUT_CANNOT_RECOVER;
0248         /*
0249          * Set the struct iscsi_seq pointer to reuse later.
0250          */
0251         cmd->seq_ptr = seq;
0252 
0253         if (seq->status == DATAOUT_SEQUENCE_COMPLETE) {
0254             if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
0255                 return DATAOUT_CANNOT_RECOVER;
0256             return DATAOUT_WITHIN_COMMAND_RECOVERY;
0257         }
0258 
0259         next_burst_len = (seq->next_burst_len + payload_length);
0260     }
0261 
0262     if (next_burst_len > conn->sess->sess_ops->MaxBurstLength) {
0263         pr_err("Command ITT: 0x%08x, NextBurstLength: %u and"
0264             " Length: %u exceeds MaxBurstLength: %u. protocol"
0265             " error.\n", cmd->init_task_tag,
0266             (next_burst_len - payload_length),
0267             payload_length, conn->sess->sess_ops->MaxBurstLength);
0268         return DATAOUT_CANNOT_RECOVER;
0269     }
0270 
0271     /*
0272      * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
0273      * checks for the current DataOUT Sequence.
0274      */
0275     if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
0276         /*
0277          * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
0278          * sequence checks are handled in
0279          * iscsit_dataout_datapduinorder_no_fbit().
0280          */
0281         if (!conn->sess->sess_ops->DataPDUInOrder)
0282             goto out;
0283 
0284         if (conn->sess->sess_ops->DataSequenceInOrder) {
0285             if ((next_burst_len <
0286                  conn->sess->sess_ops->MaxBurstLength) &&
0287                ((cmd->write_data_done + payload_length) <
0288                  cmd->se_cmd.data_length)) {
0289                 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
0290                 " before end of DataOUT sequence, protocol"
0291                 " error.\n", cmd->init_task_tag);
0292                 return DATAOUT_CANNOT_RECOVER;
0293             }
0294         } else {
0295             if (next_burst_len < seq->xfer_len) {
0296                 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
0297                 " before end of DataOUT sequence, protocol"
0298                 " error.\n", cmd->init_task_tag);
0299                 return DATAOUT_CANNOT_RECOVER;
0300             }
0301         }
0302     } else {
0303         if (conn->sess->sess_ops->DataSequenceInOrder) {
0304             if (next_burst_len ==
0305                     conn->sess->sess_ops->MaxBurstLength) {
0306                 pr_err("Command ITT: 0x%08x reached"
0307                 " MaxBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is"
0308                 " not set, protocol error.", cmd->init_task_tag,
0309                     conn->sess->sess_ops->MaxBurstLength);
0310                 return DATAOUT_CANNOT_RECOVER;
0311             }
0312             if ((cmd->write_data_done + payload_length) ==
0313                     cmd->se_cmd.data_length) {
0314                 pr_err("Command ITT: 0x%08x reached"
0315                 " last DataOUT PDU in sequence but ISCSI_FLAG_"
0316                 "CMD_FINAL is not set, protocol error.\n",
0317                     cmd->init_task_tag);
0318                 return DATAOUT_CANNOT_RECOVER;
0319             }
0320         } else {
0321             if (next_burst_len == seq->xfer_len) {
0322                 pr_err("Command ITT: 0x%08x reached"
0323                 " last DataOUT PDU in sequence but ISCSI_FLAG_"
0324                 "CMD_FINAL is not set, protocol error.\n",
0325                     cmd->init_task_tag);
0326                 return DATAOUT_CANNOT_RECOVER;
0327             }
0328         }
0329     }
0330 
0331 out:
0332     return DATAOUT_NORMAL;
0333 }
0334 
0335 static int iscsit_dataout_check_datasn(
0336     struct iscsit_cmd *cmd,
0337     unsigned char *buf)
0338 {
0339     u32 data_sn = 0;
0340     struct iscsit_conn *conn = cmd->conn;
0341     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0342     u32 payload_length = ntoh24(hdr->dlength);
0343 
0344     /*
0345      * Considering the target has no method of re-requesting DataOUT
0346      * by DataSN, if we receieve a greater DataSN than expected we
0347      * assume the functions for DataPDUInOrder=[Yes,No] below will
0348      * handle it.
0349      *
0350      * If the DataSN is less than expected, dump the payload.
0351      */
0352     if (conn->sess->sess_ops->DataSequenceInOrder)
0353         data_sn = cmd->data_sn;
0354     else {
0355         struct iscsi_seq *seq = cmd->seq_ptr;
0356         data_sn = seq->data_sn;
0357     }
0358 
0359     if (be32_to_cpu(hdr->datasn) > data_sn) {
0360         pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
0361             " higher than expected 0x%08x.\n", cmd->init_task_tag,
0362                 be32_to_cpu(hdr->datasn), data_sn);
0363         goto recover;
0364     } else if (be32_to_cpu(hdr->datasn) < data_sn) {
0365         pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
0366             " lower than expected 0x%08x, discarding payload.\n",
0367             cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
0368         goto dump;
0369     }
0370 
0371     return DATAOUT_NORMAL;
0372 
0373 recover:
0374     if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
0375         pr_err("Unable to perform within-command recovery"
0376                 " while ERL=0.\n");
0377         return DATAOUT_CANNOT_RECOVER;
0378     }
0379 dump:
0380     if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
0381         return DATAOUT_CANNOT_RECOVER;
0382 
0383     return DATAOUT_WITHIN_COMMAND_RECOVERY;
0384 }
0385 
0386 static int iscsit_dataout_pre_datapduinorder_yes(
0387     struct iscsit_cmd *cmd,
0388     unsigned char *buf)
0389 {
0390     int dump = 0, recovery = 0;
0391     struct iscsit_conn *conn = cmd->conn;
0392     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0393     u32 payload_length = ntoh24(hdr->dlength);
0394 
0395     /*
0396      * For DataSequenceInOrder=Yes: If the offset is greater than the global
0397      * DataPDUInOrder=Yes offset counter in struct iscsit_cmd a protcol error has
0398      * occurred and fail the connection.
0399      *
0400      * For DataSequenceInOrder=No: If the offset is greater than the per
0401      * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
0402      * error has occurred and fail the connection.
0403      */
0404     if (conn->sess->sess_ops->DataSequenceInOrder) {
0405         if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
0406             pr_err("Command ITT: 0x%08x, received offset"
0407             " %u different than expected %u.\n", cmd->init_task_tag,
0408                 be32_to_cpu(hdr->offset), cmd->write_data_done);
0409             recovery = 1;
0410             goto recover;
0411         }
0412     } else {
0413         struct iscsi_seq *seq = cmd->seq_ptr;
0414 
0415         if (be32_to_cpu(hdr->offset) > seq->offset) {
0416             pr_err("Command ITT: 0x%08x, received offset"
0417             " %u greater than expected %u.\n", cmd->init_task_tag,
0418                 be32_to_cpu(hdr->offset), seq->offset);
0419             recovery = 1;
0420             goto recover;
0421         } else if (be32_to_cpu(hdr->offset) < seq->offset) {
0422             pr_err("Command ITT: 0x%08x, received offset"
0423             " %u less than expected %u, discarding payload.\n",
0424                 cmd->init_task_tag, be32_to_cpu(hdr->offset),
0425                 seq->offset);
0426             dump = 1;
0427             goto dump;
0428         }
0429     }
0430 
0431     return DATAOUT_NORMAL;
0432 
0433 recover:
0434     if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
0435         pr_err("Unable to perform within-command recovery"
0436                 " while ERL=0.\n");
0437         return DATAOUT_CANNOT_RECOVER;
0438     }
0439 dump:
0440     if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
0441         return DATAOUT_CANNOT_RECOVER;
0442 
0443     return (recovery) ? iscsit_recover_dataout_sequence(cmd,
0444         be32_to_cpu(hdr->offset), payload_length) :
0445            (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
0446 }
0447 
0448 static int iscsit_dataout_pre_datapduinorder_no(
0449     struct iscsit_cmd *cmd,
0450     unsigned char *buf)
0451 {
0452     struct iscsi_pdu *pdu;
0453     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0454     u32 payload_length = ntoh24(hdr->dlength);
0455 
0456     pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
0457                     payload_length);
0458     if (!pdu)
0459         return DATAOUT_CANNOT_RECOVER;
0460 
0461     cmd->pdu_ptr = pdu;
0462 
0463     switch (pdu->status) {
0464     case ISCSI_PDU_NOT_RECEIVED:
0465     case ISCSI_PDU_CRC_FAILED:
0466     case ISCSI_PDU_TIMED_OUT:
0467         break;
0468     case ISCSI_PDU_RECEIVED_OK:
0469         pr_err("Command ITT: 0x%08x received already gotten"
0470             " Offset: %u, Length: %u\n", cmd->init_task_tag,
0471                 be32_to_cpu(hdr->offset), payload_length);
0472         return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
0473     default:
0474         return DATAOUT_CANNOT_RECOVER;
0475     }
0476 
0477     return DATAOUT_NORMAL;
0478 }
0479 
0480 static int iscsit_dataout_update_r2t(struct iscsit_cmd *cmd, u32 offset, u32 length)
0481 {
0482     struct iscsi_r2t *r2t;
0483 
0484     if (cmd->unsolicited_data)
0485         return 0;
0486 
0487     r2t = iscsit_get_r2t_for_eos(cmd, offset, length);
0488     if (!r2t)
0489         return -1;
0490 
0491     spin_lock_bh(&cmd->r2t_lock);
0492     r2t->seq_complete = 1;
0493     cmd->outstanding_r2ts--;
0494     spin_unlock_bh(&cmd->r2t_lock);
0495 
0496     return 0;
0497 }
0498 
0499 static int iscsit_dataout_update_datapduinorder_no(
0500     struct iscsit_cmd *cmd,
0501     u32 data_sn,
0502     int f_bit)
0503 {
0504     int ret = 0;
0505     struct iscsi_pdu *pdu = cmd->pdu_ptr;
0506 
0507     pdu->data_sn = data_sn;
0508 
0509     switch (pdu->status) {
0510     case ISCSI_PDU_NOT_RECEIVED:
0511         pdu->status = ISCSI_PDU_RECEIVED_OK;
0512         break;
0513     case ISCSI_PDU_CRC_FAILED:
0514         pdu->status = ISCSI_PDU_RECEIVED_OK;
0515         break;
0516     case ISCSI_PDU_TIMED_OUT:
0517         pdu->status = ISCSI_PDU_RECEIVED_OK;
0518         break;
0519     default:
0520         return DATAOUT_CANNOT_RECOVER;
0521     }
0522 
0523     if (f_bit) {
0524         ret = iscsit_dataout_datapduinorder_no_fbit(cmd, pdu);
0525         if (ret == DATAOUT_CANNOT_RECOVER)
0526             return ret;
0527     }
0528 
0529     return DATAOUT_NORMAL;
0530 }
0531 
0532 static int iscsit_dataout_post_crc_passed(
0533     struct iscsit_cmd *cmd,
0534     unsigned char *buf)
0535 {
0536     int ret, send_r2t = 0;
0537     struct iscsit_conn *conn = cmd->conn;
0538     struct iscsi_seq *seq = NULL;
0539     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0540     u32 payload_length = ntoh24(hdr->dlength);
0541 
0542     if (cmd->unsolicited_data) {
0543         if ((cmd->first_burst_len + payload_length) ==
0544              conn->sess->sess_ops->FirstBurstLength) {
0545             if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
0546                     payload_length) < 0)
0547                 return DATAOUT_CANNOT_RECOVER;
0548             send_r2t = 1;
0549         }
0550 
0551         if (!conn->sess->sess_ops->DataPDUInOrder) {
0552             ret = iscsit_dataout_update_datapduinorder_no(cmd,
0553                 be32_to_cpu(hdr->datasn),
0554                 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
0555             if (ret == DATAOUT_CANNOT_RECOVER)
0556                 return ret;
0557         }
0558 
0559         cmd->first_burst_len += payload_length;
0560 
0561         if (conn->sess->sess_ops->DataSequenceInOrder)
0562             cmd->data_sn++;
0563         else {
0564             seq = cmd->seq_ptr;
0565             seq->data_sn++;
0566             seq->offset += payload_length;
0567         }
0568 
0569         if (send_r2t) {
0570             if (seq)
0571                 seq->status = DATAOUT_SEQUENCE_COMPLETE;
0572             cmd->first_burst_len = 0;
0573             cmd->unsolicited_data = 0;
0574         }
0575     } else {
0576         if (conn->sess->sess_ops->DataSequenceInOrder) {
0577             if ((cmd->next_burst_len + payload_length) ==
0578                  conn->sess->sess_ops->MaxBurstLength) {
0579                 if (iscsit_dataout_update_r2t(cmd,
0580                         be32_to_cpu(hdr->offset),
0581                         payload_length) < 0)
0582                     return DATAOUT_CANNOT_RECOVER;
0583                 send_r2t = 1;
0584             }
0585 
0586             if (!conn->sess->sess_ops->DataPDUInOrder) {
0587                 ret = iscsit_dataout_update_datapduinorder_no(
0588                         cmd, be32_to_cpu(hdr->datasn),
0589                         (hdr->flags & ISCSI_FLAG_CMD_FINAL));
0590                 if (ret == DATAOUT_CANNOT_RECOVER)
0591                     return ret;
0592             }
0593 
0594             cmd->next_burst_len += payload_length;
0595             cmd->data_sn++;
0596 
0597             if (send_r2t)
0598                 cmd->next_burst_len = 0;
0599         } else {
0600             seq = cmd->seq_ptr;
0601 
0602             if ((seq->next_burst_len + payload_length) ==
0603                  seq->xfer_len) {
0604                 if (iscsit_dataout_update_r2t(cmd,
0605                         be32_to_cpu(hdr->offset),
0606                         payload_length) < 0)
0607                     return DATAOUT_CANNOT_RECOVER;
0608                 send_r2t = 1;
0609             }
0610 
0611             if (!conn->sess->sess_ops->DataPDUInOrder) {
0612                 ret = iscsit_dataout_update_datapduinorder_no(
0613                         cmd, be32_to_cpu(hdr->datasn),
0614                         (hdr->flags & ISCSI_FLAG_CMD_FINAL));
0615                 if (ret == DATAOUT_CANNOT_RECOVER)
0616                     return ret;
0617             }
0618 
0619             seq->data_sn++;
0620             seq->offset += payload_length;
0621             seq->next_burst_len += payload_length;
0622 
0623             if (send_r2t) {
0624                 seq->next_burst_len = 0;
0625                 seq->status = DATAOUT_SEQUENCE_COMPLETE;
0626             }
0627         }
0628     }
0629 
0630     if (send_r2t && conn->sess->sess_ops->DataSequenceInOrder)
0631         cmd->data_sn = 0;
0632 
0633     cmd->write_data_done += payload_length;
0634 
0635     if (cmd->write_data_done == cmd->se_cmd.data_length)
0636         return DATAOUT_SEND_TO_TRANSPORT;
0637     else if (send_r2t)
0638         return DATAOUT_SEND_R2T;
0639     else
0640         return DATAOUT_NORMAL;
0641 }
0642 
0643 static int iscsit_dataout_post_crc_failed(
0644     struct iscsit_cmd *cmd,
0645     unsigned char *buf)
0646 {
0647     struct iscsit_conn *conn = cmd->conn;
0648     struct iscsi_pdu *pdu;
0649     struct iscsi_data *hdr = (struct iscsi_data *) buf;
0650     u32 payload_length = ntoh24(hdr->dlength);
0651 
0652     if (conn->sess->sess_ops->DataPDUInOrder)
0653         goto recover;
0654     /*
0655      * The rest of this function is only called when DataPDUInOrder=No.
0656      */
0657     pdu = cmd->pdu_ptr;
0658 
0659     switch (pdu->status) {
0660     case ISCSI_PDU_NOT_RECEIVED:
0661         pdu->status = ISCSI_PDU_CRC_FAILED;
0662         break;
0663     case ISCSI_PDU_CRC_FAILED:
0664         break;
0665     case ISCSI_PDU_TIMED_OUT:
0666         pdu->status = ISCSI_PDU_CRC_FAILED;
0667         break;
0668     default:
0669         return DATAOUT_CANNOT_RECOVER;
0670     }
0671 
0672 recover:
0673     return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
0674                         payload_length);
0675 }
0676 
0677 /*
0678  *  Called from iscsit_handle_data_out() before DataOUT Payload is received
0679  *  and CRC computed.
0680  */
0681 int iscsit_check_pre_dataout(
0682     struct iscsit_cmd *cmd,
0683     unsigned char *buf)
0684 {
0685     int ret;
0686     struct iscsit_conn *conn = cmd->conn;
0687 
0688     ret = iscsit_dataout_within_command_recovery_check(cmd, buf);
0689     if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
0690         (ret == DATAOUT_CANNOT_RECOVER))
0691         return ret;
0692 
0693     ret = iscsit_dataout_check_datasn(cmd, buf);
0694     if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
0695         (ret == DATAOUT_CANNOT_RECOVER))
0696         return ret;
0697 
0698     if (cmd->unsolicited_data) {
0699         ret = iscsit_dataout_check_unsolicited_sequence(cmd, buf);
0700         if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
0701             (ret == DATAOUT_CANNOT_RECOVER))
0702             return ret;
0703     } else {
0704         ret = iscsit_dataout_check_sequence(cmd, buf);
0705         if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
0706             (ret == DATAOUT_CANNOT_RECOVER))
0707             return ret;
0708     }
0709 
0710     return (conn->sess->sess_ops->DataPDUInOrder) ?
0711         iscsit_dataout_pre_datapduinorder_yes(cmd, buf) :
0712         iscsit_dataout_pre_datapduinorder_no(cmd, buf);
0713 }
0714 
0715 /*
0716  *  Called from iscsit_handle_data_out() after DataOUT Payload is received
0717  *  and CRC computed.
0718  */
0719 int iscsit_check_post_dataout(
0720     struct iscsit_cmd *cmd,
0721     unsigned char *buf,
0722     u8 data_crc_failed)
0723 {
0724     struct iscsit_conn *conn = cmd->conn;
0725 
0726     cmd->dataout_timeout_retries = 0;
0727 
0728     if (!data_crc_failed)
0729         return iscsit_dataout_post_crc_passed(cmd, buf);
0730     else {
0731         if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
0732             pr_err("Unable to recover from DataOUT CRC"
0733                 " failure while ERL=0, closing session.\n");
0734             iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
0735                       buf);
0736             return DATAOUT_CANNOT_RECOVER;
0737         }
0738 
0739         iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
0740         return iscsit_dataout_post_crc_failed(cmd, buf);
0741     }
0742 }
0743 
0744 void iscsit_handle_time2retain_timeout(struct timer_list *t)
0745 {
0746     struct iscsit_session *sess = from_timer(sess, t, time2retain_timer);
0747     struct iscsi_portal_group *tpg = sess->tpg;
0748     struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
0749 
0750     spin_lock_bh(&se_tpg->session_lock);
0751     if (sess->time2retain_timer_flags & ISCSI_TF_STOP) {
0752         spin_unlock_bh(&se_tpg->session_lock);
0753         return;
0754     }
0755     if (atomic_read(&sess->session_reinstatement)) {
0756         pr_err("Exiting Time2Retain handler because"
0757                 " session_reinstatement=1\n");
0758         spin_unlock_bh(&se_tpg->session_lock);
0759         return;
0760     }
0761     sess->time2retain_timer_flags |= ISCSI_TF_EXPIRED;
0762 
0763     pr_err("Time2Retain timer expired for SID: %u, cleaning up"
0764             " iSCSI session.\n", sess->sid);
0765 
0766     iscsit_fill_cxn_timeout_err_stats(sess);
0767     spin_unlock_bh(&se_tpg->session_lock);
0768     iscsit_close_session(sess, false);
0769 }
0770 
0771 void iscsit_start_time2retain_handler(struct iscsit_session *sess)
0772 {
0773     int tpg_active;
0774     /*
0775      * Only start Time2Retain timer when the associated TPG is still in
0776      * an ACTIVE (eg: not disabled or shutdown) state.
0777      */
0778     spin_lock(&sess->tpg->tpg_state_lock);
0779     tpg_active = (sess->tpg->tpg_state == TPG_STATE_ACTIVE);
0780     spin_unlock(&sess->tpg->tpg_state_lock);
0781 
0782     if (!tpg_active)
0783         return;
0784 
0785     if (sess->time2retain_timer_flags & ISCSI_TF_RUNNING)
0786         return;
0787 
0788     pr_debug("Starting Time2Retain timer for %u seconds on"
0789         " SID: %u\n", sess->sess_ops->DefaultTime2Retain, sess->sid);
0790 
0791     sess->time2retain_timer_flags &= ~ISCSI_TF_STOP;
0792     sess->time2retain_timer_flags |= ISCSI_TF_RUNNING;
0793     mod_timer(&sess->time2retain_timer,
0794           jiffies + sess->sess_ops->DefaultTime2Retain * HZ);
0795 }
0796 
0797 int iscsit_stop_time2retain_timer(struct iscsit_session *sess)
0798 {
0799     struct iscsi_portal_group *tpg = sess->tpg;
0800     struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
0801 
0802     lockdep_assert_held(&se_tpg->session_lock);
0803 
0804     if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)
0805         return -1;
0806 
0807     if (!(sess->time2retain_timer_flags & ISCSI_TF_RUNNING))
0808         return 0;
0809 
0810     sess->time2retain_timer_flags |= ISCSI_TF_STOP;
0811     spin_unlock(&se_tpg->session_lock);
0812 
0813     del_timer_sync(&sess->time2retain_timer);
0814 
0815     spin_lock(&se_tpg->session_lock);
0816     sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
0817     pr_debug("Stopped Time2Retain Timer for SID: %u\n",
0818             sess->sid);
0819     return 0;
0820 }
0821 
0822 void iscsit_connection_reinstatement_rcfr(struct iscsit_conn *conn)
0823 {
0824     spin_lock_bh(&conn->state_lock);
0825     if (atomic_read(&conn->connection_exit)) {
0826         spin_unlock_bh(&conn->state_lock);
0827         goto sleep;
0828     }
0829 
0830     if (atomic_read(&conn->transport_failed)) {
0831         spin_unlock_bh(&conn->state_lock);
0832         goto sleep;
0833     }
0834     spin_unlock_bh(&conn->state_lock);
0835 
0836     if (conn->tx_thread && conn->tx_thread_active)
0837         send_sig(SIGINT, conn->tx_thread, 1);
0838     if (conn->rx_thread && conn->rx_thread_active)
0839         send_sig(SIGINT, conn->rx_thread, 1);
0840 
0841 sleep:
0842     wait_for_completion(&conn->conn_wait_rcfr_comp);
0843     complete(&conn->conn_post_wait_comp);
0844 }
0845 
0846 void iscsit_cause_connection_reinstatement(struct iscsit_conn *conn, int sleep)
0847 {
0848     spin_lock_bh(&conn->state_lock);
0849     if (atomic_read(&conn->connection_exit)) {
0850         spin_unlock_bh(&conn->state_lock);
0851         return;
0852     }
0853 
0854     if (atomic_read(&conn->transport_failed)) {
0855         spin_unlock_bh(&conn->state_lock);
0856         return;
0857     }
0858 
0859     if (atomic_read(&conn->connection_reinstatement)) {
0860         spin_unlock_bh(&conn->state_lock);
0861         return;
0862     }
0863 
0864     if (conn->tx_thread && conn->tx_thread_active)
0865         send_sig(SIGINT, conn->tx_thread, 1);
0866     if (conn->rx_thread && conn->rx_thread_active)
0867         send_sig(SIGINT, conn->rx_thread, 1);
0868 
0869     atomic_set(&conn->connection_reinstatement, 1);
0870     if (!sleep) {
0871         spin_unlock_bh(&conn->state_lock);
0872         return;
0873     }
0874 
0875     atomic_set(&conn->sleep_on_conn_wait_comp, 1);
0876     spin_unlock_bh(&conn->state_lock);
0877 
0878     wait_for_completion(&conn->conn_wait_comp);
0879     complete(&conn->conn_post_wait_comp);
0880 }
0881 EXPORT_SYMBOL(iscsit_cause_connection_reinstatement);
0882 
0883 void iscsit_fall_back_to_erl0(struct iscsit_session *sess)
0884 {
0885     pr_debug("Falling back to ErrorRecoveryLevel=0 for SID:"
0886             " %u\n", sess->sid);
0887 
0888     atomic_set(&sess->session_fall_back_to_erl0, 1);
0889 }
0890 
0891 static void iscsit_handle_connection_cleanup(struct iscsit_conn *conn)
0892 {
0893     struct iscsit_session *sess = conn->sess;
0894 
0895     if ((sess->sess_ops->ErrorRecoveryLevel == 2) &&
0896         !atomic_read(&sess->session_reinstatement) &&
0897         !atomic_read(&sess->session_fall_back_to_erl0))
0898         iscsit_connection_recovery_transport_reset(conn);
0899     else {
0900         pr_debug("Performing cleanup for failed iSCSI"
0901             " Connection ID: %hu from %s\n", conn->cid,
0902             sess->sess_ops->InitiatorName);
0903         iscsit_close_connection(conn);
0904     }
0905 }
0906 
0907 void iscsit_take_action_for_connection_exit(struct iscsit_conn *conn, bool *conn_freed)
0908 {
0909     *conn_freed = false;
0910 
0911     spin_lock_bh(&conn->state_lock);
0912     if (atomic_read(&conn->connection_exit)) {
0913         spin_unlock_bh(&conn->state_lock);
0914         return;
0915     }
0916     atomic_set(&conn->connection_exit, 1);
0917 
0918     if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
0919         spin_unlock_bh(&conn->state_lock);
0920         iscsit_close_connection(conn);
0921         *conn_freed = true;
0922         return;
0923     }
0924 
0925     if (conn->conn_state == TARG_CONN_STATE_CLEANUP_WAIT) {
0926         spin_unlock_bh(&conn->state_lock);
0927         return;
0928     }
0929 
0930     pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
0931     conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
0932     spin_unlock_bh(&conn->state_lock);
0933 
0934     iscsit_handle_connection_cleanup(conn);
0935     *conn_freed = true;
0936 }