Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iscsi-target: Initial traditional TCP conversion to iscsit_transport

This patch performs the initial conversion of existing traditional iscsi
to use iscsit_transport API callers. This includes:

- iscsi-np cleanups for iscsit_transport_type
- Add iscsi-np transport calls w/ ->iscsit_setup_up() and ->iscsit_free_np()
- Convert login thread process context to use ->iscsit_accept_np() for
connections with pre-allocated struct iscsi_conn
- Convert existing socket accept code to iscsit_accept_np()
- Convert login RX/TX callers to use ->iscsit_get_login_rx() and
->iscsit_put_login_tx() to exchange request/response PDUs
- Convert existing socket login RX/TX calls into iscsit_get_login_rx()
and iscsit_put_login_tx()
- Change iscsit_close_connection() to invoke ->iscsit_free_conn() +
iscsit_put_transport() calls.
- Add iscsit_register_transport() + iscsit_unregister_transport() calls
to module init/exit

v4 changes:

- Add missing iscsit_put_transport() call in iscsi_target_setup_login_socket()
failure case

v2 changes:

- Update module init/exit to use register_transport() + unregister_transport()

Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

+380 -315
+28 -7
drivers/target/iscsi/iscsi_target.c
··· 49 49 #include "iscsi_target_device.h" 50 50 #include "iscsi_target_stat.h" 51 51 52 + #include <target/iscsi/iscsi_transport.h> 53 + 52 54 static LIST_HEAD(g_tiqn_list); 53 55 static LIST_HEAD(g_np_list); 54 56 static DEFINE_SPINLOCK(tiqn_lock); ··· 403 401 spin_unlock_bh(&np_lock); 404 402 405 403 pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", 406 - np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ? 407 - "TCP" : "SCTP"); 404 + np->np_ip, np->np_port, np->np_transport->name); 408 405 409 406 return np; 410 407 } ··· 442 441 return 0; 443 442 } 444 443 445 - static int iscsit_del_np_comm(struct iscsi_np *np) 444 + static void iscsit_free_np(struct iscsi_np *np) 446 445 { 447 446 if (np->np_socket) 448 447 sock_release(np->np_socket); 449 - return 0; 450 448 } 451 449 452 450 int iscsit_del_np(struct iscsi_np *np) ··· 467 467 send_sig(SIGINT, np->np_thread, 1); 468 468 kthread_stop(np->np_thread); 469 469 } 470 - iscsit_del_np_comm(np); 470 + 471 + np->np_transport->iscsit_free_np(np); 471 472 472 473 spin_lock_bh(&np_lock); 473 474 list_del(&np->np_list); 474 475 spin_unlock_bh(&np_lock); 475 476 476 477 pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", 477 - np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ? 478 - "TCP" : "SCTP"); 478 + np->np_ip, np->np_port, np->np_transport->name); 479 479 480 + iscsit_put_transport(np->np_transport); 480 481 kfree(np); 481 482 return 0; 482 483 } 484 + 485 + static struct iscsit_transport iscsi_target_transport = { 486 + .name = "iSCSI/TCP", 487 + .transport_type = ISCSI_TCP, 488 + .owner = NULL, 489 + .iscsit_setup_np = iscsit_setup_np, 490 + .iscsit_accept_np = iscsit_accept_np, 491 + .iscsit_free_np = iscsit_free_np, 492 + .iscsit_get_login_rx = iscsit_get_login_rx, 493 + .iscsit_put_login_tx = iscsit_put_login_tx, 494 + }; 483 495 484 496 static int __init iscsi_target_init_module(void) 485 497 { ··· 569 557 goto ooo_out; 570 558 } 571 559 560 + iscsit_register_transport(&iscsi_target_transport); 561 + 572 562 if (iscsit_load_discovery_tpg() < 0) 573 563 goto r2t_out; 574 564 ··· 601 587 iscsi_deallocate_thread_sets(); 602 588 iscsi_thread_set_free(); 603 589 iscsit_release_discovery_tpg(); 590 + iscsit_unregister_transport(&iscsi_target_transport); 604 591 kmem_cache_destroy(lio_cmd_cache); 605 592 kmem_cache_destroy(lio_qr_cache); 606 593 kmem_cache_destroy(lio_dr_cache); ··· 4068 4053 4069 4054 if (conn->sock) 4070 4055 sock_release(conn->sock); 4056 + 4057 + if (conn->conn_transport->iscsit_free_conn) 4058 + conn->conn_transport->iscsit_free_conn(conn); 4059 + 4060 + iscsit_put_transport(conn->conn_transport); 4061 + 4071 4062 conn->thread_set = NULL; 4072 4063 4073 4064 pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
+12 -3
drivers/target/iscsi/iscsi_target_core.h
··· 60 60 61 61 #define ISCSI_IOV_DATA_BUFFER 5 62 62 63 - enum tpg_np_network_transport_table { 63 + enum iscsit_transport_type { 64 64 ISCSI_TCP = 0, 65 65 ISCSI_SCTP_TCP = 1, 66 66 ISCSI_SCTP_UDP = 2, ··· 503 503 u16 login_port; 504 504 u16 local_port; 505 505 int net_size; 506 + int login_family; 506 507 u32 auth_id; 507 508 u32 conn_flags; 508 509 /* Used for iscsi_tx_login_rsp() */ ··· 563 562 struct list_head immed_queue_list; 564 563 struct list_head response_queue_list; 565 564 struct iscsi_conn_ops *conn_ops; 565 + struct iscsi_login *conn_login; 566 + struct iscsit_transport *conn_transport; 566 567 struct iscsi_param_list *param_list; 567 568 /* Used for per connection auth state machine */ 568 569 void *auth_protocol; 570 + void *context; 569 571 struct iscsi_login_thread_s *login_thread; 570 572 struct iscsi_portal_group *tpg; 571 573 /* Pointer to parent session */ ··· 667 663 u8 first_request; 668 664 u8 version_min; 669 665 u8 version_max; 666 + u8 login_complete; 667 + u8 login_failed; 670 668 char isid[6]; 671 669 u32 cmd_sn; 672 670 itt_t init_task_tag; ··· 676 670 u32 rsp_length; 677 671 u16 cid; 678 672 u16 tsih; 679 - char *req; 680 - char *rsp; 673 + char req[ISCSI_HDR_LEN]; 674 + char rsp[ISCSI_HDR_LEN]; 681 675 char *req_buf; 682 676 char *rsp_buf; 677 + struct iscsi_conn *conn; 683 678 } ____cacheline_aligned; 684 679 685 680 struct iscsi_node_attrib { ··· 761 754 struct task_struct *np_thread; 762 755 struct timer_list np_login_timer; 763 756 struct iscsi_portal_group *np_login_tpg; 757 + void *np_context; 758 + struct iscsit_transport *np_transport; 764 759 struct list_head np_list; 765 760 } ____cacheline_aligned; 766 761
+289 -127
drivers/target/iscsi/iscsi_target_login.c
··· 39 39 #include "iscsi_target.h" 40 40 #include "iscsi_target_parameters.h" 41 41 42 - static int iscsi_login_init_conn(struct iscsi_conn *conn) 42 + #include <target/iscsi/iscsi_transport.h> 43 + 44 + static struct iscsi_login *iscsi_login_init_conn(struct iscsi_conn *conn) 43 45 { 46 + struct iscsi_login *login; 47 + 48 + login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL); 49 + if (!login) { 50 + pr_err("Unable to allocate memory for struct iscsi_login.\n"); 51 + return NULL; 52 + } 53 + login->conn = conn; 54 + login->first_request = 1; 55 + 56 + login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); 57 + if (!login->req_buf) { 58 + pr_err("Unable to allocate memory for response buffer.\n"); 59 + goto out_login; 60 + } 61 + 62 + login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); 63 + if (!login->rsp_buf) { 64 + pr_err("Unable to allocate memory for request buffer.\n"); 65 + goto out_req_buf; 66 + } 67 + 68 + conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL); 69 + if (!conn->conn_ops) { 70 + pr_err("Unable to allocate memory for" 71 + " struct iscsi_conn_ops.\n"); 72 + goto out_rsp_buf; 73 + } 74 + 44 75 init_waitqueue_head(&conn->queues_wq); 45 76 INIT_LIST_HEAD(&conn->conn_list); 46 77 INIT_LIST_HEAD(&conn->conn_cmd_list); ··· 93 62 94 63 if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) { 95 64 pr_err("Unable to allocate conn->conn_cpumask\n"); 96 - return -ENOMEM; 65 + goto out_conn_ops; 97 66 } 67 + conn->conn_login = login; 98 68 99 - return 0; 69 + return login; 70 + 71 + out_conn_ops: 72 + kfree(conn->conn_ops); 73 + out_rsp_buf: 74 + kfree(login->rsp_buf); 75 + out_req_buf: 76 + kfree(login->req_buf); 77 + out_login: 78 + kfree(login); 79 + return NULL; 100 80 } 101 81 102 82 /* ··· 615 573 616 574 static void iscsi_post_login_start_timers(struct iscsi_conn *conn) 617 575 { 576 + #warning FIXME: Reenable iscsit_start_nopin_timer 577 + #if 0 618 578 struct iscsi_session *sess = conn->sess; 619 579 620 580 if (!sess->sess_ops->SessionType) 621 581 iscsit_start_nopin_timer(conn); 582 + #endif 622 583 } 623 584 624 585 static int iscsi_post_login_handler( ··· 677 632 spin_unlock_bh(&sess->conn_lock); 678 633 679 634 iscsi_post_login_start_timers(conn); 680 - iscsi_activate_thread_set(conn, ts); 635 + 636 + if (conn->conn_transport == ISCSI_TCP) { 637 + iscsi_activate_thread_set(conn, ts); 638 + } else { 639 + printk("Not calling iscsi_activate_thread_set....\n"); 640 + dump_stack(); 641 + } 681 642 /* 682 643 * Determine CPU mask to ensure connection's RX and TX kthreads 683 644 * are scheduled on the same CPU. ··· 812 761 spin_unlock_bh(&np->np_thread_lock); 813 762 } 814 763 815 - int iscsi_target_setup_login_socket( 764 + int iscsit_setup_np( 816 765 struct iscsi_np *np, 817 766 struct __kernel_sockaddr_storage *sockaddr) 818 767 { 819 - struct socket *sock; 768 + struct socket *sock = NULL; 820 769 int backlog = 5, ret, opt = 0, len; 821 770 822 771 switch (np->np_network_transport) { ··· 832 781 np->np_ip_proto = IPPROTO_SCTP; 833 782 np->np_sock_type = SOCK_SEQPACKET; 834 783 break; 835 - case ISCSI_IWARP_TCP: 836 - case ISCSI_IWARP_SCTP: 837 - case ISCSI_INFINIBAND: 838 784 default: 839 785 pr_err("Unsupported network_transport: %d\n", 840 786 np->np_network_transport); 841 787 return -EINVAL; 842 788 } 789 + 790 + np->np_ip_proto = IPPROTO_TCP; 791 + np->np_sock_type = SOCK_STREAM; 843 792 844 793 ret = sock_create(sockaddr->ss_family, np->np_sock_type, 845 794 np->np_ip_proto, &sock); ··· 904 853 } 905 854 906 855 return 0; 907 - 908 856 fail: 909 857 np->np_socket = NULL; 910 858 if (sock) ··· 911 861 return ret; 912 862 } 913 863 864 + int iscsi_target_setup_login_socket( 865 + struct iscsi_np *np, 866 + struct __kernel_sockaddr_storage *sockaddr) 867 + { 868 + struct iscsit_transport *t; 869 + int rc; 870 + 871 + t = iscsit_get_transport(np->np_network_transport); 872 + if (!t) 873 + return -EINVAL; 874 + 875 + rc = t->iscsit_setup_np(np, sockaddr); 876 + if (rc < 0) { 877 + iscsit_put_transport(t); 878 + return rc; 879 + } 880 + 881 + np->np_transport = t; 882 + printk("Set np->np_transport to %p -> %s\n", np->np_transport, 883 + np->np_transport->name); 884 + return 0; 885 + } 886 + 887 + int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) 888 + { 889 + struct socket *new_sock, *sock = np->np_socket; 890 + struct sockaddr_in sock_in; 891 + struct sockaddr_in6 sock_in6; 892 + int rc, err; 893 + 894 + rc = kernel_accept(sock, &new_sock, 0); 895 + if (rc < 0) 896 + return rc; 897 + 898 + conn->sock = new_sock; 899 + conn->login_family = np->np_sockaddr.ss_family; 900 + printk("iSCSI/TCP: Setup conn->sock from new_sock: %p\n", new_sock); 901 + 902 + if (np->np_sockaddr.ss_family == AF_INET6) { 903 + memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); 904 + 905 + rc = conn->sock->ops->getname(conn->sock, 906 + (struct sockaddr *)&sock_in6, &err, 1); 907 + if (!rc) { 908 + snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", 909 + &sock_in6.sin6_addr.in6_u); 910 + conn->login_port = ntohs(sock_in6.sin6_port); 911 + } 912 + 913 + rc = conn->sock->ops->getname(conn->sock, 914 + (struct sockaddr *)&sock_in6, &err, 0); 915 + if (!rc) { 916 + snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c", 917 + &sock_in6.sin6_addr.in6_u); 918 + conn->local_port = ntohs(sock_in6.sin6_port); 919 + } 920 + } else { 921 + memset(&sock_in, 0, sizeof(struct sockaddr_in)); 922 + 923 + rc = conn->sock->ops->getname(conn->sock, 924 + (struct sockaddr *)&sock_in, &err, 1); 925 + if (!rc) { 926 + sprintf(conn->login_ip, "%pI4", 927 + &sock_in.sin_addr.s_addr); 928 + conn->login_port = ntohs(sock_in.sin_port); 929 + } 930 + 931 + rc = conn->sock->ops->getname(conn->sock, 932 + (struct sockaddr *)&sock_in, &err, 0); 933 + if (!rc) { 934 + sprintf(conn->local_ip, "%pI4", 935 + &sock_in.sin_addr.s_addr); 936 + conn->local_port = ntohs(sock_in.sin_port); 937 + } 938 + } 939 + 940 + return 0; 941 + } 942 + 943 + int iscsit_get_login_rx(struct iscsi_conn *conn, struct iscsi_login *login) 944 + { 945 + struct iscsi_login_req *login_req; 946 + u32 padding = 0, payload_length; 947 + 948 + if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0) 949 + return -1; 950 + 951 + login_req = (struct iscsi_login_req *)login->req; 952 + payload_length = ntoh24(login_req->dlength); 953 + padding = ((-payload_length) & 3); 954 + 955 + pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," 956 + " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n", 957 + login_req->flags, login_req->itt, login_req->cmdsn, 958 + login_req->exp_statsn, login_req->cid, payload_length); 959 + /* 960 + * Setup the initial iscsi_login values from the leading 961 + * login request PDU. 962 + */ 963 + if (login->first_request) { 964 + login_req = (struct iscsi_login_req *)login->req; 965 + login->leading_connection = (!login_req->tsih) ? 1 : 0; 966 + login->current_stage = 967 + (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2; 968 + login->version_min = login_req->min_version; 969 + login->version_max = login_req->max_version; 970 + memcpy(login->isid, login_req->isid, 6); 971 + login->cmd_sn = be32_to_cpu(login_req->cmdsn); 972 + login->init_task_tag = login_req->itt; 973 + login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn); 974 + login->cid = be16_to_cpu(login_req->cid); 975 + login->tsih = be16_to_cpu(login_req->tsih); 976 + } 977 + 978 + if (iscsi_target_check_login_request(conn, login) < 0) 979 + return -1; 980 + 981 + memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS); 982 + if (iscsi_login_rx_data(conn, login->req_buf, 983 + payload_length + padding) < 0) 984 + return -1; 985 + 986 + return 0; 987 + } 988 + 989 + int iscsit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, 990 + u32 length) 991 + { 992 + if (iscsi_login_tx_data(conn, login->rsp, login->rsp_buf, length) < 0) 993 + return -1; 994 + 995 + return 0; 996 + } 997 + 998 + static int 999 + iscsit_conn_set_transport(struct iscsi_conn *conn, struct iscsit_transport *t) 1000 + { 1001 + int rc; 1002 + 1003 + if (!t->owner) { 1004 + conn->conn_transport = t; 1005 + return 0; 1006 + } 1007 + 1008 + rc = try_module_get(t->owner); 1009 + if (!rc) { 1010 + pr_err("try_module_get() failed for %s\n", t->name); 1011 + return -EINVAL; 1012 + } 1013 + 1014 + conn->conn_transport = t; 1015 + return 0; 1016 + } 1017 + 914 1018 static int __iscsi_target_login_thread(struct iscsi_np *np) 915 1019 { 916 - u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0; 917 - int err, ret = 0, stop; 1020 + u8 *buffer, zero_tsih = 0; 1021 + int ret = 0, rc, stop; 918 1022 struct iscsi_conn *conn = NULL; 919 1023 struct iscsi_login *login; 920 1024 struct iscsi_portal_group *tpg = NULL; 921 - struct socket *new_sock, *sock; 922 - struct kvec iov; 923 1025 struct iscsi_login_req *pdu; 924 - struct sockaddr_in sock_in; 925 - struct sockaddr_in6 sock_in6; 926 1026 927 1027 flush_signals(current); 928 - sock = np->np_socket; 929 1028 930 1029 spin_lock_bh(&np->np_thread_lock); 931 1030 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { ··· 1085 886 } 1086 887 spin_unlock_bh(&np->np_thread_lock); 1087 888 1088 - if (kernel_accept(sock, &new_sock, 0) < 0) { 1089 - spin_lock_bh(&np->np_thread_lock); 1090 - if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { 1091 - spin_unlock_bh(&np->np_thread_lock); 1092 - complete(&np->np_restart_comp); 1093 - /* Get another socket */ 1094 - return 1; 1095 - } 1096 - spin_unlock_bh(&np->np_thread_lock); 1097 - goto out; 1098 - } 1099 - iscsi_start_login_thread_timer(np); 1100 - 1101 889 conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL); 1102 890 if (!conn) { 1103 891 pr_err("Could not allocate memory for" 1104 892 " new connection\n"); 1105 - sock_release(new_sock); 1106 893 /* Get another socket */ 1107 894 return 1; 1108 895 } 1109 - 1110 896 pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); 1111 897 conn->conn_state = TARG_CONN_STATE_FREE; 1112 - conn->sock = new_sock; 1113 898 1114 - pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); 1115 - conn->conn_state = TARG_CONN_STATE_XPT_UP; 899 + if (iscsit_conn_set_transport(conn, np->np_transport) < 0) { 900 + kfree(conn); 901 + return 1; 902 + } 1116 903 1117 - /* 1118 - * Allocate conn->conn_ops early as a failure calling 1119 - * iscsit_tx_login_rsp() below will call tx_data(). 1120 - */ 1121 - conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL); 1122 - if (!conn->conn_ops) { 1123 - pr_err("Unable to allocate memory for" 1124 - " struct iscsi_conn_ops.\n"); 1125 - goto new_sess_out; 904 + rc = np->np_transport->iscsit_accept_np(np, conn); 905 + if (rc == -ENOSYS) { 906 + complete(&np->np_restart_comp); 907 + iscsit_put_transport(conn->conn_transport); 908 + kfree(conn); 909 + conn = NULL; 910 + goto exit; 911 + } else if (rc < 0) { 912 + spin_lock_bh(&np->np_thread_lock); 913 + if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { 914 + spin_unlock_bh(&np->np_thread_lock); 915 + complete(&np->np_restart_comp); 916 + if (ret == -ENODEV) { 917 + iscsit_put_transport(conn->conn_transport); 918 + kfree(conn); 919 + conn = NULL; 920 + goto out; 921 + } 922 + /* Get another socket */ 923 + return 1; 924 + } 925 + spin_unlock_bh(&np->np_thread_lock); 926 + iscsit_put_transport(conn->conn_transport); 927 + kfree(conn); 928 + conn = NULL; 929 + goto out; 1126 930 } 1127 931 /* 1128 932 * Perform the remaining iSCSI connection initialization items.. 1129 933 */ 1130 - if (iscsi_login_init_conn(conn) < 0) 1131 - goto new_sess_out; 1132 - 1133 - memset(buffer, 0, ISCSI_HDR_LEN); 1134 - memset(&iov, 0, sizeof(struct kvec)); 1135 - iov.iov_base = buffer; 1136 - iov.iov_len = ISCSI_HDR_LEN; 1137 - 1138 - if (rx_data(conn, &iov, 1, ISCSI_HDR_LEN) <= 0) { 1139 - pr_err("rx_data() returned an error.\n"); 934 + login = iscsi_login_init_conn(conn); 935 + if (!login) { 1140 936 goto new_sess_out; 1141 937 } 1142 938 1143 - iscsi_opcode = (buffer[0] & ISCSI_OPCODE_MASK); 1144 - if (!(iscsi_opcode & ISCSI_OP_LOGIN)) { 1145 - pr_err("First opcode is not login request," 1146 - " failing login request.\n"); 939 + iscsi_start_login_thread_timer(np); 940 + 941 + pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n"); 942 + conn->conn_state = TARG_CONN_STATE_XPT_UP; 943 + /* 944 + * This will process the first login request + payload.. 945 + */ 946 + rc = np->np_transport->iscsit_get_login_rx(conn, login); 947 + if (rc == 1) 948 + return 1; 949 + else if (rc < 0) 1147 950 goto new_sess_out; 1148 - } 1149 951 1150 - pdu = (struct iscsi_login_req *) buffer; 1151 - 952 + buffer = &login->req[0]; 953 + pdu = (struct iscsi_login_req *)buffer; 1152 954 /* 1153 955 * Used by iscsit_tx_login_rsp() for Login Resonses PDUs 1154 956 * when Status-Class != 0. 1155 957 */ 1156 - conn->login_itt = pdu->itt; 958 + conn->login_itt = pdu->itt; 1157 959 1158 960 spin_lock_bh(&np->np_thread_lock); 1159 961 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { ··· 1167 967 } 1168 968 spin_unlock_bh(&np->np_thread_lock); 1169 969 1170 - if (np->np_sockaddr.ss_family == AF_INET6) { 1171 - memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); 1172 - 1173 - if (conn->sock->ops->getname(conn->sock, 1174 - (struct sockaddr *)&sock_in6, &err, 1) < 0) { 1175 - pr_err("sock_ops->getname() failed.\n"); 1176 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1177 - ISCSI_LOGIN_STATUS_TARGET_ERROR); 1178 - goto new_sess_out; 1179 - } 1180 - snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", 1181 - &sock_in6.sin6_addr.in6_u); 1182 - conn->login_port = ntohs(sock_in6.sin6_port); 1183 - 1184 - if (conn->sock->ops->getname(conn->sock, 1185 - (struct sockaddr *)&sock_in6, &err, 0) < 0) { 1186 - pr_err("sock_ops->getname() failed.\n"); 1187 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1188 - ISCSI_LOGIN_STATUS_TARGET_ERROR); 1189 - goto new_sess_out; 1190 - } 1191 - snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c", 1192 - &sock_in6.sin6_addr.in6_u); 1193 - conn->local_port = ntohs(sock_in6.sin6_port); 1194 - 1195 - } else { 1196 - memset(&sock_in, 0, sizeof(struct sockaddr_in)); 1197 - 1198 - if (conn->sock->ops->getname(conn->sock, 1199 - (struct sockaddr *)&sock_in, &err, 1) < 0) { 1200 - pr_err("sock_ops->getname() failed.\n"); 1201 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1202 - ISCSI_LOGIN_STATUS_TARGET_ERROR); 1203 - goto new_sess_out; 1204 - } 1205 - sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr); 1206 - conn->login_port = ntohs(sock_in.sin_port); 1207 - 1208 - if (conn->sock->ops->getname(conn->sock, 1209 - (struct sockaddr *)&sock_in, &err, 0) < 0) { 1210 - pr_err("sock_ops->getname() failed.\n"); 1211 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1212 - ISCSI_LOGIN_STATUS_TARGET_ERROR); 1213 - goto new_sess_out; 1214 - } 1215 - sprintf(conn->local_ip, "%pI4", &sock_in.sin_addr.s_addr); 1216 - conn->local_port = ntohs(sock_in.sin_port); 1217 - } 1218 - 1219 970 conn->network_transport = np->np_network_transport; 1220 971 1221 972 pr_debug("Received iSCSI login request from %s on %s Network" 1222 - " Portal %s:%hu\n", conn->login_ip, 1223 - (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP", 1224 - conn->local_ip, conn->local_port); 973 + " Portal %s:%hu\n", conn->login_ip, np->np_transport->name, 974 + conn->local_ip, conn->local_port); 1225 975 1226 976 pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); 1227 977 conn->conn_state = TARG_CONN_STATE_IN_LOGIN; ··· 1200 1050 if (iscsi_login_non_zero_tsih_s1(conn, buffer) < 0) 1201 1051 goto new_sess_out; 1202 1052 } 1203 - 1204 1053 /* 1205 - * This will process the first login request, and call 1206 - * iscsi_target_locate_portal(), and return a valid struct iscsi_login. 1054 + * SessionType: Discovery 1055 + * 1056 + * Locates Default Portal 1057 + * 1058 + * SessionType: Normal 1059 + * 1060 + * Locates Target Portal from NP -> Target IQN 1207 1061 */ 1208 - login = iscsi_target_init_negotiation(np, conn, buffer); 1209 - if (!login) { 1062 + rc = iscsi_target_locate_portal(np, conn, login); 1063 + if (rc < 0) { 1210 1064 tpg = conn->tpg; 1211 1065 goto new_sess_out; 1212 1066 } ··· 1222 1068 } 1223 1069 1224 1070 if (zero_tsih) { 1225 - if (iscsi_login_zero_tsih_s2(conn) < 0) { 1226 - iscsi_target_nego_release(login, conn); 1071 + if (iscsi_login_zero_tsih_s2(conn) < 0) 1227 1072 goto new_sess_out; 1228 - } 1229 1073 } else { 1230 - if (iscsi_login_non_zero_tsih_s2(conn, buffer) < 0) { 1231 - iscsi_target_nego_release(login, conn); 1074 + if (iscsi_login_non_zero_tsih_s2(conn, buffer) < 0) 1232 1075 goto old_sess_out; 1233 - } 1234 1076 } 1235 1077 1236 1078 if (iscsi_target_start_negotiation(login, conn) < 0) ··· 1303 1153 iscsi_release_param_list(conn->param_list); 1304 1154 conn->param_list = NULL; 1305 1155 } 1306 - if (conn->sock) 1156 + iscsi_target_nego_release(conn); 1157 + 1158 + if (conn->sock) { 1307 1159 sock_release(conn->sock); 1160 + conn->sock = NULL; 1161 + } 1162 + 1163 + if (conn->conn_transport->iscsit_free_conn) 1164 + conn->conn_transport->iscsit_free_conn(conn); 1165 + 1166 + iscsit_put_transport(conn->conn_transport); 1167 + 1308 1168 kfree(conn); 1309 1169 1310 1170 if (tpg) { ··· 1332 1172 /* Wait for another socket.. */ 1333 1173 if (!stop) 1334 1174 return 1; 1335 - 1175 + exit: 1336 1176 iscsi_stop_login_thread_timer(np); 1337 1177 spin_lock_bh(&np->np_thread_lock); 1338 1178 np->np_thread_state = ISCSI_NP_THREAD_EXIT; 1179 + np->np_thread = NULL; 1339 1180 spin_unlock_bh(&np->np_thread_lock); 1181 + 1340 1182 return 0; 1341 1183 } 1342 1184
+6
drivers/target/iscsi/iscsi_target_login.h
··· 4 4 extern int iscsi_login_setup_crypto(struct iscsi_conn *); 5 5 extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *); 6 6 extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32); 7 + extern int iscsit_setup_np(struct iscsi_np *, 8 + struct __kernel_sockaddr_storage *); 7 9 extern int iscsi_target_setup_login_socket(struct iscsi_np *, 8 10 struct __kernel_sockaddr_storage *); 11 + extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *); 12 + extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); 13 + extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); 14 + extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *); 9 15 extern int iscsi_target_login_thread(void *); 10 16 extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *); 11 17
+19 -148
drivers/target/iscsi/iscsi_target_nego.c
··· 22 22 #include <scsi/iscsi_proto.h> 23 23 #include <target/target_core_base.h> 24 24 #include <target/target_core_fabric.h> 25 + #include <target/iscsi/iscsi_transport.h> 25 26 26 27 #include "iscsi_target_core.h" 27 28 #include "iscsi_target_parameters.h" ··· 170 169 kfree(conn->auth_protocol); 171 170 } 172 171 173 - static int iscsi_target_check_login_request( 172 + int iscsi_target_check_login_request( 174 173 struct iscsi_conn *conn, 175 174 struct iscsi_login *login) 176 175 { ··· 353 352 354 353 padding = ((-login->rsp_length) & 3); 355 354 356 - if (iscsi_login_tx_data( 357 - conn, 358 - login->rsp, 359 - login->rsp_buf, 360 - login->rsp_length + padding) < 0) 355 + if (conn->conn_transport->iscsit_put_login_tx(conn, login, 356 + login->rsp_length + padding) < 0) 361 357 return -1; 362 358 363 359 login->rsp_length = 0; ··· 366 368 return 0; 367 369 } 368 370 369 - static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) 370 - { 371 - u32 padding = 0, payload_length; 372 - struct iscsi_login_req *login_req; 373 - 374 - if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0) 375 - return -1; 376 - 377 - login_req = (struct iscsi_login_req *) login->req; 378 - payload_length = ntoh24(login_req->dlength); 379 - 380 - pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," 381 - " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n", 382 - login_req->flags, login_req->itt, login_req->cmdsn, 383 - login_req->exp_statsn, login_req->cid, payload_length); 384 - 385 - if (iscsi_target_check_login_request(conn, login) < 0) 386 - return -1; 387 - 388 - padding = ((-payload_length) & 3); 389 - memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS); 390 - 391 - if (iscsi_login_rx_data( 392 - conn, 393 - login->req_buf, 394 - payload_length + padding) < 0) 395 - return -1; 396 - 397 - return 0; 398 - } 399 - 400 371 static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login) 401 372 { 402 373 if (iscsi_target_do_tx_login_io(conn, login) < 0) 403 374 return -1; 404 375 405 - if (iscsi_target_do_rx_login_io(conn, login) < 0) 406 - return -1; 407 - 408 - return 0; 409 - } 410 - 411 - static int iscsi_target_get_initial_payload( 412 - struct iscsi_conn *conn, 413 - struct iscsi_login *login) 414 - { 415 - u32 padding = 0, payload_length; 416 - struct iscsi_login_req *login_req; 417 - 418 - login_req = (struct iscsi_login_req *) login->req; 419 - payload_length = ntoh24(login_req->dlength); 420 - 421 - pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," 422 - " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", 423 - login_req->flags, login_req->itt, login_req->cmdsn, 424 - login_req->exp_statsn, payload_length); 425 - 426 - if (iscsi_target_check_login_request(conn, login) < 0) 427 - return -1; 428 - 429 - padding = ((-payload_length) & 3); 430 - 431 - if (iscsi_login_rx_data( 432 - conn, 433 - login->req_buf, 434 - payload_length + padding) < 0) 376 + if (conn->conn_transport->iscsit_get_login_rx(conn, login) < 0) 435 377 return -1; 436 378 437 379 return 0; ··· 631 693 return -1; 632 694 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { 633 695 login->tsih = conn->sess->tsih; 696 + login->login_complete = 1; 634 697 if (iscsi_target_do_tx_login_io(conn, 635 698 login) < 0) 636 699 return -1; ··· 675 736 /* 676 737 * Processes the first Login Request.. 677 738 */ 678 - static int iscsi_target_locate_portal( 739 + int iscsi_target_locate_portal( 679 740 struct iscsi_np *np, 680 741 struct iscsi_conn *conn, 681 742 struct iscsi_login *login) ··· 736 797 737 798 start += strlen(key) + strlen(value) + 2; 738 799 } 800 + 801 + printk("i_buf: %s, s_buf: %s, t_buf: %s\n", i_buf, s_buf, t_buf); 739 802 740 803 /* 741 804 * See 5.3. Login Phase. ··· 897 956 return ret; 898 957 } 899 958 900 - struct iscsi_login *iscsi_target_init_negotiation( 901 - struct iscsi_np *np, 902 - struct iscsi_conn *conn, 903 - char *login_pdu) 904 - { 905 - struct iscsi_login *login; 906 - 907 - login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL); 908 - if (!login) { 909 - pr_err("Unable to allocate memory for struct iscsi_login.\n"); 910 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 911 - ISCSI_LOGIN_STATUS_NO_RESOURCES); 912 - return NULL; 913 - } 914 - 915 - login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL); 916 - if (!login->req) { 917 - pr_err("Unable to allocate memory for Login Request.\n"); 918 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 919 - ISCSI_LOGIN_STATUS_NO_RESOURCES); 920 - goto out; 921 - } 922 - 923 - login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); 924 - if (!login->req_buf) { 925 - pr_err("Unable to allocate memory for response buffer.\n"); 926 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 927 - ISCSI_LOGIN_STATUS_NO_RESOURCES); 928 - goto out; 929 - } 930 - /* 931 - * SessionType: Discovery 932 - * 933 - * Locates Default Portal 934 - * 935 - * SessionType: Normal 936 - * 937 - * Locates Target Portal from NP -> Target IQN 938 - */ 939 - if (iscsi_target_locate_portal(np, conn, login) < 0) { 940 - goto out; 941 - } 942 - 943 - return login; 944 - out: 945 - kfree(login->req); 946 - kfree(login->req_buf); 947 - kfree(login); 948 - 949 - return NULL; 950 - } 951 - 952 959 int iscsi_target_start_negotiation( 953 960 struct iscsi_login *login, 954 961 struct iscsi_conn *conn) 955 962 { 956 - int ret = -1; 957 - 958 - login->rsp = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); 959 - if (!login->rsp) { 960 - pr_err("Unable to allocate memory for" 961 - " Login Response.\n"); 962 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 963 - ISCSI_LOGIN_STATUS_NO_RESOURCES); 964 - ret = -1; 965 - goto out; 966 - } 967 - 968 - login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); 969 - if (!login->rsp_buf) { 970 - pr_err("Unable to allocate memory for" 971 - " request buffer.\n"); 972 - iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 973 - ISCSI_LOGIN_STATUS_NO_RESOURCES); 974 - ret = -1; 975 - goto out; 976 - } 963 + int ret; 977 964 978 965 ret = iscsi_target_do_login(conn, login); 979 - out: 980 966 if (ret != 0) 981 967 iscsi_remove_failed_auth_entry(conn); 982 968 983 - iscsi_target_nego_release(login, conn); 969 + iscsi_target_nego_release(conn); 984 970 return ret; 985 971 } 986 972 987 - void iscsi_target_nego_release( 988 - struct iscsi_login *login, 989 - struct iscsi_conn *conn) 973 + void iscsi_target_nego_release(struct iscsi_conn *conn) 990 974 { 991 - kfree(login->req); 992 - kfree(login->rsp); 975 + struct iscsi_login *login = conn->conn_login; 976 + 977 + if (!login) 978 + return; 979 + 993 980 kfree(login->req_buf); 994 981 kfree(login->rsp_buf); 995 982 kfree(login); 983 + 984 + conn->conn_login = NULL; 996 985 }
+7 -4
drivers/target/iscsi/iscsi_target_nego.h
··· 7 7 extern void convert_null_to_semi(char *, int); 8 8 extern int extract_param(const char *, const char *, unsigned int, char *, 9 9 unsigned char *); 10 - extern struct iscsi_login *iscsi_target_init_negotiation( 11 - struct iscsi_np *, struct iscsi_conn *, char *); 10 + extern int iscsi_target_check_login_request(struct iscsi_conn *, 11 + struct iscsi_login *); 12 + extern int iscsi_target_get_initial_payload(struct iscsi_conn *, 13 + struct iscsi_login *); 14 + extern int iscsi_target_locate_portal(struct iscsi_np *, struct iscsi_conn *, 15 + struct iscsi_login *); 12 16 extern int iscsi_target_start_negotiation( 13 17 struct iscsi_login *, struct iscsi_conn *); 14 - extern void iscsi_target_nego_release( 15 - struct iscsi_login *, struct iscsi_conn *); 18 + extern void iscsi_target_nego_release(struct iscsi_conn *); 16 19 17 20 #endif /* ISCSI_TARGET_NEGO_H */
+8 -4
drivers/target/iscsi/iscsi_target_parameters.c
··· 59 59 char *text_buf, 60 60 int text_length) 61 61 { 62 - int length, tx_sent; 62 + int length, tx_sent, iov_cnt = 1; 63 63 struct kvec iov[2]; 64 64 65 65 length = (ISCSI_HDR_LEN + text_length); ··· 67 67 memset(&iov[0], 0, 2 * sizeof(struct kvec)); 68 68 iov[0].iov_len = ISCSI_HDR_LEN; 69 69 iov[0].iov_base = pdu_buf; 70 - iov[1].iov_len = text_length; 71 - iov[1].iov_base = text_buf; 70 + 71 + if (text_buf && text_length) { 72 + iov[1].iov_len = text_length; 73 + iov[1].iov_base = text_buf; 74 + iov_cnt++; 75 + } 72 76 73 77 /* 74 78 * Initial Marker-less Interval. ··· 81 77 */ 82 78 conn->if_marker += length; 83 79 84 - tx_sent = tx_data(conn, &iov[0], 2, length); 80 + tx_sent = tx_data(conn, &iov[0], iov_cnt, length); 85 81 if (tx_sent != length) { 86 82 pr_err("tx_data returned %d, expecting %d.\n", 87 83 tx_sent, length);
+4 -2
drivers/target/iscsi/iscsi_target_tpg.c
··· 31 31 #include "iscsi_target.h" 32 32 #include "iscsi_target_parameters.h" 33 33 34 + #include <target/iscsi/iscsi_transport.h> 35 + 34 36 struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt) 35 37 { 36 38 struct iscsi_portal_group *tpg; ··· 510 508 511 509 pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n", 512 510 tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, 513 - (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP"); 511 + np->np_transport->name); 514 512 515 513 return tpg_np; 516 514 } ··· 524 522 525 523 pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n", 526 524 tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, 527 - (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP"); 525 + np->np_transport->name); 528 526 529 527 tpg_np->tpg_np = NULL; 530 528 tpg_np->tpg = NULL;
+7 -20
drivers/target/iscsi/iscsi_target_util.c
··· 24 24 #include <target/target_core_base.h> 25 25 #include <target/target_core_fabric.h> 26 26 #include <target/target_core_configfs.h> 27 + #include <target/iscsi/iscsi_transport.h> 27 28 28 29 #include "iscsi_target_core.h" 29 30 #include "iscsi_target_parameters.h" ··· 1227 1226 */ 1228 1227 int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_detail) 1229 1228 { 1230 - u8 iscsi_hdr[ISCSI_HDR_LEN]; 1231 - int err; 1232 - struct kvec iov; 1233 1229 struct iscsi_login_rsp *hdr; 1230 + struct iscsi_login *login = conn->conn_login; 1234 1231 1232 + login->login_failed = 1; 1235 1233 iscsit_collect_login_stats(conn, status_class, status_detail); 1236 1234 1237 - memset(&iov, 0, sizeof(struct kvec)); 1238 - memset(&iscsi_hdr, 0x0, ISCSI_HDR_LEN); 1239 - 1240 - hdr = (struct iscsi_login_rsp *)&iscsi_hdr; 1235 + hdr = (struct iscsi_login_rsp *)&login->rsp[0]; 1241 1236 hdr->opcode = ISCSI_OP_LOGIN_RSP; 1242 1237 hdr->status_class = status_class; 1243 1238 hdr->status_detail = status_detail; 1244 1239 hdr->itt = conn->login_itt; 1245 1240 1246 - iov.iov_base = &iscsi_hdr; 1247 - iov.iov_len = ISCSI_HDR_LEN; 1248 - 1249 - PRINT_BUFF(iscsi_hdr, ISCSI_HDR_LEN); 1250 - 1251 - err = tx_data(conn, &iov, 1, ISCSI_HDR_LEN); 1252 - if (err != ISCSI_HDR_LEN) { 1253 - pr_err("tx_data returned less than expected\n"); 1254 - return -1; 1255 - } 1256 - 1257 - return 0; 1241 + return conn->conn_transport->iscsit_put_login_tx(conn, login, 0); 1258 1242 } 1259 1243 1260 1244 void iscsit_print_session_params(struct iscsi_session *sess) ··· 1418 1432 strcpy(ls->last_intr_fail_name, 1419 1433 (intrname ? intrname->value : "Unknown")); 1420 1434 1421 - ls->last_intr_fail_ip_family = conn->sock->sk->sk_family; 1435 + ls->last_intr_fail_ip_family = conn->login_family; 1436 + 1422 1437 snprintf(ls->last_intr_fail_ip_addr, IPV6_ADDRESS_SPACE, 1423 1438 "%s", conn->login_ip); 1424 1439 ls->last_fail_time = get_jiffies_64();