forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/target/iscsi/iscsi_target.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*******************************************************************************
23 * This file contains main functions related to the iSCSI Target Core Driver.
34 *
....@@ -5,15 +6,6 @@
56 *
67 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
78 *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
179 ******************************************************************************/
1810
1911 #include <crypto/hash.h>
....@@ -308,15 +300,14 @@
308300 return false;
309301 }
310302
311
-/*
312
- * Called with mutex np_lock held
313
- */
314303 static struct iscsi_np *iscsit_get_np(
315304 struct sockaddr_storage *sockaddr,
316305 int network_transport)
317306 {
318307 struct iscsi_np *np;
319308 bool match;
309
+
310
+ lockdep_assert_held(&np_lock);
320311
321312 list_for_each_entry(np, &g_np_list, np_list) {
322313 spin_lock_bh(&np->np_thread_lock);
....@@ -573,7 +564,8 @@
573564 return 0;
574565 }
575566
576
-static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
567
+static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec,
568
+ u32 data_offset, u32 data_length);
577569 static void iscsit_unmap_iovec(struct iscsi_cmd *);
578570 static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
579571 u32, u32, u32, u8 *);
....@@ -604,7 +596,8 @@
604596 *header_digest);
605597 }
606598
607
- iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1],
599
+ iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[iov_count],
600
+ cmd->orig_iov_data_count - (iov_count + 2),
608601 datain->offset, datain->length);
609602 if (iov_ret < 0)
610603 return -1;
....@@ -713,7 +706,7 @@
713706 sizeof(struct iscsi_queue_req),
714707 __alignof__(struct iscsi_queue_req), 0, NULL);
715708 if (!lio_qr_cache) {
716
- pr_err("nable to kmem_cache_create() for"
709
+ pr_err("Unable to kmem_cache_create() for"
717710 " lio_qr_cache\n");
718711 goto bitmap_out;
719712 }
....@@ -886,13 +879,10 @@
886879 * Map some portion of the allocated scatterlist to an iovec, suitable for
887880 * kernel sockets to copy data in/out.
888881 */
889
-static int iscsit_map_iovec(
890
- struct iscsi_cmd *cmd,
891
- struct kvec *iov,
892
- u32 data_offset,
893
- u32 data_length)
882
+static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec,
883
+ u32 data_offset, u32 data_length)
894884 {
895
- u32 i = 0;
885
+ u32 i = 0, orig_data_length = data_length;
896886 struct scatterlist *sg;
897887 unsigned int page_off;
898888
....@@ -901,9 +891,12 @@
901891 */
902892 u32 ent = data_offset / PAGE_SIZE;
903893
894
+ if (!data_length)
895
+ return 0;
896
+
904897 if (ent >= cmd->se_cmd.t_data_nents) {
905898 pr_err("Initial page entry out-of-bounds\n");
906
- return -1;
899
+ goto overflow;
907900 }
908901
909902 sg = &cmd->se_cmd.t_data_sg[ent];
....@@ -913,7 +906,12 @@
913906 cmd->first_data_sg_off = page_off;
914907
915908 while (data_length) {
916
- u32 cur_len = min_t(u32, data_length, sg->length - page_off);
909
+ u32 cur_len;
910
+
911
+ if (WARN_ON_ONCE(!sg || i >= nvec))
912
+ goto overflow;
913
+
914
+ cur_len = min_t(u32, data_length, sg->length - page_off);
917915
918916 iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
919917 iov[i].iov_len = cur_len;
....@@ -927,6 +925,16 @@
927925 cmd->kmapped_nents = i;
928926
929927 return i;
928
+
929
+overflow:
930
+ pr_err("offset %d + length %d overflow; %d/%d; sg-list:\n",
931
+ data_offset, orig_data_length, i, nvec);
932
+ for_each_sg(cmd->se_cmd.t_data_sg, sg,
933
+ cmd->se_cmd.t_data_nents, i) {
934
+ pr_err("[%d] off %d len %d\n",
935
+ i, sg->offset, sg->length);
936
+ }
937
+ return -1;
930938 }
931939
932940 static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
....@@ -1149,7 +1157,7 @@
11491157 transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
11501158 conn->sess->se_sess, be32_to_cpu(hdr->data_length),
11511159 cmd->data_direction, sam_task_attr,
1152
- cmd->sense_buffer + 2);
1160
+ cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun));
11531161
11541162 pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
11551163 " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
....@@ -1158,22 +1166,24 @@
11581166
11591167 target_get_sess_cmd(&cmd->se_cmd, true);
11601168
1161
- cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
1162
- scsilun_to_int(&hdr->lun));
1163
- if (cmd->sense_reason)
1164
- goto attach_cmd;
1165
-
1166
- /* only used for printks or comparing with ->ref_task_tag */
11671169 cmd->se_cmd.tag = (__force u32)cmd->init_task_tag;
1168
- cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
1170
+ cmd->sense_reason = target_cmd_init_cdb(&cmd->se_cmd, hdr->cdb);
11691171 if (cmd->sense_reason) {
11701172 if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
11711173 return iscsit_add_reject_cmd(cmd,
1172
- ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1174
+ ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
11731175 }
11741176
11751177 goto attach_cmd;
11761178 }
1179
+
1180
+ cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd);
1181
+ if (cmd->sense_reason)
1182
+ goto attach_cmd;
1183
+
1184
+ cmd->sense_reason = target_cmd_parse_cdb(&cmd->se_cmd);
1185
+ if (cmd->sense_reason)
1186
+ goto attach_cmd;
11771187
11781188 if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
11791189 return iscsit_add_reject_cmd(cmd,
....@@ -1194,7 +1204,7 @@
11941204 }
11951205 EXPORT_SYMBOL(iscsit_setup_scsi_cmd);
11961206
1197
-void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd)
1207
+void iscsit_set_unsolicited_dataout(struct iscsi_cmd *cmd)
11981208 {
11991209 iscsit_set_dataout_sequence_values(cmd);
12001210
....@@ -1202,7 +1212,7 @@
12021212 iscsit_start_dataout_timer(cmd, cmd->conn);
12031213 spin_unlock_bh(&cmd->dataout_timeout_lock);
12041214 }
1205
-EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout);
1215
+EXPORT_SYMBOL(iscsit_set_unsolicited_dataout);
12061216
12071217 int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
12081218 struct iscsi_scsi_req *hdr)
....@@ -1236,7 +1246,7 @@
12361246 */
12371247 if (!cmd->immediate_data) {
12381248 if (!cmd->sense_reason && cmd->unsolicited_data)
1239
- iscsit_set_unsoliticed_dataout(cmd);
1249
+ iscsit_set_unsolicited_dataout(cmd);
12401250 if (!cmd->sense_reason)
12411251 return 0;
12421252
....@@ -1268,27 +1278,27 @@
12681278 bool dump_payload)
12691279 {
12701280 int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
1281
+ int rc;
1282
+
12711283 /*
12721284 * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
12731285 */
1274
- if (dump_payload)
1275
- goto after_immediate_data;
1276
- /*
1277
- * Check for underflow case where both EDTL and immediate data payload
1278
- * exceeds what is presented by CDB's TRANSFER LENGTH, and what has
1279
- * already been set in target_cmd_size_check() as se_cmd->data_length.
1280
- *
1281
- * For this special case, fail the command and dump the immediate data
1282
- * payload.
1283
- */
1284
- if (cmd->first_burst_len > cmd->se_cmd.data_length) {
1285
- cmd->sense_reason = TCM_INVALID_CDB_FIELD;
1286
- goto after_immediate_data;
1286
+ if (dump_payload) {
1287
+ u32 length = min(cmd->se_cmd.data_length - cmd->write_data_done,
1288
+ cmd->first_burst_len);
1289
+
1290
+ pr_debug("Dumping min(%d - %d, %d) = %d bytes of immediate data\n",
1291
+ cmd->se_cmd.data_length, cmd->write_data_done,
1292
+ cmd->first_burst_len, length);
1293
+ rc = iscsit_dump_data_payload(cmd->conn, length, 1);
1294
+ pr_debug("Finished dumping immediate data\n");
1295
+ if (rc < 0)
1296
+ immed_ret = IMMEDIATE_DATA_CANNOT_RECOVER;
1297
+ } else {
1298
+ immed_ret = iscsit_handle_immediate_data(cmd, hdr,
1299
+ cmd->first_burst_len);
12871300 }
12881301
1289
- immed_ret = iscsit_handle_immediate_data(cmd, hdr,
1290
- cmd->first_burst_len);
1291
-after_immediate_data:
12921302 if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) {
12931303 /*
12941304 * A PDU/CmdSN carrying Immediate Data passed
....@@ -1301,14 +1311,11 @@
13011311 return -1;
13021312
13031313 if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1304
- int rc;
1305
-
1306
- rc = iscsit_dump_data_payload(cmd->conn,
1307
- cmd->first_burst_len, 1);
13081314 target_put_sess_cmd(&cmd->se_cmd);
1309
- return rc;
1315
+
1316
+ return 0;
13101317 } else if (cmd->unsolicited_data)
1311
- iscsit_set_unsoliticed_dataout(cmd);
1318
+ iscsit_set_unsolicited_dataout(cmd);
13121319
13131320 } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
13141321 /*
....@@ -1505,8 +1512,6 @@
15051512 if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
15061513 iscsit_stop_dataout_timer(cmd);
15071514
1508
- transport_check_aborted_status(se_cmd,
1509
- (hdr->flags & ISCSI_FLAG_CMD_FINAL));
15101515 return iscsit_dump_data_payload(conn, payload_length, 1);
15111516 }
15121517 } else {
....@@ -1521,12 +1526,9 @@
15211526 * TASK_ABORTED status.
15221527 */
15231528 if (se_cmd->transport_state & CMD_T_ABORTED) {
1524
- if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1525
- if (--cmd->outstanding_r2ts < 1) {
1526
- iscsit_stop_dataout_timer(cmd);
1527
- transport_check_aborted_status(
1528
- se_cmd, 1);
1529
- }
1529
+ if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
1530
+ --cmd->outstanding_r2ts < 1)
1531
+ iscsit_stop_dataout_timer(cmd);
15301532
15311533 return iscsit_dump_data_payload(conn, payload_length, 1);
15321534 }
....@@ -1586,14 +1588,16 @@
15861588 {
15871589 struct kvec *iov;
15881590 u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0;
1589
- u32 payload_length = ntoh24(hdr->dlength);
1591
+ u32 payload_length;
15901592 int iov_ret, data_crc_failed = 0;
15911593
1594
+ payload_length = min_t(u32, cmd->se_cmd.data_length,
1595
+ ntoh24(hdr->dlength));
15921596 rx_size += payload_length;
15931597 iov = &cmd->iov_data[0];
15941598
1595
- iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
1596
- payload_length);
1599
+ iov_ret = iscsit_map_iovec(cmd, iov, cmd->orig_iov_data_count - 2,
1600
+ be32_to_cpu(hdr->offset), payload_length);
15971601 if (iov_ret < 0)
15981602 return -1;
15991603
....@@ -1613,6 +1617,7 @@
16131617 rx_size += ISCSI_CRC_LEN;
16141618 }
16151619
1620
+ WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count);
16161621 rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
16171622
16181623 iscsit_unmap_iovec(cmd);
....@@ -1878,6 +1883,7 @@
18781883 rx_size += ISCSI_CRC_LEN;
18791884 }
18801885
1886
+ WARN_ON_ONCE(niov > ARRAY_SIZE(cmd->iov_misc));
18811887 rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size);
18821888 if (rx_got != rx_size) {
18831889 ret = -1;
....@@ -2008,7 +2014,8 @@
20082014
20092015 transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
20102016 conn->sess->se_sess, 0, DMA_NONE,
2011
- TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
2017
+ TCM_SIMPLE_TAG, cmd->sense_buffer + 2,
2018
+ scsilun_to_int(&hdr->lun));
20122019
20132020 target_get_sess_cmd(&cmd->se_cmd, true);
20142021
....@@ -2046,8 +2053,7 @@
20462053 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
20472054 */
20482055 if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
2049
- ret = transport_lookup_tmr_lun(&cmd->se_cmd,
2050
- scsilun_to_int(&hdr->lun));
2056
+ ret = transport_lookup_tmr_lun(&cmd->se_cmd);
20512057 if (ret < 0) {
20522058 se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
20532059 goto attach;
....@@ -2197,24 +2203,22 @@
21972203 }
21982204 goto empty_sendtargets;
21992205 }
2200
- if (strncmp("SendTargets", text_in, 11) != 0) {
2206
+ if (strncmp("SendTargets=", text_in, 12) != 0) {
22012207 pr_err("Received Text Data that is not"
22022208 " SendTargets, cannot continue.\n");
22032209 goto reject;
22042210 }
2211
+ /* '=' confirmed in strncmp */
22052212 text_ptr = strchr(text_in, '=');
2206
- if (!text_ptr) {
2207
- pr_err("No \"=\" separator found in Text Data,"
2208
- " cannot continue.\n");
2209
- goto reject;
2210
- }
2211
- if (!strncmp("=All", text_ptr, 4)) {
2213
+ BUG_ON(!text_ptr);
2214
+ if (!strncmp("=All", text_ptr, 5)) {
22122215 cmd->cmd_flags |= ICF_SENDTARGETS_ALL;
22132216 } else if (!strncmp("=iqn.", text_ptr, 5) ||
22142217 !strncmp("=eui.", text_ptr, 5)) {
22152218 cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE;
22162219 } else {
2217
- pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
2220
+ pr_err("Unable to locate valid SendTargets%s value\n",
2221
+ text_ptr);
22182222 goto reject;
22192223 }
22202224
....@@ -2258,42 +2262,40 @@
22582262 rx_size = payload_length;
22592263 if (payload_length) {
22602264 u32 checksum = 0, data_crc = 0;
2261
- u32 padding = 0, pad_bytes = 0;
2265
+ u32 padding = 0;
22622266 int niov = 0, rx_got;
2263
- struct kvec iov[3];
2267
+ struct kvec iov[2];
22642268
2265
- text_in = kzalloc(payload_length, GFP_KERNEL);
2269
+ rx_size = ALIGN(payload_length, 4);
2270
+ text_in = kzalloc(rx_size, GFP_KERNEL);
22662271 if (!text_in)
22672272 goto reject;
22682273
22692274 cmd->text_in_ptr = text_in;
22702275
2271
- memset(iov, 0, 3 * sizeof(struct kvec));
2276
+ memset(iov, 0, sizeof(iov));
22722277 iov[niov].iov_base = text_in;
2273
- iov[niov++].iov_len = payload_length;
2278
+ iov[niov++].iov_len = rx_size;
22742279
2275
- padding = ((-payload_length) & 3);
2276
- if (padding != 0) {
2277
- iov[niov].iov_base = &pad_bytes;
2278
- iov[niov++].iov_len = padding;
2279
- rx_size += padding;
2280
+ padding = rx_size - payload_length;
2281
+ if (padding)
22802282 pr_debug("Receiving %u additional bytes"
22812283 " for padding.\n", padding);
2282
- }
22832284 if (conn->conn_ops->DataDigest) {
22842285 iov[niov].iov_base = &checksum;
22852286 iov[niov++].iov_len = ISCSI_CRC_LEN;
22862287 rx_size += ISCSI_CRC_LEN;
22872288 }
22882289
2290
+ WARN_ON_ONCE(niov > ARRAY_SIZE(iov));
22892291 rx_got = rx_data(conn, &iov[0], niov, rx_size);
22902292 if (rx_got != rx_size)
22912293 goto reject;
22922294
22932295 if (conn->conn_ops->DataDigest) {
2294
- iscsit_do_crypto_hash_buf(conn->conn_rx_hash, text_in,
2295
- payload_length, padding,
2296
- &pad_bytes, &data_crc);
2296
+ iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
2297
+ text_in, rx_size, 0, NULL,
2298
+ &data_crc);
22972299
22982300 if (checksum != data_crc) {
22992301 pr_err("Text data CRC32C DataDigest"
....@@ -2596,14 +2598,34 @@
25962598 u32 checksum, iov_count = 0, padding = 0;
25972599 struct iscsi_conn *conn = cmd->conn;
25982600 struct kvec *iov;
2601
+ void *overflow_buf = NULL;
25992602
2600
- iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length);
2603
+ BUG_ON(cmd->write_data_done > cmd->se_cmd.data_length);
2604
+ rx_size = min(cmd->se_cmd.data_length - cmd->write_data_done, length);
2605
+ iov_ret = iscsit_map_iovec(cmd, cmd->iov_data,
2606
+ cmd->orig_iov_data_count - 2,
2607
+ cmd->write_data_done, rx_size);
26012608 if (iov_ret < 0)
26022609 return IMMEDIATE_DATA_CANNOT_RECOVER;
26032610
2604
- rx_size = length;
26052611 iov_count = iov_ret;
26062612 iov = &cmd->iov_data[0];
2613
+ if (rx_size < length) {
2614
+ /*
2615
+ * Special case: length of immediate data exceeds the data
2616
+ * buffer size derived from the CDB.
2617
+ */
2618
+ overflow_buf = kmalloc(length - rx_size, GFP_KERNEL);
2619
+ if (!overflow_buf) {
2620
+ iscsit_unmap_iovec(cmd);
2621
+ return IMMEDIATE_DATA_CANNOT_RECOVER;
2622
+ }
2623
+ cmd->overflow_buf = overflow_buf;
2624
+ iov[iov_count].iov_base = overflow_buf;
2625
+ iov[iov_count].iov_len = length - rx_size;
2626
+ iov_count++;
2627
+ rx_size = length;
2628
+ }
26072629
26082630 padding = ((-length) & 3);
26092631 if (padding != 0) {
....@@ -2618,6 +2640,7 @@
26182640 rx_size += ISCSI_CRC_LEN;
26192641 }
26202642
2643
+ WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count);
26212644 rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
26222645
26232646 iscsit_unmap_iovec(cmd);
....@@ -2672,9 +2695,6 @@
26722695 return IMMEDIATE_DATA_NORMAL_OPERATION;
26732696 }
26742697
2675
-/*
2676
- * Called with sess->conn_lock held.
2677
- */
26782698 /* #warning iscsi_build_conn_drop_async_message() only sends out on connections
26792699 with active network interface */
26802700 static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
....@@ -2682,6 +2702,8 @@
26822702 struct iscsi_cmd *cmd;
26832703 struct iscsi_conn *conn_p;
26842704 bool found = false;
2705
+
2706
+ lockdep_assert_held(&conn->sess->conn_lock);
26852707
26862708 /*
26872709 * Only send a Asynchronous Message on connections whos network
....@@ -3143,6 +3165,12 @@
31433165 else
31443166 xfer_len = conn->sess->sess_ops->MaxBurstLength;
31453167 }
3168
+
3169
+ if ((s32)xfer_len < 0) {
3170
+ cmd->cmd_flags |= ICF_SENT_LAST_R2T;
3171
+ break;
3172
+ }
3173
+
31463174 cmd->r2t_offset += xfer_len;
31473175
31483176 if (cmd->r2t_offset == cmd->se_cmd.data_length)
....@@ -3723,7 +3751,7 @@
37233751 case ISTATE_SEND_LOGOUTRSP:
37243752 if (!iscsit_logout_post_handler(cmd, conn))
37253753 return -ECONNRESET;
3726
- /* fall through */
3754
+ fallthrough;
37273755 case ISTATE_SEND_STATUS:
37283756 case ISTATE_SEND_ASYNCMSG:
37293757 case ISTATE_SEND_NOPIN:
....@@ -4056,9 +4084,12 @@
40564084 list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
40574085 struct se_cmd *se_cmd = &cmd->se_cmd;
40584086
4059
- if (se_cmd->se_tfo != NULL) {
4060
- spin_lock_irq(&se_cmd->t_state_lock);
4061
- if (se_cmd->transport_state & CMD_T_ABORTED) {
4087
+ if (!se_cmd->se_tfo)
4088
+ continue;
4089
+
4090
+ spin_lock_irq(&se_cmd->t_state_lock);
4091
+ if (se_cmd->transport_state & CMD_T_ABORTED) {
4092
+ if (!(se_cmd->transport_state & CMD_T_TAS))
40624093 /*
40634094 * LIO's abort path owns the cleanup for this,
40644095 * so put it back on the list and let
....@@ -4066,11 +4097,10 @@
40664097 */
40674098 list_move_tail(&cmd->i_conn_node,
40684099 &conn->conn_cmd_list);
4069
- } else {
4070
- se_cmd->transport_state |= CMD_T_FABRIC_STOP;
4071
- }
4072
- spin_unlock_irq(&se_cmd->t_state_lock);
4100
+ } else {
4101
+ se_cmd->transport_state |= CMD_T_FABRIC_STOP;
40734102 }
4103
+ spin_unlock_irq(&se_cmd->t_state_lock);
40744104 }
40754105 spin_unlock_bh(&conn->cmd_lock);
40764106
....@@ -4355,6 +4385,9 @@
43554385 iscsit_stop_time2retain_timer(sess);
43564386 spin_unlock_bh(&se_tpg->session_lock);
43574387
4388
+ if (sess->sess_ops->ErrorRecoveryLevel == 2)
4389
+ iscsit_free_connection_recovery_entries(sess);
4390
+
43584391 /*
43594392 * transport_deregister_session_configfs() will clear the
43604393 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
....@@ -4371,8 +4404,7 @@
43714404 * restart the timer and exit.
43724405 */
43734406 if (!in_interrupt()) {
4374
- if (iscsit_check_session_usage_count(sess) == 1)
4375
- iscsit_stop_session(sess, 1, 1);
4407
+ iscsit_check_session_usage_count(sess);
43764408 } else {
43774409 if (iscsit_check_session_usage_count(sess) == 2) {
43784410 atomic_set(&sess->session_logout, 0);
....@@ -4382,9 +4414,6 @@
43824414 }
43834415
43844416 transport_deregister_session(sess->se_sess);
4385
-
4386
- if (sess->sess_ops->ErrorRecoveryLevel == 2)
4387
- iscsit_free_connection_recovery_entires(sess);
43884417
43894418 iscsit_free_all_ooo_cmdsns(sess);
43904419
....@@ -4510,7 +4539,6 @@
45104539 iscsit_logout_post_handler_closesession(conn);
45114540 break;
45124541 }
4513
- ret = 0;
45144542 break;
45154543 case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
45164544 if (conn->cid == cmd->logout_cid) {
....@@ -4521,7 +4549,6 @@
45214549 iscsit_logout_post_handler_samecid(conn);
45224550 break;
45234551 }
4524
- ret = 0;
45254552 } else {
45264553 switch (cmd->logout_response) {
45274554 case ISCSI_LOGOUT_SUCCESS: