iscsi_target_erl0.c 27 KB

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