hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/scsi/iscsi_tcp.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * iSCSI Initiator over TCP/IP Data-Path
34 *
....@@ -6,16 +7,6 @@
67 * Copyright (C) 2005 - 2006 Mike Christie
78 * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
89 * maintained by open-iscsi@googlegroups.com
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License as published
12
- * by the Free Software Foundation; either version 2 of the License, or
13
- * (at your option) any later version.
14
- *
15
- * This program is distributed in the hope that it will be useful, but
16
- * WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * General Public License for more details.
1910 *
2011 * See the file COPYING included with this distribution for more details.
2112 *
....@@ -44,6 +35,7 @@
4435 #include <scsi/scsi_host.h>
4536 #include <scsi/scsi.h>
4637 #include <scsi/scsi_transport_iscsi.h>
38
+#include <trace/events/iscsi.h>
4739
4840 #include "iscsi_tcp.h"
4941
....@@ -72,6 +64,9 @@
7264 iscsi_conn_printk(KERN_INFO, _conn, \
7365 "%s " dbg_fmt, \
7466 __func__, ##arg); \
67
+ iscsi_dbg_trace(trace_iscsi_dbg_sw_tcp, \
68
+ &(_conn)->cls_conn->dev, \
69
+ "%s " dbg_fmt, __func__, ##arg);\
7570 } while (0);
7671
7772
....@@ -522,7 +517,7 @@
522517 if (!task->sc)
523518 iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count);
524519 else {
525
- struct scsi_data_buffer *sdb = scsi_out(task->sc);
520
+ struct scsi_data_buffer *sdb = &task->sc->sdb;
526521
527522 err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl,
528523 sdb->table.nents, offset,
....@@ -563,6 +558,8 @@
563558 tcp_conn = conn->dd_data;
564559 tcp_sw_conn = tcp_conn->dd_data;
565560
561
+ mutex_init(&tcp_sw_conn->sock_lock);
562
+
566563 tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
567564 if (IS_ERR(tfm))
568565 goto free_conn;
....@@ -597,11 +594,15 @@
597594
598595 static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
599596 {
600
- struct iscsi_session *session = conn->session;
601597 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
602598 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
603599 struct socket *sock = tcp_sw_conn->sock;
604600
601
+ /*
602
+ * The iscsi transport class will make sure we are not called in
603
+ * parallel with start, stop, bind and destroys. However, this can be
604
+ * called twice if userspace does a stop then a destroy.
605
+ */
605606 if (!sock)
606607 return;
607608
....@@ -609,9 +610,9 @@
609610 iscsi_sw_tcp_conn_restore_callbacks(conn);
610611 sock_put(sock->sk);
611612
612
- spin_lock_bh(&session->frwd_lock);
613
+ mutex_lock(&tcp_sw_conn->sock_lock);
613614 tcp_sw_conn->sock = NULL;
614
- spin_unlock_bh(&session->frwd_lock);
615
+ mutex_unlock(&tcp_sw_conn->sock_lock);
615616 sockfd_put(sock);
616617 }
617618
....@@ -663,7 +664,6 @@
663664 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
664665 int is_leading)
665666 {
666
- struct iscsi_session *session = cls_session->dd_data;
667667 struct iscsi_conn *conn = cls_conn->dd_data;
668668 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
669669 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
....@@ -683,10 +683,10 @@
683683 if (err)
684684 goto free_socket;
685685
686
- spin_lock_bh(&session->frwd_lock);
686
+ mutex_lock(&tcp_sw_conn->sock_lock);
687687 /* bind iSCSI connection and socket */
688688 tcp_sw_conn->sock = sock;
689
- spin_unlock_bh(&session->frwd_lock);
689
+ mutex_unlock(&tcp_sw_conn->sock_lock);
690690
691691 /* setup Socket parameters */
692692 sk = sock->sk;
....@@ -721,9 +721,15 @@
721721 iscsi_set_param(cls_conn, param, buf, buflen);
722722 break;
723723 case ISCSI_PARAM_DATADGST_EN:
724
+ mutex_lock(&tcp_sw_conn->sock_lock);
725
+ if (!tcp_sw_conn->sock) {
726
+ mutex_unlock(&tcp_sw_conn->sock_lock);
727
+ return -ENOTCONN;
728
+ }
724729 iscsi_set_param(cls_conn, param, buf, buflen);
725730 tcp_sw_conn->sendpage = conn->datadgst_en ?
726731 sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
732
+ mutex_unlock(&tcp_sw_conn->sock_lock);
727733 break;
728734 case ISCSI_PARAM_MAX_R2T:
729735 return iscsi_tcp_set_max_r2t(conn, buf);
....@@ -738,9 +744,10 @@
738744 enum iscsi_param param, char *buf)
739745 {
740746 struct iscsi_conn *conn = cls_conn->dd_data;
741
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
742
- struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
747
+ struct iscsi_sw_tcp_conn *tcp_sw_conn;
748
+ struct iscsi_tcp_conn *tcp_conn;
743749 struct sockaddr_in6 addr;
750
+ struct socket *sock;
744751 int rc;
745752
746753 switch(param) {
....@@ -748,17 +755,36 @@
748755 case ISCSI_PARAM_CONN_ADDRESS:
749756 case ISCSI_PARAM_LOCAL_PORT:
750757 spin_lock_bh(&conn->session->frwd_lock);
751
- if (!tcp_sw_conn || !tcp_sw_conn->sock) {
758
+ if (!conn->session->leadconn) {
752759 spin_unlock_bh(&conn->session->frwd_lock);
753760 return -ENOTCONN;
754761 }
762
+ /*
763
+ * The conn has been setup and bound, so just grab a ref
764
+ * incase a destroy runs while we are in the net layer.
765
+ */
766
+ iscsi_get_conn(conn->cls_conn);
767
+ spin_unlock_bh(&conn->session->frwd_lock);
768
+
769
+ tcp_conn = conn->dd_data;
770
+ tcp_sw_conn = tcp_conn->dd_data;
771
+
772
+ mutex_lock(&tcp_sw_conn->sock_lock);
773
+ sock = tcp_sw_conn->sock;
774
+ if (!sock) {
775
+ rc = -ENOTCONN;
776
+ goto sock_unlock;
777
+ }
778
+
755779 if (param == ISCSI_PARAM_LOCAL_PORT)
756
- rc = kernel_getsockname(tcp_sw_conn->sock,
780
+ rc = kernel_getsockname(sock,
757781 (struct sockaddr *)&addr);
758782 else
759
- rc = kernel_getpeername(tcp_sw_conn->sock,
783
+ rc = kernel_getpeername(sock,
760784 (struct sockaddr *)&addr);
761
- spin_unlock_bh(&conn->session->frwd_lock);
785
+sock_unlock:
786
+ mutex_unlock(&tcp_sw_conn->sock_lock);
787
+ iscsi_put_conn(conn->cls_conn);
762788 if (rc < 0)
763789 return rc;
764790
....@@ -775,15 +801,17 @@
775801 enum iscsi_host_param param, char *buf)
776802 {
777803 struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
778
- struct iscsi_session *session = tcp_sw_host->session;
804
+ struct iscsi_session *session;
779805 struct iscsi_conn *conn;
780806 struct iscsi_tcp_conn *tcp_conn;
781807 struct iscsi_sw_tcp_conn *tcp_sw_conn;
782808 struct sockaddr_in6 addr;
809
+ struct socket *sock;
783810 int rc;
784811
785812 switch (param) {
786813 case ISCSI_HOST_PARAM_IPADDRESS:
814
+ session = tcp_sw_host->session;
787815 if (!session)
788816 return -ENOTCONN;
789817
....@@ -794,16 +822,22 @@
794822 return -ENOTCONN;
795823 }
796824 tcp_conn = conn->dd_data;
797
-
798825 tcp_sw_conn = tcp_conn->dd_data;
799
- if (!tcp_sw_conn->sock) {
800
- spin_unlock_bh(&session->frwd_lock);
801
- return -ENOTCONN;
802
- }
803
-
804
- rc = kernel_getsockname(tcp_sw_conn->sock,
805
- (struct sockaddr *)&addr);
826
+ /*
827
+ * The conn has been setup and bound, so just grab a ref
828
+ * incase a destroy runs while we are in the net layer.
829
+ */
830
+ iscsi_get_conn(conn->cls_conn);
806831 spin_unlock_bh(&session->frwd_lock);
832
+
833
+ mutex_lock(&tcp_sw_conn->sock_lock);
834
+ sock = tcp_sw_conn->sock;
835
+ if (!sock)
836
+ rc = -ENOTCONN;
837
+ else
838
+ rc = kernel_getsockname(sock, (struct sockaddr *)&addr);
839
+ mutex_unlock(&tcp_sw_conn->sock_lock);
840
+ iscsi_put_conn(conn->cls_conn);
807841 if (rc < 0)
808842 return rc;
809843
....@@ -872,12 +906,14 @@
872906 if (!cls_session)
873907 goto remove_host;
874908 session = cls_session->dd_data;
875
- tcp_sw_host = iscsi_host_priv(shost);
876
- tcp_sw_host->session = session;
877909
878910 shost->can_queue = session->scsi_cmds_max;
879911 if (iscsi_tcp_r2tpool_alloc(session))
880912 goto remove_session;
913
+
914
+ /* We are now fully setup so expose the session to sysfs. */
915
+ tcp_sw_host = iscsi_host_priv(shost);
916
+ tcp_sw_host->session = session;
881917 return cls_session;
882918
883919 remove_session:
....@@ -960,12 +996,6 @@
960996 return 0;
961997 }
962998
963
-static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
964
-{
965
- blk_queue_flag_set(QUEUE_FLAG_BIDI, sdev->request_queue);
966
- return 0;
967
-}
968
-
969999 static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
9701000 {
9711001 struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
....@@ -973,8 +1003,8 @@
9731003 struct iscsi_conn *conn = session->leadconn;
9741004
9751005 if (conn->datadgst_en)
976
- sdev->request_queue->backing_dev_info->capabilities
977
- |= BDI_CAP_STABLE_WRITES;
1006
+ blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES,
1007
+ sdev->request_queue);
9781008 blk_queue_dma_alignment(sdev->request_queue, 0);
9791009 return 0;
9801010 }
....@@ -992,8 +1022,7 @@
9921022 .eh_abort_handler = iscsi_eh_abort,
9931023 .eh_device_reset_handler= iscsi_eh_device_reset,
9941024 .eh_target_reset_handler = iscsi_eh_recover_target,
995
- .use_clustering = DISABLE_CLUSTERING,
996
- .slave_alloc = iscsi_sw_tcp_slave_alloc,
1025
+ .dma_boundary = PAGE_SIZE - 1,
9971026 .slave_configure = iscsi_sw_tcp_slave_configure,
9981027 .target_alloc = iscsi_target_alloc,
9991028 .proc_name = "iscsi_tcp",