1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /******************************************************************************
3 * This file contains error recovery level zero functions used by
4 * the iSCSI Target driver.
6 * (c) Copyright 2007-2013 Datera, Inc.
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 ******************************************************************************/
12 #include <linux/sched/signal.h>
14 #include <scsi/iscsi_proto.h>
15 #include <target/target_core_base.h>
16 #include <target/target_core_fabric.h>
18 #include <target/iscsi/iscsi_target_core.h>
19 #include "iscsi_target_seq_pdu_list.h"
20 #include "iscsi_target_erl0.h"
21 #include "iscsi_target_erl1.h"
22 #include "iscsi_target_erl2.h"
23 #include "iscsi_target_util.h"
24 #include "iscsi_target.h"
27 * Used to set values in struct iscsi_cmd that iscsit_dataout_check_sequence()
28 * checks against to determine a PDU's Offset+Length is within the current
29 * DataOUT Sequence. Used for DataSequenceInOrder=Yes only.
31 void iscsit_set_dataout_sequence_values(
32 struct iscsi_cmd
*cmd
)
34 struct iscsi_conn
*conn
= cmd
->conn
;
36 * Still set seq_start_offset and seq_end_offset for Unsolicited
37 * DataOUT, even if DataSequenceInOrder=No.
39 if (cmd
->unsolicited_data
) {
40 cmd
->seq_start_offset
= cmd
->write_data_done
;
41 cmd
->seq_end_offset
= min(cmd
->se_cmd
.data_length
,
42 conn
->sess
->sess_ops
->FirstBurstLength
);
46 if (!conn
->sess
->sess_ops
->DataSequenceInOrder
)
49 if (!cmd
->seq_start_offset
&& !cmd
->seq_end_offset
) {
50 cmd
->seq_start_offset
= cmd
->write_data_done
;
51 cmd
->seq_end_offset
= (cmd
->se_cmd
.data_length
>
52 conn
->sess
->sess_ops
->MaxBurstLength
) ?
53 (cmd
->write_data_done
+
54 conn
->sess
->sess_ops
->MaxBurstLength
) : cmd
->se_cmd
.data_length
;
56 cmd
->seq_start_offset
= cmd
->seq_end_offset
;
57 cmd
->seq_end_offset
= ((cmd
->seq_end_offset
+
58 conn
->sess
->sess_ops
->MaxBurstLength
) >=
59 cmd
->se_cmd
.data_length
) ? cmd
->se_cmd
.data_length
:
60 (cmd
->seq_end_offset
+
61 conn
->sess
->sess_ops
->MaxBurstLength
);
65 static int iscsit_dataout_within_command_recovery_check(
66 struct iscsi_cmd
*cmd
,
69 struct iscsi_conn
*conn
= cmd
->conn
;
70 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
71 u32 payload_length
= ntoh24(hdr
->dlength
);
74 * We do the within-command recovery checks here as it is
75 * the first function called in iscsi_check_pre_dataout().
76 * Basically, if we are in within-command recovery and
77 * the PDU does not contain the offset the sequence needs,
80 * This only applies to DataPDUInOrder=Yes, for
81 * DataPDUInOrder=No we only re-request the failed PDU
82 * and check that all PDUs in a sequence are received
83 * upon end of sequence.
85 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
86 if ((cmd
->cmd_flags
& ICF_WITHIN_COMMAND_RECOVERY
) &&
87 cmd
->write_data_done
!= be32_to_cpu(hdr
->offset
))
90 cmd
->cmd_flags
&= ~ICF_WITHIN_COMMAND_RECOVERY
;
92 struct iscsi_seq
*seq
;
94 seq
= iscsit_get_seq_holder(cmd
, be32_to_cpu(hdr
->offset
),
97 return DATAOUT_CANNOT_RECOVER
;
99 * Set the struct iscsi_seq pointer to reuse later.
103 if (conn
->sess
->sess_ops
->DataPDUInOrder
) {
105 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY
&&
106 (seq
->offset
!= be32_to_cpu(hdr
->offset
) ||
107 seq
->data_sn
!= be32_to_cpu(hdr
->datasn
)))
111 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY
&&
112 seq
->data_sn
!= be32_to_cpu(hdr
->datasn
))
116 if (seq
->status
== DATAOUT_SEQUENCE_COMPLETE
)
119 if (seq
->status
!= DATAOUT_SEQUENCE_COMPLETE
)
123 return DATAOUT_NORMAL
;
126 pr_err("Dumping DataOUT PDU Offset: %u Length: %d DataSN:"
127 " 0x%08x\n", hdr
->offset
, payload_length
, hdr
->datasn
);
128 return iscsit_dump_data_payload(conn
, payload_length
, 1);
131 static int iscsit_dataout_check_unsolicited_sequence(
132 struct iscsi_cmd
*cmd
,
136 struct iscsi_conn
*conn
= cmd
->conn
;
137 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
138 u32 payload_length
= ntoh24(hdr
->dlength
);
141 if ((be32_to_cpu(hdr
->offset
) < cmd
->seq_start_offset
) ||
142 ((be32_to_cpu(hdr
->offset
) + payload_length
) > cmd
->seq_end_offset
)) {
143 pr_err("Command ITT: 0x%08x with Offset: %u,"
144 " Length: %u outside of Unsolicited Sequence %u:%u while"
145 " DataSequenceInOrder=Yes.\n", cmd
->init_task_tag
,
146 be32_to_cpu(hdr
->offset
), payload_length
, cmd
->seq_start_offset
,
147 cmd
->seq_end_offset
);
148 return DATAOUT_CANNOT_RECOVER
;
151 first_burst_len
= (cmd
->first_burst_len
+ payload_length
);
153 if (first_burst_len
> conn
->sess
->sess_ops
->FirstBurstLength
) {
154 pr_err("Total %u bytes exceeds FirstBurstLength: %u"
155 " for this Unsolicited DataOut Burst.\n",
156 first_burst_len
, conn
->sess
->sess_ops
->FirstBurstLength
);
157 transport_send_check_condition_and_sense(&cmd
->se_cmd
,
158 TCM_INCORRECT_AMOUNT_OF_DATA
, 0);
159 return DATAOUT_CANNOT_RECOVER
;
163 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
164 * checks for the current Unsolicited DataOUT Sequence.
166 if (hdr
->flags
& ISCSI_FLAG_CMD_FINAL
) {
168 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
169 * sequence checks are handled in
170 * iscsit_dataout_datapduinorder_no_fbit().
172 if (!conn
->sess
->sess_ops
->DataPDUInOrder
)
175 if ((first_burst_len
!= cmd
->se_cmd
.data_length
) &&
176 (first_burst_len
!= conn
->sess
->sess_ops
->FirstBurstLength
)) {
177 pr_err("Unsolicited non-immediate data"
178 " received %u does not equal FirstBurstLength: %u, and"
179 " does not equal ExpXferLen %u.\n", first_burst_len
,
180 conn
->sess
->sess_ops
->FirstBurstLength
,
181 cmd
->se_cmd
.data_length
);
182 transport_send_check_condition_and_sense(&cmd
->se_cmd
,
183 TCM_INCORRECT_AMOUNT_OF_DATA
, 0);
184 return DATAOUT_CANNOT_RECOVER
;
187 if (first_burst_len
== conn
->sess
->sess_ops
->FirstBurstLength
) {
188 pr_err("Command ITT: 0x%08x reached"
189 " FirstBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
190 " error.\n", cmd
->init_task_tag
,
191 conn
->sess
->sess_ops
->FirstBurstLength
);
192 return DATAOUT_CANNOT_RECOVER
;
194 if (first_burst_len
== cmd
->se_cmd
.data_length
) {
195 pr_err("Command ITT: 0x%08x reached"
196 " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
197 " error.\n", cmd
->init_task_tag
, cmd
->se_cmd
.data_length
);
198 return DATAOUT_CANNOT_RECOVER
;
203 return DATAOUT_NORMAL
;
206 static int iscsit_dataout_check_sequence(
207 struct iscsi_cmd
*cmd
,
211 struct iscsi_conn
*conn
= cmd
->conn
;
212 struct iscsi_seq
*seq
= NULL
;
213 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
214 u32 payload_length
= ntoh24(hdr
->dlength
);
217 * For DataSequenceInOrder=Yes: Check that the offset and offset+length
218 * is within range as defined by iscsi_set_dataout_sequence_values().
220 * For DataSequenceInOrder=No: Check that an struct iscsi_seq exists for
221 * offset+length tuple.
223 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
225 * Due to possibility of recovery DataOUT sent by the initiator
226 * fullfilling an Recovery R2T, it's best to just dump the
227 * payload here, instead of erroring out.
229 if ((be32_to_cpu(hdr
->offset
) < cmd
->seq_start_offset
) ||
230 ((be32_to_cpu(hdr
->offset
) + payload_length
) > cmd
->seq_end_offset
)) {
231 pr_err("Command ITT: 0x%08x with Offset: %u,"
232 " Length: %u outside of Sequence %u:%u while"
233 " DataSequenceInOrder=Yes.\n", cmd
->init_task_tag
,
234 be32_to_cpu(hdr
->offset
), payload_length
, cmd
->seq_start_offset
,
235 cmd
->seq_end_offset
);
237 if (iscsit_dump_data_payload(conn
, payload_length
, 1) < 0)
238 return DATAOUT_CANNOT_RECOVER
;
239 return DATAOUT_WITHIN_COMMAND_RECOVERY
;
242 next_burst_len
= (cmd
->next_burst_len
+ payload_length
);
244 seq
= iscsit_get_seq_holder(cmd
, be32_to_cpu(hdr
->offset
),
247 return DATAOUT_CANNOT_RECOVER
;
249 * Set the struct iscsi_seq pointer to reuse later.
253 if (seq
->status
== DATAOUT_SEQUENCE_COMPLETE
) {
254 if (iscsit_dump_data_payload(conn
, payload_length
, 1) < 0)
255 return DATAOUT_CANNOT_RECOVER
;
256 return DATAOUT_WITHIN_COMMAND_RECOVERY
;
259 next_burst_len
= (seq
->next_burst_len
+ payload_length
);
262 if (next_burst_len
> conn
->sess
->sess_ops
->MaxBurstLength
) {
263 pr_err("Command ITT: 0x%08x, NextBurstLength: %u and"
264 " Length: %u exceeds MaxBurstLength: %u. protocol"
265 " error.\n", cmd
->init_task_tag
,
266 (next_burst_len
- payload_length
),
267 payload_length
, conn
->sess
->sess_ops
->MaxBurstLength
);
268 return DATAOUT_CANNOT_RECOVER
;
272 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
273 * checks for the current DataOUT Sequence.
275 if (hdr
->flags
& ISCSI_FLAG_CMD_FINAL
) {
277 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
278 * sequence checks are handled in
279 * iscsit_dataout_datapduinorder_no_fbit().
281 if (!conn
->sess
->sess_ops
->DataPDUInOrder
)
284 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
285 if ((next_burst_len
<
286 conn
->sess
->sess_ops
->MaxBurstLength
) &&
287 ((cmd
->write_data_done
+ payload_length
) <
288 cmd
->se_cmd
.data_length
)) {
289 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
290 " before end of DataOUT sequence, protocol"
291 " error.\n", cmd
->init_task_tag
);
292 return DATAOUT_CANNOT_RECOVER
;
295 if (next_burst_len
< seq
->xfer_len
) {
296 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
297 " before end of DataOUT sequence, protocol"
298 " error.\n", cmd
->init_task_tag
);
299 return DATAOUT_CANNOT_RECOVER
;
303 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
304 if (next_burst_len
==
305 conn
->sess
->sess_ops
->MaxBurstLength
) {
306 pr_err("Command ITT: 0x%08x reached"
307 " MaxBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is"
308 " not set, protocol error.", cmd
->init_task_tag
,
309 conn
->sess
->sess_ops
->MaxBurstLength
);
310 return DATAOUT_CANNOT_RECOVER
;
312 if ((cmd
->write_data_done
+ payload_length
) ==
313 cmd
->se_cmd
.data_length
) {
314 pr_err("Command ITT: 0x%08x reached"
315 " last DataOUT PDU in sequence but ISCSI_FLAG_"
316 "CMD_FINAL is not set, protocol error.\n",
318 return DATAOUT_CANNOT_RECOVER
;
321 if (next_burst_len
== seq
->xfer_len
) {
322 pr_err("Command ITT: 0x%08x reached"
323 " last DataOUT PDU in sequence but ISCSI_FLAG_"
324 "CMD_FINAL is not set, protocol error.\n",
326 return DATAOUT_CANNOT_RECOVER
;
332 return DATAOUT_NORMAL
;
335 static int iscsit_dataout_check_datasn(
336 struct iscsi_cmd
*cmd
,
340 struct iscsi_conn
*conn
= cmd
->conn
;
341 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
342 u32 payload_length
= ntoh24(hdr
->dlength
);
345 * Considering the target has no method of re-requesting DataOUT
346 * by DataSN, if we receieve a greater DataSN than expected we
347 * assume the functions for DataPDUInOrder=[Yes,No] below will
350 * If the DataSN is less than expected, dump the payload.
352 if (conn
->sess
->sess_ops
->DataSequenceInOrder
)
353 data_sn
= cmd
->data_sn
;
355 struct iscsi_seq
*seq
= cmd
->seq_ptr
;
356 data_sn
= seq
->data_sn
;
359 if (be32_to_cpu(hdr
->datasn
) > data_sn
) {
360 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
361 " higher than expected 0x%08x.\n", cmd
->init_task_tag
,
362 be32_to_cpu(hdr
->datasn
), data_sn
);
364 } else if (be32_to_cpu(hdr
->datasn
) < data_sn
) {
365 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
366 " lower than expected 0x%08x, discarding payload.\n",
367 cmd
->init_task_tag
, be32_to_cpu(hdr
->datasn
), data_sn
);
371 return DATAOUT_NORMAL
;
374 if (!conn
->sess
->sess_ops
->ErrorRecoveryLevel
) {
375 pr_err("Unable to perform within-command recovery"
377 return DATAOUT_CANNOT_RECOVER
;
380 if (iscsit_dump_data_payload(conn
, payload_length
, 1) < 0)
381 return DATAOUT_CANNOT_RECOVER
;
383 return DATAOUT_WITHIN_COMMAND_RECOVERY
;
386 static int iscsit_dataout_pre_datapduinorder_yes(
387 struct iscsi_cmd
*cmd
,
390 int dump
= 0, recovery
= 0;
391 struct iscsi_conn
*conn
= cmd
->conn
;
392 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
393 u32 payload_length
= ntoh24(hdr
->dlength
);
396 * For DataSequenceInOrder=Yes: If the offset is greater than the global
397 * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has
398 * occurred and fail the connection.
400 * For DataSequenceInOrder=No: If the offset is greater than the per
401 * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
402 * error has occurred and fail the connection.
404 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
405 if (be32_to_cpu(hdr
->offset
) != cmd
->write_data_done
) {
406 pr_err("Command ITT: 0x%08x, received offset"
407 " %u different than expected %u.\n", cmd
->init_task_tag
,
408 be32_to_cpu(hdr
->offset
), cmd
->write_data_done
);
413 struct iscsi_seq
*seq
= cmd
->seq_ptr
;
415 if (be32_to_cpu(hdr
->offset
) > seq
->offset
) {
416 pr_err("Command ITT: 0x%08x, received offset"
417 " %u greater than expected %u.\n", cmd
->init_task_tag
,
418 be32_to_cpu(hdr
->offset
), seq
->offset
);
421 } else if (be32_to_cpu(hdr
->offset
) < seq
->offset
) {
422 pr_err("Command ITT: 0x%08x, received offset"
423 " %u less than expected %u, discarding payload.\n",
424 cmd
->init_task_tag
, be32_to_cpu(hdr
->offset
),
431 return DATAOUT_NORMAL
;
434 if (!conn
->sess
->sess_ops
->ErrorRecoveryLevel
) {
435 pr_err("Unable to perform within-command recovery"
437 return DATAOUT_CANNOT_RECOVER
;
440 if (iscsit_dump_data_payload(conn
, payload_length
, 1) < 0)
441 return DATAOUT_CANNOT_RECOVER
;
443 return (recovery
) ? iscsit_recover_dataout_sequence(cmd
,
444 be32_to_cpu(hdr
->offset
), payload_length
) :
445 (dump
) ? DATAOUT_WITHIN_COMMAND_RECOVERY
: DATAOUT_NORMAL
;
448 static int iscsit_dataout_pre_datapduinorder_no(
449 struct iscsi_cmd
*cmd
,
452 struct iscsi_pdu
*pdu
;
453 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
454 u32 payload_length
= ntoh24(hdr
->dlength
);
456 pdu
= iscsit_get_pdu_holder(cmd
, be32_to_cpu(hdr
->offset
),
459 return DATAOUT_CANNOT_RECOVER
;
463 switch (pdu
->status
) {
464 case ISCSI_PDU_NOT_RECEIVED
:
465 case ISCSI_PDU_CRC_FAILED
:
466 case ISCSI_PDU_TIMED_OUT
:
468 case ISCSI_PDU_RECEIVED_OK
:
469 pr_err("Command ITT: 0x%08x received already gotten"
470 " Offset: %u, Length: %u\n", cmd
->init_task_tag
,
471 be32_to_cpu(hdr
->offset
), payload_length
);
472 return iscsit_dump_data_payload(cmd
->conn
, payload_length
, 1);
474 return DATAOUT_CANNOT_RECOVER
;
477 return DATAOUT_NORMAL
;
480 static int iscsit_dataout_update_r2t(struct iscsi_cmd
*cmd
, u32 offset
, u32 length
)
482 struct iscsi_r2t
*r2t
;
484 if (cmd
->unsolicited_data
)
487 r2t
= iscsit_get_r2t_for_eos(cmd
, offset
, length
);
491 spin_lock_bh(&cmd
->r2t_lock
);
492 r2t
->seq_complete
= 1;
493 cmd
->outstanding_r2ts
--;
494 spin_unlock_bh(&cmd
->r2t_lock
);
499 static int iscsit_dataout_update_datapduinorder_no(
500 struct iscsi_cmd
*cmd
,
505 struct iscsi_pdu
*pdu
= cmd
->pdu_ptr
;
507 pdu
->data_sn
= data_sn
;
509 switch (pdu
->status
) {
510 case ISCSI_PDU_NOT_RECEIVED
:
511 pdu
->status
= ISCSI_PDU_RECEIVED_OK
;
513 case ISCSI_PDU_CRC_FAILED
:
514 pdu
->status
= ISCSI_PDU_RECEIVED_OK
;
516 case ISCSI_PDU_TIMED_OUT
:
517 pdu
->status
= ISCSI_PDU_RECEIVED_OK
;
520 return DATAOUT_CANNOT_RECOVER
;
524 ret
= iscsit_dataout_datapduinorder_no_fbit(cmd
, pdu
);
525 if (ret
== DATAOUT_CANNOT_RECOVER
)
529 return DATAOUT_NORMAL
;
532 static int iscsit_dataout_post_crc_passed(
533 struct iscsi_cmd
*cmd
,
536 int ret
, send_r2t
= 0;
537 struct iscsi_conn
*conn
= cmd
->conn
;
538 struct iscsi_seq
*seq
= NULL
;
539 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
540 u32 payload_length
= ntoh24(hdr
->dlength
);
542 if (cmd
->unsolicited_data
) {
543 if ((cmd
->first_burst_len
+ payload_length
) ==
544 conn
->sess
->sess_ops
->FirstBurstLength
) {
545 if (iscsit_dataout_update_r2t(cmd
, be32_to_cpu(hdr
->offset
),
547 return DATAOUT_CANNOT_RECOVER
;
551 if (!conn
->sess
->sess_ops
->DataPDUInOrder
) {
552 ret
= iscsit_dataout_update_datapduinorder_no(cmd
,
553 be32_to_cpu(hdr
->datasn
),
554 (hdr
->flags
& ISCSI_FLAG_CMD_FINAL
));
555 if (ret
== DATAOUT_CANNOT_RECOVER
)
559 cmd
->first_burst_len
+= payload_length
;
561 if (conn
->sess
->sess_ops
->DataSequenceInOrder
)
566 seq
->offset
+= payload_length
;
571 seq
->status
= DATAOUT_SEQUENCE_COMPLETE
;
572 cmd
->first_burst_len
= 0;
573 cmd
->unsolicited_data
= 0;
576 if (conn
->sess
->sess_ops
->DataSequenceInOrder
) {
577 if ((cmd
->next_burst_len
+ payload_length
) ==
578 conn
->sess
->sess_ops
->MaxBurstLength
) {
579 if (iscsit_dataout_update_r2t(cmd
,
580 be32_to_cpu(hdr
->offset
),
582 return DATAOUT_CANNOT_RECOVER
;
586 if (!conn
->sess
->sess_ops
->DataPDUInOrder
) {
587 ret
= iscsit_dataout_update_datapduinorder_no(
588 cmd
, be32_to_cpu(hdr
->datasn
),
589 (hdr
->flags
& ISCSI_FLAG_CMD_FINAL
));
590 if (ret
== DATAOUT_CANNOT_RECOVER
)
594 cmd
->next_burst_len
+= payload_length
;
598 cmd
->next_burst_len
= 0;
602 if ((seq
->next_burst_len
+ payload_length
) ==
604 if (iscsit_dataout_update_r2t(cmd
,
605 be32_to_cpu(hdr
->offset
),
607 return DATAOUT_CANNOT_RECOVER
;
611 if (!conn
->sess
->sess_ops
->DataPDUInOrder
) {
612 ret
= iscsit_dataout_update_datapduinorder_no(
613 cmd
, be32_to_cpu(hdr
->datasn
),
614 (hdr
->flags
& ISCSI_FLAG_CMD_FINAL
));
615 if (ret
== DATAOUT_CANNOT_RECOVER
)
620 seq
->offset
+= payload_length
;
621 seq
->next_burst_len
+= payload_length
;
624 seq
->next_burst_len
= 0;
625 seq
->status
= DATAOUT_SEQUENCE_COMPLETE
;
630 if (send_r2t
&& conn
->sess
->sess_ops
->DataSequenceInOrder
)
633 cmd
->write_data_done
+= payload_length
;
635 if (cmd
->write_data_done
== cmd
->se_cmd
.data_length
)
636 return DATAOUT_SEND_TO_TRANSPORT
;
638 return DATAOUT_SEND_R2T
;
640 return DATAOUT_NORMAL
;
643 static int iscsit_dataout_post_crc_failed(
644 struct iscsi_cmd
*cmd
,
647 struct iscsi_conn
*conn
= cmd
->conn
;
648 struct iscsi_pdu
*pdu
;
649 struct iscsi_data
*hdr
= (struct iscsi_data
*) buf
;
650 u32 payload_length
= ntoh24(hdr
->dlength
);
652 if (conn
->sess
->sess_ops
->DataPDUInOrder
)
655 * The rest of this function is only called when DataPDUInOrder=No.
659 switch (pdu
->status
) {
660 case ISCSI_PDU_NOT_RECEIVED
:
661 pdu
->status
= ISCSI_PDU_CRC_FAILED
;
663 case ISCSI_PDU_CRC_FAILED
:
665 case ISCSI_PDU_TIMED_OUT
:
666 pdu
->status
= ISCSI_PDU_CRC_FAILED
;
669 return DATAOUT_CANNOT_RECOVER
;
673 return iscsit_recover_dataout_sequence(cmd
, be32_to_cpu(hdr
->offset
),
678 * Called from iscsit_handle_data_out() before DataOUT Payload is received
681 int iscsit_check_pre_dataout(
682 struct iscsi_cmd
*cmd
,
686 struct iscsi_conn
*conn
= cmd
->conn
;
688 ret
= iscsit_dataout_within_command_recovery_check(cmd
, buf
);
689 if ((ret
== DATAOUT_WITHIN_COMMAND_RECOVERY
) ||
690 (ret
== DATAOUT_CANNOT_RECOVER
))
693 ret
= iscsit_dataout_check_datasn(cmd
, buf
);
694 if ((ret
== DATAOUT_WITHIN_COMMAND_RECOVERY
) ||
695 (ret
== DATAOUT_CANNOT_RECOVER
))
698 if (cmd
->unsolicited_data
) {
699 ret
= iscsit_dataout_check_unsolicited_sequence(cmd
, buf
);
700 if ((ret
== DATAOUT_WITHIN_COMMAND_RECOVERY
) ||
701 (ret
== DATAOUT_CANNOT_RECOVER
))
704 ret
= iscsit_dataout_check_sequence(cmd
, buf
);
705 if ((ret
== DATAOUT_WITHIN_COMMAND_RECOVERY
) ||
706 (ret
== DATAOUT_CANNOT_RECOVER
))
710 return (conn
->sess
->sess_ops
->DataPDUInOrder
) ?
711 iscsit_dataout_pre_datapduinorder_yes(cmd
, buf
) :
712 iscsit_dataout_pre_datapduinorder_no(cmd
, buf
);
716 * Called from iscsit_handle_data_out() after DataOUT Payload is received
719 int iscsit_check_post_dataout(
720 struct iscsi_cmd
*cmd
,
724 struct iscsi_conn
*conn
= cmd
->conn
;
726 cmd
->dataout_timeout_retries
= 0;
728 if (!data_crc_failed
)
729 return iscsit_dataout_post_crc_passed(cmd
, buf
);
731 if (!conn
->sess
->sess_ops
->ErrorRecoveryLevel
) {
732 pr_err("Unable to recover from DataOUT CRC"
733 " failure while ERL=0, closing session.\n");
734 iscsit_reject_cmd(cmd
, ISCSI_REASON_DATA_DIGEST_ERROR
,
736 return DATAOUT_CANNOT_RECOVER
;
739 iscsit_reject_cmd(cmd
, ISCSI_REASON_DATA_DIGEST_ERROR
, buf
);
740 return iscsit_dataout_post_crc_failed(cmd
, buf
);
744 void iscsit_handle_time2retain_timeout(struct timer_list
*t
)
746 struct iscsi_session
*sess
= from_timer(sess
, t
, time2retain_timer
);
747 struct iscsi_portal_group
*tpg
= sess
->tpg
;
748 struct se_portal_group
*se_tpg
= &tpg
->tpg_se_tpg
;
750 spin_lock_bh(&se_tpg
->session_lock
);
751 if (sess
->time2retain_timer_flags
& ISCSI_TF_STOP
) {
752 spin_unlock_bh(&se_tpg
->session_lock
);
755 if (atomic_read(&sess
->session_reinstatement
)) {
756 pr_err("Exiting Time2Retain handler because"
757 " session_reinstatement=1\n");
758 spin_unlock_bh(&se_tpg
->session_lock
);
761 sess
->time2retain_timer_flags
|= ISCSI_TF_EXPIRED
;
763 pr_err("Time2Retain timer expired for SID: %u, cleaning up"
764 " iSCSI session.\n", sess
->sid
);
766 iscsit_fill_cxn_timeout_err_stats(sess
);
767 spin_unlock_bh(&se_tpg
->session_lock
);
768 iscsit_close_session(sess
);
771 void iscsit_start_time2retain_handler(struct iscsi_session
*sess
)
775 * Only start Time2Retain timer when the associated TPG is still in
776 * an ACTIVE (eg: not disabled or shutdown) state.
778 spin_lock(&sess
->tpg
->tpg_state_lock
);
779 tpg_active
= (sess
->tpg
->tpg_state
== TPG_STATE_ACTIVE
);
780 spin_unlock(&sess
->tpg
->tpg_state_lock
);
785 if (sess
->time2retain_timer_flags
& ISCSI_TF_RUNNING
)
788 pr_debug("Starting Time2Retain timer for %u seconds on"
789 " SID: %u\n", sess
->sess_ops
->DefaultTime2Retain
, sess
->sid
);
791 sess
->time2retain_timer_flags
&= ~ISCSI_TF_STOP
;
792 sess
->time2retain_timer_flags
|= ISCSI_TF_RUNNING
;
793 mod_timer(&sess
->time2retain_timer
,
794 jiffies
+ sess
->sess_ops
->DefaultTime2Retain
* HZ
);
797 int iscsit_stop_time2retain_timer(struct iscsi_session
*sess
)
799 struct iscsi_portal_group
*tpg
= sess
->tpg
;
800 struct se_portal_group
*se_tpg
= &tpg
->tpg_se_tpg
;
802 lockdep_assert_held(&se_tpg
->session_lock
);
804 if (sess
->time2retain_timer_flags
& ISCSI_TF_EXPIRED
)
807 if (!(sess
->time2retain_timer_flags
& ISCSI_TF_RUNNING
))
810 sess
->time2retain_timer_flags
|= ISCSI_TF_STOP
;
811 spin_unlock(&se_tpg
->session_lock
);
813 del_timer_sync(&sess
->time2retain_timer
);
815 spin_lock(&se_tpg
->session_lock
);
816 sess
->time2retain_timer_flags
&= ~ISCSI_TF_RUNNING
;
817 pr_debug("Stopped Time2Retain Timer for SID: %u\n",
822 void iscsit_connection_reinstatement_rcfr(struct iscsi_conn
*conn
)
824 spin_lock_bh(&conn
->state_lock
);
825 if (atomic_read(&conn
->connection_exit
)) {
826 spin_unlock_bh(&conn
->state_lock
);
830 if (atomic_read(&conn
->transport_failed
)) {
831 spin_unlock_bh(&conn
->state_lock
);
834 spin_unlock_bh(&conn
->state_lock
);
836 if (conn
->tx_thread
&& conn
->tx_thread_active
)
837 send_sig(SIGINT
, conn
->tx_thread
, 1);
838 if (conn
->rx_thread
&& conn
->rx_thread_active
)
839 send_sig(SIGINT
, conn
->rx_thread
, 1);
842 wait_for_completion(&conn
->conn_wait_rcfr_comp
);
843 complete(&conn
->conn_post_wait_comp
);
846 void iscsit_cause_connection_reinstatement(struct iscsi_conn
*conn
, int sleep
)
848 spin_lock_bh(&conn
->state_lock
);
849 if (atomic_read(&conn
->connection_exit
)) {
850 spin_unlock_bh(&conn
->state_lock
);
854 if (atomic_read(&conn
->transport_failed
)) {
855 spin_unlock_bh(&conn
->state_lock
);
859 if (atomic_read(&conn
->connection_reinstatement
)) {
860 spin_unlock_bh(&conn
->state_lock
);
864 if (conn
->tx_thread
&& conn
->tx_thread_active
)
865 send_sig(SIGINT
, conn
->tx_thread
, 1);
866 if (conn
->rx_thread
&& conn
->rx_thread_active
)
867 send_sig(SIGINT
, conn
->rx_thread
, 1);
869 atomic_set(&conn
->connection_reinstatement
, 1);
871 spin_unlock_bh(&conn
->state_lock
);
875 atomic_set(&conn
->sleep_on_conn_wait_comp
, 1);
876 spin_unlock_bh(&conn
->state_lock
);
878 wait_for_completion(&conn
->conn_wait_comp
);
879 complete(&conn
->conn_post_wait_comp
);
881 EXPORT_SYMBOL(iscsit_cause_connection_reinstatement
);
883 void iscsit_fall_back_to_erl0(struct iscsi_session
*sess
)
885 pr_debug("Falling back to ErrorRecoveryLevel=0 for SID:"
888 atomic_set(&sess
->session_fall_back_to_erl0
, 1);
891 static void iscsit_handle_connection_cleanup(struct iscsi_conn
*conn
)
893 struct iscsi_session
*sess
= conn
->sess
;
895 if ((sess
->sess_ops
->ErrorRecoveryLevel
== 2) &&
896 !atomic_read(&sess
->session_reinstatement
) &&
897 !atomic_read(&sess
->session_fall_back_to_erl0
))
898 iscsit_connection_recovery_transport_reset(conn
);
900 pr_debug("Performing cleanup for failed iSCSI"
901 " Connection ID: %hu from %s\n", conn
->cid
,
902 sess
->sess_ops
->InitiatorName
);
903 iscsit_close_connection(conn
);
907 void iscsit_take_action_for_connection_exit(struct iscsi_conn
*conn
, bool *conn_freed
)
911 spin_lock_bh(&conn
->state_lock
);
912 if (atomic_read(&conn
->connection_exit
)) {
913 spin_unlock_bh(&conn
->state_lock
);
916 atomic_set(&conn
->connection_exit
, 1);
918 if (conn
->conn_state
== TARG_CONN_STATE_IN_LOGOUT
) {
919 spin_unlock_bh(&conn
->state_lock
);
920 iscsit_close_connection(conn
);
925 if (conn
->conn_state
== TARG_CONN_STATE_CLEANUP_WAIT
) {
926 spin_unlock_bh(&conn
->state_lock
);
930 pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
931 conn
->conn_state
= TARG_CONN_STATE_CLEANUP_WAIT
;
932 spin_unlock_bh(&conn
->state_lock
);
934 iscsit_handle_connection_cleanup(conn
);