forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/target/iscsi/iscsi_target_nego.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*******************************************************************************
23 * This file contains main functions related to iSCSI Parameter negotiation.
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 <linux/ctype.h>
....@@ -160,22 +152,11 @@
160152
161153 if (strstr("None", authtype))
162154 return 1;
163
-#ifdef CANSRP
164
- else if (strstr("SRP", authtype))
165
- return srp_main_loop(conn, auth, in_buf, out_buf,
166
- &in_length, out_length);
167
-#endif
168155 else if (strstr("CHAP", authtype))
169156 return chap_main_loop(conn, auth, in_buf, out_buf,
170157 &in_length, out_length);
171
- else if (strstr("SPKM1", authtype))
172
- return 2;
173
- else if (strstr("SPKM2", authtype))
174
- return 2;
175
- else if (strstr("KRB5", authtype))
176
- return 2;
177
- else
178
- return 2;
158
+ /* SRP, SPKM1, SPKM2 and KRB5 are unsupported */
159
+ return 2;
179160 }
180161
181162 static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
....@@ -500,7 +481,7 @@
500481 {
501482 if (sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) {
502483 pr_debug("__iscsi_target_sk_check_close: TCP_CLOSE_WAIT|TCP_CLOSE,"
503
- "returning FALSE\n");
484
+ "returning TRUE\n");
504485 return true;
505486 }
506487 return false;
....@@ -643,13 +624,37 @@
643624 pr_debug("iscsi_target_do_login_rx after rx_login_io, %p, %s:%d\n",
644625 conn, current->comm, current->pid);
645626
627
+ /*
628
+ * LOGIN_FLAGS_READ_ACTIVE is cleared so that sk_data_ready
629
+ * could be triggered again after this.
630
+ *
631
+ * LOGIN_FLAGS_WRITE_ACTIVE is cleared after we successfully
632
+ * process a login PDU, so that sk_state_chage can do login
633
+ * cleanup as needed if the socket is closed. If a delayed work is
634
+ * ongoing (LOGIN_FLAGS_WRITE_ACTIVE or LOGIN_FLAGS_READ_ACTIVE),
635
+ * sk_state_change will leave the cleanup to the delayed work or
636
+ * it will schedule a delayed work to do cleanup.
637
+ */
638
+ if (conn->sock) {
639
+ struct sock *sk = conn->sock->sk;
640
+
641
+ write_lock_bh(&sk->sk_callback_lock);
642
+ if (!test_bit(LOGIN_FLAGS_INITIAL_PDU, &conn->login_flags)) {
643
+ clear_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags);
644
+ set_bit(LOGIN_FLAGS_WRITE_ACTIVE, &conn->login_flags);
645
+ }
646
+ write_unlock_bh(&sk->sk_callback_lock);
647
+ }
648
+
646649 rc = iscsi_target_do_login(conn, login);
647650 if (rc < 0) {
648651 goto err;
649652 } else if (!rc) {
650
- if (iscsi_target_sk_check_and_clear(conn, LOGIN_FLAGS_READ_ACTIVE))
653
+ if (iscsi_target_sk_check_and_clear(conn,
654
+ LOGIN_FLAGS_WRITE_ACTIVE))
651655 goto err;
652656 } else if (rc == 1) {
657
+ cancel_delayed_work(&conn->login_work);
653658 iscsi_target_nego_release(conn);
654659 iscsi_post_login_handler(np, conn, zero_tsih);
655660 iscsit_deaccess_np(np, tpg, tpg_np);
....@@ -658,6 +663,7 @@
658663
659664 err:
660665 iscsi_target_restore_sock_callbacks(conn);
666
+ cancel_delayed_work(&conn->login_work);
661667 iscsi_target_login_drop(conn, login);
662668 iscsit_deaccess_np(np, tpg, tpg_np);
663669 }
....@@ -688,9 +694,10 @@
688694 state = __iscsi_target_sk_check_close(sk);
689695 pr_debug("__iscsi_target_sk_close_change: state: %d\n", state);
690696
691
- if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) {
692
- pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1 sk_state_change"
693
- " conn: %p\n", conn);
697
+ if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags) ||
698
+ test_bit(LOGIN_FLAGS_WRITE_ACTIVE, &conn->login_flags)) {
699
+ pr_debug("Got LOGIN_FLAGS_{READ|WRITE}_ACTIVE=1"
700
+ " sk_state_change conn: %p\n", conn);
694701 if (state)
695702 set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags);
696703 write_unlock_bh(&sk->sk_callback_lock);
....@@ -1072,6 +1079,7 @@
10721079 iscsi_target_set_sock_callbacks(conn);
10731080
10741081 login->np = np;
1082
+ conn->tpg = NULL;
10751083
10761084 login_req = (struct iscsi_login_req *) login->req;
10771085 payload_length = ntoh24(login_req->dlength);
....@@ -1141,7 +1149,6 @@
11411149 */
11421150 sessiontype = strncmp(s_buf, DISCOVERY, 9);
11431151 if (!sessiontype) {
1144
- conn->tpg = iscsit_global->discovery_tpg;
11451152 if (!login->leading_connection)
11461153 goto get_target;
11471154
....@@ -1158,9 +1165,11 @@
11581165 * Serialize access across the discovery struct iscsi_portal_group to
11591166 * process login attempt.
11601167 */
1168
+ conn->tpg = iscsit_global->discovery_tpg;
11611169 if (iscsit_access_np(np, conn->tpg) < 0) {
11621170 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
11631171 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
1172
+ conn->tpg = NULL;
11641173 ret = -1;
11651174 goto out;
11661175 }