iscsi_target_erl0.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. /******************************************************************************
  2. * This file contains error recovery level zero functions used by
  3. * the iSCSI Target driver.
  4. *
  5. * (c) Copyright 2007-2013 Datera, Inc.
  6. *
  7. * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. ******************************************************************************/
  19. #include <scsi/iscsi_proto.h>
  20. #include <target/target_core_base.h>
  21. #include <target/target_core_fabric.h>
  22. #include <target/iscsi/iscsi_target_core.h>
  23. #include "iscsi_target_seq_pdu_list.h"
  24. #include "iscsi_target_erl0.h"
  25. #include "iscsi_target_erl1.h"
  26. #include "iscsi_target_erl2.h"
  27. #include "iscsi_target_util.h"
  28. #include "iscsi_target.h"
  29. /*
  30. * Used to set values in struct iscsi_cmd that iscsit_dataout_check_sequence()
  31. * checks against to determine a PDU's Offset+Length is within the current
  32. * DataOUT Sequence. Used for DataSequenceInOrder=Yes only.
  33. */
  34. void iscsit_set_dataout_sequence_values(
  35. struct iscsi_cmd *cmd)
  36. {
  37. struct iscsi_conn *conn = cmd->conn;
  38. /*
  39. * Still set seq_start_offset and seq_end_offset for Unsolicited
  40. * DataOUT, even if DataSequenceInOrder=No.
  41. */
  42. if (cmd->unsolicited_data) {
  43. cmd->seq_start_offset = cmd->write_data_done;
  44. cmd->seq_end_offset = min(cmd->se_cmd.data_length,
  45. conn->sess->sess_ops->FirstBurstLength);
  46. return;
  47. }
  48. if (!conn->sess->sess_ops->DataSequenceInOrder)
  49. return;
  50. if (!cmd->seq_start_offset && !cmd->seq_end_offset) {
  51. cmd->seq_start_offset = cmd->write_data_done;
  52. cmd->seq_end_offset = (cmd->se_cmd.data_length >
  53. conn->sess->sess_ops->MaxBurstLength) ?
  54. (cmd->write_data_done +
  55. conn->sess->sess_ops->MaxBurstLength) : cmd->se_cmd.data_length;
  56. } else {
  57. cmd->seq_start_offset = cmd->seq_end_offset;
  58. cmd->seq_end_offset = ((cmd->seq_end_offset +
  59. conn->sess->sess_ops->MaxBurstLength) >=
  60. cmd->se_cmd.data_length) ? cmd->se_cmd.data_length :
  61. (cmd->seq_end_offset +
  62. conn->sess->sess_ops->MaxBurstLength);
  63. }
  64. }
  65. static int iscsit_dataout_within_command_recovery_check(
  66. struct iscsi_cmd *cmd,
  67. unsigned char *buf)
  68. {
  69. struct iscsi_conn *conn = cmd->conn;
  70. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  71. u32 payload_length = ntoh24(hdr->dlength);
  72. /*
  73. * We do the within-command recovery checks here as it is
  74. * the first function called in iscsi_check_pre_dataout().
  75. * Basically, if we are in within-command recovery and
  76. * the PDU does not contain the offset the sequence needs,
  77. * dump the payload.
  78. *
  79. * This only applies to DataPDUInOrder=Yes, for
  80. * DataPDUInOrder=No we only re-request the failed PDU
  81. * and check that all PDUs in a sequence are received
  82. * upon end of sequence.
  83. */
  84. if (conn->sess->sess_ops->DataSequenceInOrder) {
  85. if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
  86. cmd->write_data_done != be32_to_cpu(hdr->offset))
  87. goto dump;
  88. cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
  89. } else {
  90. struct iscsi_seq *seq;
  91. seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
  92. payload_length);
  93. if (!seq)
  94. return DATAOUT_CANNOT_RECOVER;
  95. /*
  96. * Set the struct iscsi_seq pointer to reuse later.
  97. */
  98. cmd->seq_ptr = seq;
  99. if (conn->sess->sess_ops->DataPDUInOrder) {
  100. if (seq->status ==
  101. DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
  102. (seq->offset != be32_to_cpu(hdr->offset) ||
  103. seq->data_sn != be32_to_cpu(hdr->datasn)))
  104. goto dump;
  105. } else {
  106. if (seq->status ==
  107. DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
  108. seq->data_sn != be32_to_cpu(hdr->datasn))
  109. goto dump;
  110. }
  111. if (seq->status == DATAOUT_SEQUENCE_COMPLETE)
  112. goto dump;
  113. if (seq->status != DATAOUT_SEQUENCE_COMPLETE)
  114. seq->status = 0;
  115. }
  116. return DATAOUT_NORMAL;
  117. dump:
  118. pr_err("Dumping DataOUT PDU Offset: %u Length: %d DataSN:"
  119. " 0x%08x\n", hdr->offset, payload_length, hdr->datasn);
  120. return iscsit_dump_data_payload(conn, payload_length, 1);
  121. }
  122. static int iscsit_dataout_check_unsolicited_sequence(
  123. struct iscsi_cmd *cmd,
  124. unsigned char *buf)
  125. {
  126. u32 first_burst_len;
  127. struct iscsi_conn *conn = cmd->conn;
  128. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  129. u32 payload_length = ntoh24(hdr->dlength);
  130. if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
  131. ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
  132. pr_err("Command ITT: 0x%08x with Offset: %u,"
  133. " Length: %u outside of Unsolicited Sequence %u:%u while"
  134. " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
  135. be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
  136. cmd->seq_end_offset);
  137. return DATAOUT_CANNOT_RECOVER;
  138. }
  139. first_burst_len = (cmd->first_burst_len + payload_length);
  140. if (first_burst_len > conn->sess->sess_ops->FirstBurstLength) {
  141. pr_err("Total %u bytes exceeds FirstBurstLength: %u"
  142. " for this Unsolicited DataOut Burst.\n",
  143. first_burst_len, conn->sess->sess_ops->FirstBurstLength);
  144. transport_send_check_condition_and_sense(&cmd->se_cmd,
  145. TCM_INCORRECT_AMOUNT_OF_DATA, 0);
  146. return DATAOUT_CANNOT_RECOVER;
  147. }
  148. /*
  149. * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
  150. * checks for the current Unsolicited DataOUT Sequence.
  151. */
  152. if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
  153. /*
  154. * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
  155. * sequence checks are handled in
  156. * iscsit_dataout_datapduinorder_no_fbit().
  157. */
  158. if (!conn->sess->sess_ops->DataPDUInOrder)
  159. goto out;
  160. if ((first_burst_len != cmd->se_cmd.data_length) &&
  161. (first_burst_len != conn->sess->sess_ops->FirstBurstLength)) {
  162. pr_err("Unsolicited non-immediate data"
  163. " received %u does not equal FirstBurstLength: %u, and"
  164. " does not equal ExpXferLen %u.\n", first_burst_len,
  165. conn->sess->sess_ops->FirstBurstLength,
  166. cmd->se_cmd.data_length);
  167. transport_send_check_condition_and_sense(&cmd->se_cmd,
  168. TCM_INCORRECT_AMOUNT_OF_DATA, 0);
  169. return DATAOUT_CANNOT_RECOVER;
  170. }
  171. } else {
  172. if (first_burst_len == conn->sess->sess_ops->FirstBurstLength) {
  173. pr_err("Command ITT: 0x%08x reached"
  174. " FirstBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
  175. " error.\n", cmd->init_task_tag,
  176. conn->sess->sess_ops->FirstBurstLength);
  177. return DATAOUT_CANNOT_RECOVER;
  178. }
  179. if (first_burst_len == cmd->se_cmd.data_length) {
  180. pr_err("Command ITT: 0x%08x reached"
  181. " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
  182. " error.\n", cmd->init_task_tag, cmd->se_cmd.data_length);
  183. return DATAOUT_CANNOT_RECOVER;
  184. }
  185. }
  186. out:
  187. return DATAOUT_NORMAL;
  188. }
  189. static int iscsit_dataout_check_sequence(
  190. struct iscsi_cmd *cmd,
  191. unsigned char *buf)
  192. {
  193. u32 next_burst_len;
  194. struct iscsi_conn *conn = cmd->conn;
  195. struct iscsi_seq *seq = NULL;
  196. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  197. u32 payload_length = ntoh24(hdr->dlength);
  198. /*
  199. * For DataSequenceInOrder=Yes: Check that the offset and offset+length
  200. * is within range as defined by iscsi_set_dataout_sequence_values().
  201. *
  202. * For DataSequenceInOrder=No: Check that an struct iscsi_seq exists for
  203. * offset+length tuple.
  204. */
  205. if (conn->sess->sess_ops->DataSequenceInOrder) {
  206. /*
  207. * Due to possibility of recovery DataOUT sent by the initiator
  208. * fullfilling an Recovery R2T, it's best to just dump the
  209. * payload here, instead of erroring out.
  210. */
  211. if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
  212. ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
  213. pr_err("Command ITT: 0x%08x with Offset: %u,"
  214. " Length: %u outside of Sequence %u:%u while"
  215. " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
  216. be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
  217. cmd->seq_end_offset);
  218. if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
  219. return DATAOUT_CANNOT_RECOVER;
  220. return DATAOUT_WITHIN_COMMAND_RECOVERY;
  221. }
  222. next_burst_len = (cmd->next_burst_len + payload_length);
  223. } else {
  224. seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
  225. payload_length);
  226. if (!seq)
  227. return DATAOUT_CANNOT_RECOVER;
  228. /*
  229. * Set the struct iscsi_seq pointer to reuse later.
  230. */
  231. cmd->seq_ptr = seq;
  232. if (seq->status == DATAOUT_SEQUENCE_COMPLETE) {
  233. if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
  234. return DATAOUT_CANNOT_RECOVER;
  235. return DATAOUT_WITHIN_COMMAND_RECOVERY;
  236. }
  237. next_burst_len = (seq->next_burst_len + payload_length);
  238. }
  239. if (next_burst_len > conn->sess->sess_ops->MaxBurstLength) {
  240. pr_err("Command ITT: 0x%08x, NextBurstLength: %u and"
  241. " Length: %u exceeds MaxBurstLength: %u. protocol"
  242. " error.\n", cmd->init_task_tag,
  243. (next_burst_len - payload_length),
  244. payload_length, conn->sess->sess_ops->MaxBurstLength);
  245. return DATAOUT_CANNOT_RECOVER;
  246. }
  247. /*
  248. * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
  249. * checks for the current DataOUT Sequence.
  250. */
  251. if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
  252. /*
  253. * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
  254. * sequence checks are handled in
  255. * iscsit_dataout_datapduinorder_no_fbit().
  256. */
  257. if (!conn->sess->sess_ops->DataPDUInOrder)
  258. goto out;
  259. if (conn->sess->sess_ops->DataSequenceInOrder) {
  260. if ((next_burst_len <
  261. conn->sess->sess_ops->MaxBurstLength) &&
  262. ((cmd->write_data_done + payload_length) <
  263. cmd->se_cmd.data_length)) {
  264. pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
  265. " before end of DataOUT sequence, protocol"
  266. " error.\n", cmd->init_task_tag);
  267. return DATAOUT_CANNOT_RECOVER;
  268. }
  269. } else {
  270. if (next_burst_len < seq->xfer_len) {
  271. pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
  272. " before end of DataOUT sequence, protocol"
  273. " error.\n", cmd->init_task_tag);
  274. return DATAOUT_CANNOT_RECOVER;
  275. }
  276. }
  277. } else {
  278. if (conn->sess->sess_ops->DataSequenceInOrder) {
  279. if (next_burst_len ==
  280. conn->sess->sess_ops->MaxBurstLength) {
  281. pr_err("Command ITT: 0x%08x reached"
  282. " MaxBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is"
  283. " not set, protocol error.", cmd->init_task_tag,
  284. conn->sess->sess_ops->MaxBurstLength);
  285. return DATAOUT_CANNOT_RECOVER;
  286. }
  287. if ((cmd->write_data_done + payload_length) ==
  288. cmd->se_cmd.data_length) {
  289. pr_err("Command ITT: 0x%08x reached"
  290. " last DataOUT PDU in sequence but ISCSI_FLAG_"
  291. "CMD_FINAL is not set, protocol error.\n",
  292. cmd->init_task_tag);
  293. return DATAOUT_CANNOT_RECOVER;
  294. }
  295. } else {
  296. if (next_burst_len == seq->xfer_len) {
  297. pr_err("Command ITT: 0x%08x reached"
  298. " last DataOUT PDU in sequence but ISCSI_FLAG_"
  299. "CMD_FINAL is not set, protocol error.\n",
  300. cmd->init_task_tag);
  301. return DATAOUT_CANNOT_RECOVER;
  302. }
  303. }
  304. }
  305. out:
  306. return DATAOUT_NORMAL;
  307. }
  308. static int iscsit_dataout_check_datasn(
  309. struct iscsi_cmd *cmd,
  310. unsigned char *buf)
  311. {
  312. u32 data_sn = 0;
  313. struct iscsi_conn *conn = cmd->conn;
  314. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  315. u32 payload_length = ntoh24(hdr->dlength);
  316. /*
  317. * Considering the target has no method of re-requesting DataOUT
  318. * by DataSN, if we receieve a greater DataSN than expected we
  319. * assume the functions for DataPDUInOrder=[Yes,No] below will
  320. * handle it.
  321. *
  322. * If the DataSN is less than expected, dump the payload.
  323. */
  324. if (conn->sess->sess_ops->DataSequenceInOrder)
  325. data_sn = cmd->data_sn;
  326. else {
  327. struct iscsi_seq *seq = cmd->seq_ptr;
  328. data_sn = seq->data_sn;
  329. }
  330. if (be32_to_cpu(hdr->datasn) > data_sn) {
  331. pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
  332. " higher than expected 0x%08x.\n", cmd->init_task_tag,
  333. be32_to_cpu(hdr->datasn), data_sn);
  334. goto recover;
  335. } else if (be32_to_cpu(hdr->datasn) < data_sn) {
  336. pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
  337. " lower than expected 0x%08x, discarding payload.\n",
  338. cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
  339. goto dump;
  340. }
  341. return DATAOUT_NORMAL;
  342. recover:
  343. if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
  344. pr_err("Unable to perform within-command recovery"
  345. " while ERL=0.\n");
  346. return DATAOUT_CANNOT_RECOVER;
  347. }
  348. dump:
  349. if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
  350. return DATAOUT_CANNOT_RECOVER;
  351. return DATAOUT_WITHIN_COMMAND_RECOVERY;
  352. }
  353. static int iscsit_dataout_pre_datapduinorder_yes(
  354. struct iscsi_cmd *cmd,
  355. unsigned char *buf)
  356. {
  357. int dump = 0, recovery = 0;
  358. struct iscsi_conn *conn = cmd->conn;
  359. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  360. u32 payload_length = ntoh24(hdr->dlength);
  361. /*
  362. * For DataSequenceInOrder=Yes: If the offset is greater than the global
  363. * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has
  364. * occurred and fail the connection.
  365. *
  366. * For DataSequenceInOrder=No: If the offset is greater than the per
  367. * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
  368. * error has occurred and fail the connection.
  369. */
  370. if (conn->sess->sess_ops->DataSequenceInOrder) {
  371. if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
  372. pr_err("Command ITT: 0x%08x, received offset"
  373. " %u different than expected %u.\n", cmd->init_task_tag,
  374. be32_to_cpu(hdr->offset), cmd->write_data_done);
  375. recovery = 1;
  376. goto recover;
  377. }
  378. } else {
  379. struct iscsi_seq *seq = cmd->seq_ptr;
  380. if (be32_to_cpu(hdr->offset) > seq->offset) {
  381. pr_err("Command ITT: 0x%08x, received offset"
  382. " %u greater than expected %u.\n", cmd->init_task_tag,
  383. be32_to_cpu(hdr->offset), seq->offset);
  384. recovery = 1;
  385. goto recover;
  386. } else if (be32_to_cpu(hdr->offset) < seq->offset) {
  387. pr_err("Command ITT: 0x%08x, received offset"
  388. " %u less than expected %u, discarding payload.\n",
  389. cmd->init_task_tag, be32_to_cpu(hdr->offset),
  390. seq->offset);
  391. dump = 1;
  392. goto dump;
  393. }
  394. }
  395. return DATAOUT_NORMAL;
  396. recover:
  397. if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
  398. pr_err("Unable to perform within-command recovery"
  399. " while ERL=0.\n");
  400. return DATAOUT_CANNOT_RECOVER;
  401. }
  402. dump:
  403. if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
  404. return DATAOUT_CANNOT_RECOVER;
  405. return (recovery) ? iscsit_recover_dataout_sequence(cmd,
  406. be32_to_cpu(hdr->offset), payload_length) :
  407. (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
  408. }
  409. static int iscsit_dataout_pre_datapduinorder_no(
  410. struct iscsi_cmd *cmd,
  411. unsigned char *buf)
  412. {
  413. struct iscsi_pdu *pdu;
  414. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  415. u32 payload_length = ntoh24(hdr->dlength);
  416. pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
  417. payload_length);
  418. if (!pdu)
  419. return DATAOUT_CANNOT_RECOVER;
  420. cmd->pdu_ptr = pdu;
  421. switch (pdu->status) {
  422. case ISCSI_PDU_NOT_RECEIVED:
  423. case ISCSI_PDU_CRC_FAILED:
  424. case ISCSI_PDU_TIMED_OUT:
  425. break;
  426. case ISCSI_PDU_RECEIVED_OK:
  427. pr_err("Command ITT: 0x%08x received already gotten"
  428. " Offset: %u, Length: %u\n", cmd->init_task_tag,
  429. be32_to_cpu(hdr->offset), payload_length);
  430. return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
  431. default:
  432. return DATAOUT_CANNOT_RECOVER;
  433. }
  434. return DATAOUT_NORMAL;
  435. }
  436. static int iscsit_dataout_update_r2t(struct iscsi_cmd *cmd, u32 offset, u32 length)
  437. {
  438. struct iscsi_r2t *r2t;
  439. if (cmd->unsolicited_data)
  440. return 0;
  441. r2t = iscsit_get_r2t_for_eos(cmd, offset, length);
  442. if (!r2t)
  443. return -1;
  444. spin_lock_bh(&cmd->r2t_lock);
  445. r2t->seq_complete = 1;
  446. cmd->outstanding_r2ts--;
  447. spin_unlock_bh(&cmd->r2t_lock);
  448. return 0;
  449. }
  450. static int iscsit_dataout_update_datapduinorder_no(
  451. struct iscsi_cmd *cmd,
  452. u32 data_sn,
  453. int f_bit)
  454. {
  455. int ret = 0;
  456. struct iscsi_pdu *pdu = cmd->pdu_ptr;
  457. pdu->data_sn = data_sn;
  458. switch (pdu->status) {
  459. case ISCSI_PDU_NOT_RECEIVED:
  460. pdu->status = ISCSI_PDU_RECEIVED_OK;
  461. break;
  462. case ISCSI_PDU_CRC_FAILED:
  463. pdu->status = ISCSI_PDU_RECEIVED_OK;
  464. break;
  465. case ISCSI_PDU_TIMED_OUT:
  466. pdu->status = ISCSI_PDU_RECEIVED_OK;
  467. break;
  468. default:
  469. return DATAOUT_CANNOT_RECOVER;
  470. }
  471. if (f_bit) {
  472. ret = iscsit_dataout_datapduinorder_no_fbit(cmd, pdu);
  473. if (ret == DATAOUT_CANNOT_RECOVER)
  474. return ret;
  475. }
  476. return DATAOUT_NORMAL;
  477. }
  478. static int iscsit_dataout_post_crc_passed(
  479. struct iscsi_cmd *cmd,
  480. unsigned char *buf)
  481. {
  482. int ret, send_r2t = 0;
  483. struct iscsi_conn *conn = cmd->conn;
  484. struct iscsi_seq *seq = NULL;
  485. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  486. u32 payload_length = ntoh24(hdr->dlength);
  487. if (cmd->unsolicited_data) {
  488. if ((cmd->first_burst_len + payload_length) ==
  489. conn->sess->sess_ops->FirstBurstLength) {
  490. if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
  491. payload_length) < 0)
  492. return DATAOUT_CANNOT_RECOVER;
  493. send_r2t = 1;
  494. }
  495. if (!conn->sess->sess_ops->DataPDUInOrder) {
  496. ret = iscsit_dataout_update_datapduinorder_no(cmd,
  497. be32_to_cpu(hdr->datasn),
  498. (hdr->flags & ISCSI_FLAG_CMD_FINAL));
  499. if (ret == DATAOUT_CANNOT_RECOVER)
  500. return ret;
  501. }
  502. cmd->first_burst_len += payload_length;
  503. if (conn->sess->sess_ops->DataSequenceInOrder)
  504. cmd->data_sn++;
  505. else {
  506. seq = cmd->seq_ptr;
  507. seq->data_sn++;
  508. seq->offset += payload_length;
  509. }
  510. if (send_r2t) {
  511. if (seq)
  512. seq->status = DATAOUT_SEQUENCE_COMPLETE;
  513. cmd->first_burst_len = 0;
  514. cmd->unsolicited_data = 0;
  515. }
  516. } else {
  517. if (conn->sess->sess_ops->DataSequenceInOrder) {
  518. if ((cmd->next_burst_len + payload_length) ==
  519. conn->sess->sess_ops->MaxBurstLength) {
  520. if (iscsit_dataout_update_r2t(cmd,
  521. be32_to_cpu(hdr->offset),
  522. payload_length) < 0)
  523. return DATAOUT_CANNOT_RECOVER;
  524. send_r2t = 1;
  525. }
  526. if (!conn->sess->sess_ops->DataPDUInOrder) {
  527. ret = iscsit_dataout_update_datapduinorder_no(
  528. cmd, be32_to_cpu(hdr->datasn),
  529. (hdr->flags & ISCSI_FLAG_CMD_FINAL));
  530. if (ret == DATAOUT_CANNOT_RECOVER)
  531. return ret;
  532. }
  533. cmd->next_burst_len += payload_length;
  534. cmd->data_sn++;
  535. if (send_r2t)
  536. cmd->next_burst_len = 0;
  537. } else {
  538. seq = cmd->seq_ptr;
  539. if ((seq->next_burst_len + payload_length) ==
  540. seq->xfer_len) {
  541. if (iscsit_dataout_update_r2t(cmd,
  542. be32_to_cpu(hdr->offset),
  543. payload_length) < 0)
  544. return DATAOUT_CANNOT_RECOVER;
  545. send_r2t = 1;
  546. }
  547. if (!conn->sess->sess_ops->DataPDUInOrder) {
  548. ret = iscsit_dataout_update_datapduinorder_no(
  549. cmd, be32_to_cpu(hdr->datasn),
  550. (hdr->flags & ISCSI_FLAG_CMD_FINAL));
  551. if (ret == DATAOUT_CANNOT_RECOVER)
  552. return ret;
  553. }
  554. seq->data_sn++;
  555. seq->offset += payload_length;
  556. seq->next_burst_len += payload_length;
  557. if (send_r2t) {
  558. seq->next_burst_len = 0;
  559. seq->status = DATAOUT_SEQUENCE_COMPLETE;
  560. }
  561. }
  562. }
  563. if (send_r2t && conn->sess->sess_ops->DataSequenceInOrder)
  564. cmd->data_sn = 0;
  565. cmd->write_data_done += payload_length;
  566. if (cmd->write_data_done == cmd->se_cmd.data_length)
  567. return DATAOUT_SEND_TO_TRANSPORT;
  568. else if (send_r2t)
  569. return DATAOUT_SEND_R2T;
  570. else
  571. return DATAOUT_NORMAL;
  572. }
  573. static int iscsit_dataout_post_crc_failed(
  574. struct iscsi_cmd *cmd,
  575. unsigned char *buf)
  576. {
  577. struct iscsi_conn *conn = cmd->conn;
  578. struct iscsi_pdu *pdu;
  579. struct iscsi_data *hdr = (struct iscsi_data *) buf;
  580. u32 payload_length = ntoh24(hdr->dlength);
  581. if (conn->sess->sess_ops->DataPDUInOrder)
  582. goto recover;
  583. /*
  584. * The rest of this function is only called when DataPDUInOrder=No.
  585. */
  586. pdu = cmd->pdu_ptr;
  587. switch (pdu->status) {
  588. case ISCSI_PDU_NOT_RECEIVED:
  589. pdu->status = ISCSI_PDU_CRC_FAILED;
  590. break;
  591. case ISCSI_PDU_CRC_FAILED:
  592. break;
  593. case ISCSI_PDU_TIMED_OUT:
  594. pdu->status = ISCSI_PDU_CRC_FAILED;
  595. break;
  596. default:
  597. return DATAOUT_CANNOT_RECOVER;
  598. }
  599. recover:
  600. return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
  601. payload_length);
  602. }
  603. /*
  604. * Called from iscsit_handle_data_out() before DataOUT Payload is received
  605. * and CRC computed.
  606. */
  607. int iscsit_check_pre_dataout(
  608. struct iscsi_cmd *cmd,
  609. unsigned char *buf)
  610. {
  611. int ret;
  612. struct iscsi_conn *conn = cmd->conn;
  613. ret = iscsit_dataout_within_command_recovery_check(cmd, buf);
  614. if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
  615. (ret == DATAOUT_CANNOT_RECOVER))
  616. return ret;
  617. ret = iscsit_dataout_check_datasn(cmd, buf);
  618. if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
  619. (ret == DATAOUT_CANNOT_RECOVER))
  620. return ret;
  621. if (cmd->unsolicited_data) {
  622. ret = iscsit_dataout_check_unsolicited_sequence(cmd, buf);
  623. if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
  624. (ret == DATAOUT_CANNOT_RECOVER))
  625. return ret;
  626. } else {
  627. ret = iscsit_dataout_check_sequence(cmd, buf);
  628. if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
  629. (ret == DATAOUT_CANNOT_RECOVER))
  630. return ret;
  631. }
  632. return (conn->sess->sess_ops->DataPDUInOrder) ?
  633. iscsit_dataout_pre_datapduinorder_yes(cmd, buf) :
  634. iscsit_dataout_pre_datapduinorder_no(cmd, buf);
  635. }
  636. /*
  637. * Called from iscsit_handle_data_out() after DataOUT Payload is received
  638. * and CRC computed.
  639. */
  640. int iscsit_check_post_dataout(
  641. struct iscsi_cmd *cmd,
  642. unsigned char *buf,
  643. u8 data_crc_failed)
  644. {
  645. struct iscsi_conn *conn = cmd->conn;
  646. cmd->dataout_timeout_retries = 0;
  647. if (!data_crc_failed)
  648. return iscsit_dataout_post_crc_passed(cmd, buf);
  649. else {
  650. if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
  651. pr_err("Unable to recover from DataOUT CRC"
  652. " failure while ERL=0, closing session.\n");
  653. iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
  654. buf);
  655. return DATAOUT_CANNOT_RECOVER;
  656. }
  657. iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
  658. return iscsit_dataout_post_crc_failed(cmd, buf);
  659. }
  660. }
  661. static void iscsit_handle_time2retain_timeout(unsigned long data)
  662. {
  663. struct iscsi_session *sess = (struct iscsi_session *) data;
  664. struct iscsi_portal_group *tpg = sess->tpg;
  665. struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
  666. spin_lock_bh(&se_tpg->session_lock);
  667. if (sess->time2retain_timer_flags & ISCSI_TF_STOP) {
  668. spin_unlock_bh(&se_tpg->session_lock);
  669. return;
  670. }
  671. if (atomic_read(&sess->session_reinstatement)) {
  672. pr_err("Exiting Time2Retain handler because"
  673. " session_reinstatement=1\n");
  674. spin_unlock_bh(&se_tpg->session_lock);
  675. return;
  676. }
  677. sess->time2retain_timer_flags |= ISCSI_TF_EXPIRED;
  678. pr_err("Time2Retain timer expired for SID: %u, cleaning up"
  679. " iSCSI session.\n", sess->sid);
  680. {
  681. struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
  682. if (tiqn) {
  683. spin_lock(&tiqn->sess_err_stats.lock);
  684. strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
  685. (void *)sess->sess_ops->InitiatorName);
  686. tiqn->sess_err_stats.last_sess_failure_type =
  687. ISCSI_SESS_ERR_CXN_TIMEOUT;
  688. tiqn->sess_err_stats.cxn_timeout_errors++;
  689. atomic_long_inc(&sess->conn_timeout_errors);
  690. spin_unlock(&tiqn->sess_err_stats.lock);
  691. }
  692. }
  693. spin_unlock_bh(&se_tpg->session_lock);
  694. iscsit_close_session(sess);
  695. }
  696. void iscsit_start_time2retain_handler(struct iscsi_session *sess)
  697. {
  698. int tpg_active;
  699. /*
  700. * Only start Time2Retain timer when the associated TPG is still in
  701. * an ACTIVE (eg: not disabled or shutdown) state.
  702. */
  703. spin_lock(&sess->tpg->tpg_state_lock);
  704. tpg_active = (sess->tpg->tpg_state == TPG_STATE_ACTIVE);
  705. spin_unlock(&sess->tpg->tpg_state_lock);
  706. if (!tpg_active)
  707. return;
  708. if (sess->time2retain_timer_flags & ISCSI_TF_RUNNING)
  709. return;
  710. pr_debug("Starting Time2Retain timer for %u seconds on"
  711. " SID: %u\n", sess->sess_ops->DefaultTime2Retain, sess->sid);
  712. init_timer(&sess->time2retain_timer);
  713. sess->time2retain_timer.expires =
  714. (get_jiffies_64() + sess->sess_ops->DefaultTime2Retain * HZ);
  715. sess->time2retain_timer.data = (unsigned long)sess;
  716. sess->time2retain_timer.function = iscsit_handle_time2retain_timeout;
  717. sess->time2retain_timer_flags &= ~ISCSI_TF_STOP;
  718. sess->time2retain_timer_flags |= ISCSI_TF_RUNNING;
  719. add_timer(&sess->time2retain_timer);
  720. }
  721. /*
  722. * Called with spin_lock_bh(&struct se_portal_group->session_lock) held
  723. */
  724. int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
  725. {
  726. struct iscsi_portal_group *tpg = sess->tpg;
  727. struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
  728. if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)
  729. return -1;
  730. if (!(sess->time2retain_timer_flags & ISCSI_TF_RUNNING))
  731. return 0;
  732. sess->time2retain_timer_flags |= ISCSI_TF_STOP;
  733. spin_unlock(&se_tpg->session_lock);
  734. del_timer_sync(&sess->time2retain_timer);
  735. spin_lock(&se_tpg->session_lock);
  736. sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
  737. pr_debug("Stopped Time2Retain Timer for SID: %u\n",
  738. sess->sid);
  739. return 0;
  740. }
  741. void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn)
  742. {
  743. spin_lock_bh(&conn->state_lock);
  744. if (atomic_read(&conn->connection_exit)) {
  745. spin_unlock_bh(&conn->state_lock);
  746. goto sleep;
  747. }
  748. if (atomic_read(&conn->transport_failed)) {
  749. spin_unlock_bh(&conn->state_lock);
  750. goto sleep;
  751. }
  752. spin_unlock_bh(&conn->state_lock);
  753. if (conn->tx_thread && conn->tx_thread_active)
  754. send_sig(SIGINT, conn->tx_thread, 1);
  755. if (conn->rx_thread && conn->rx_thread_active)
  756. send_sig(SIGINT, conn->rx_thread, 1);
  757. sleep:
  758. wait_for_completion(&conn->conn_wait_rcfr_comp);
  759. complete(&conn->conn_post_wait_comp);
  760. }
  761. void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
  762. {
  763. spin_lock_bh(&conn->state_lock);
  764. if (atomic_read(&conn->connection_exit)) {
  765. spin_unlock_bh(&conn->state_lock);
  766. return;
  767. }
  768. if (atomic_read(&conn->transport_failed)) {
  769. spin_unlock_bh(&conn->state_lock);
  770. return;
  771. }
  772. if (atomic_read(&conn->connection_reinstatement)) {
  773. spin_unlock_bh(&conn->state_lock);
  774. return;
  775. }
  776. if (conn->tx_thread && conn->tx_thread_active)
  777. send_sig(SIGINT, conn->tx_thread, 1);
  778. if (conn->rx_thread && conn->rx_thread_active)
  779. send_sig(SIGINT, conn->rx_thread, 1);
  780. atomic_set(&conn->connection_reinstatement, 1);
  781. if (!sleep) {
  782. spin_unlock_bh(&conn->state_lock);
  783. return;
  784. }
  785. atomic_set(&conn->sleep_on_conn_wait_comp, 1);
  786. spin_unlock_bh(&conn->state_lock);
  787. wait_for_completion(&conn->conn_wait_comp);
  788. complete(&conn->conn_post_wait_comp);
  789. }
  790. EXPORT_SYMBOL(iscsit_cause_connection_reinstatement);
  791. void iscsit_fall_back_to_erl0(struct iscsi_session *sess)
  792. {
  793. pr_debug("Falling back to ErrorRecoveryLevel=0 for SID:"
  794. " %u\n", sess->sid);
  795. atomic_set(&sess->session_fall_back_to_erl0, 1);
  796. }
  797. static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
  798. {
  799. struct iscsi_session *sess = conn->sess;
  800. if ((sess->sess_ops->ErrorRecoveryLevel == 2) &&
  801. !atomic_read(&sess->session_reinstatement) &&
  802. !atomic_read(&sess->session_fall_back_to_erl0))
  803. iscsit_connection_recovery_transport_reset(conn);
  804. else {
  805. pr_debug("Performing cleanup for failed iSCSI"
  806. " Connection ID: %hu from %s\n", conn->cid,
  807. sess->sess_ops->InitiatorName);
  808. iscsit_close_connection(conn);
  809. }
  810. }
  811. void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn, bool *conn_freed)
  812. {
  813. *conn_freed = false;
  814. spin_lock_bh(&conn->state_lock);
  815. if (atomic_read(&conn->connection_exit)) {
  816. spin_unlock_bh(&conn->state_lock);
  817. return;
  818. }
  819. atomic_set(&conn->connection_exit, 1);
  820. if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
  821. spin_unlock_bh(&conn->state_lock);
  822. iscsit_close_connection(conn);
  823. *conn_freed = true;
  824. return;
  825. }
  826. if (conn->conn_state == TARG_CONN_STATE_CLEANUP_WAIT) {
  827. spin_unlock_bh(&conn->state_lock);
  828. return;
  829. }
  830. pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
  831. conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
  832. spin_unlock_bh(&conn->state_lock);
  833. iscsit_handle_connection_cleanup(conn);
  834. *conn_freed = true;
  835. }