^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * iSCSI Initiator over TCP/IP Data-Path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 Dmitry Yusupov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004 Alex Aizman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2005 - 2006 Mike Christie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * maintained by open-iscsi@googlegroups.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * See the file COPYING included with this distribution for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Credits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Christoph Hellwig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * FUJITA Tomonori
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Arne Redlich
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Zhenyu Wang
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/backing-dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <scsi/scsi_transport_iscsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <trace/events/iscsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "iscsi_tcp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "Alex Aizman <itn780@yahoo.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_DESCRIPTION("iSCSI/TCP data-path");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct scsi_host_template iscsi_sw_tcp_sht;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct iscsi_transport iscsi_sw_tcp_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static unsigned int iscsi_max_lun = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int iscsi_sw_tcp_dbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MODULE_PARM_DESC(debug_iscsi_tcp, "Turn on debugging for iscsi_tcp module "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "Set to 1 to turn on, and zero to turn off. Default is off.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define ISCSI_SW_TCP_DBG(_conn, dbg_fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (iscsi_sw_tcp_dbg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) iscsi_conn_printk(KERN_INFO, _conn, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "%s " dbg_fmt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __func__, ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) iscsi_dbg_trace(trace_iscsi_dbg_sw_tcp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) &(_conn)->cls_conn->dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "%s " dbg_fmt, __func__, ##arg);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * iscsi_sw_tcp_recv - TCP receive in sendfile fashion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * @rd_desc: read descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @skb: socket buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @offset: offset in skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @len: skb->len - offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned int offset, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct iscsi_conn *conn = rd_desc->arg.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int consumed, total_consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ISCSI_SW_TCP_DBG(conn, "in %d bytes\n", skb->len - offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) consumed = iscsi_tcp_recv_skb(conn, skb, offset, 0, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) offset += consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) total_consumed += consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) } while (consumed != 0 && status != ISCSI_TCP_SKB_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ISCSI_SW_TCP_DBG(conn, "read %d bytes status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) skb->len - offset, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return total_consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * iscsi_sw_sk_state_check - check socket state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @sk: socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * If the socket is in CLOSE or CLOSE_WAIT we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * not close the connection if there is still some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * data pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Must be called with sk_callback_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline int iscsi_sw_sk_state_check(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct iscsi_conn *conn = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if ((sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) (conn->session->state != ISCSI_STATE_LOGGING_OUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) !atomic_read(&sk->sk_rmem_alloc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ISCSI_SW_TCP_DBG(conn, "TCP_CLOSE|TCP_CLOSE_WAIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) iscsi_conn_failure(conn, ISCSI_ERR_TCP_CONN_CLOSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return -ECONNRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void iscsi_sw_tcp_data_ready(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct iscsi_tcp_conn *tcp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) read_descriptor_t rd_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) conn = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Use rd_desc to pass 'conn' to iscsi_tcp_recv.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * We set count to 1 because we want the network layer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * hand us all the skbs that are available. iscsi_tcp_recv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * handled pdus that cross buffers or pdus that still need data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rd_desc.arg.data = conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) rd_desc.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) iscsi_sw_sk_state_check(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* If we had to (atomically) map a highmem page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * unmap it now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) iscsi_tcp_segment_unmap(&tcp_conn->in.segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void iscsi_sw_tcp_state_change(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct iscsi_tcp_conn *tcp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct iscsi_sw_tcp_conn *tcp_sw_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) void (*old_state_change)(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) conn = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) iscsi_sw_sk_state_check(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) old_state_change = tcp_sw_conn->old_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) old_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * iscsi_write_space - Called when more output buffer space is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * @sk: socket space is available for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void iscsi_sw_tcp_write_space(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct iscsi_tcp_conn *tcp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct iscsi_sw_tcp_conn *tcp_sw_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void (*old_write_space)(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) read_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) conn = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) old_write_space = tcp_sw_conn->old_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) read_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) old_write_space(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) iscsi_conn_queue_work(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct sock *sk = tcp_sw_conn->sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* assign new callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) write_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sk->sk_user_data = conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) tcp_sw_conn->old_data_ready = sk->sk_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) tcp_sw_conn->old_state_change = sk->sk_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) tcp_sw_conn->old_write_space = sk->sk_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) sk->sk_data_ready = iscsi_sw_tcp_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) sk->sk_state_change = iscsi_sw_tcp_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sk->sk_write_space = iscsi_sw_tcp_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) write_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct sock *sk = tcp_sw_conn->sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) write_lock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sk->sk_user_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) sk->sk_data_ready = tcp_sw_conn->old_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sk->sk_state_change = tcp_sw_conn->old_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sk->sk_write_space = tcp_sw_conn->old_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) sk->sk_no_check_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) write_unlock_bh(&sk->sk_callback_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * iscsi_sw_tcp_xmit_segment - transmit segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @tcp_conn: the iSCSI TCP connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @segment: the buffer to transmnit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * This function transmits as much of the buffer as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * the network layer will accept, and returns the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * bytes transmitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * If CRC hashing is enabled, the function will compute the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * hash as it goes. When the entire segment has been transmitted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * it will retrieve the hash value and send it as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct iscsi_segment *segment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct socket *sk = tcp_sw_conn->sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) while (!iscsi_tcp_segment_done(tcp_conn, segment, 0, r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned int offset, copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) offset = segment->copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) copy = segment->size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (segment->total_copied + segment->size < segment->total_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) flags |= MSG_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Use sendpage if we can; else fall back to sendmsg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!segment->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sg = segment->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) offset += segment->sg_offset + sg->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) r = tcp_sw_conn->sendpage(sk, sg_page(sg), offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) copy, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct msghdr msg = { .msg_flags = flags };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct kvec iov = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .iov_base = segment->data + offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .iov_len = copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) r = kernel_sendmsg(sk, &msg, &iov, 1, copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) iscsi_tcp_segment_unmap(segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) copied += r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * iscsi_sw_tcp_xmit - TCP transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * @conn: iscsi connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct iscsi_segment *segment = &tcp_sw_conn->out.segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned int consumed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * We may not have been able to send data because the conn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * is getting stopped. libiscsi will know so propagate err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * for it to do the right thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (rc == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) else if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) rc = ISCSI_ERR_XMIT_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) consumed += rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (segment->total_copied >= segment->total_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (segment->done != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) rc = segment->done(tcp_conn, segment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ISCSI_SW_TCP_DBG(conn, "xmit %d bytes\n", consumed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) conn->txdata_octets += consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return consumed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* Transmit error. We could initiate error recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ISCSI_SW_TCP_DBG(conn, "Error sending PDU, errno=%d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) iscsi_conn_failure(conn, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * iscsi_tcp_xmit_qlen - return the number of bytes queued for xmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @conn: iscsi connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static inline int iscsi_sw_tcp_xmit_qlen(struct iscsi_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct iscsi_segment *segment = &tcp_sw_conn->out.segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return segment->total_copied - segment->total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int iscsi_sw_tcp_pdu_xmit(struct iscsi_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct iscsi_conn *conn = task->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int noreclaim_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!tcp_sw_conn->sock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) iscsi_conn_printk(KERN_ERR, conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) "Transport not bound to socket!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) noreclaim_flag = memalloc_noreclaim_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) while (iscsi_sw_tcp_xmit_qlen(conn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) rc = iscsi_sw_tcp_xmit(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) memalloc_noreclaim_restore(noreclaim_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * This is called when we're done sending the header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Simply copy the data_segment to the send segment, and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int iscsi_sw_tcp_send_hdr_done(struct iscsi_tcp_conn *tcp_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct iscsi_segment *segment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ISCSI_SW_TCP_DBG(tcp_conn->iscsi_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) "Header done. Next segment size %u total_size %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) tcp_sw_conn->out.segment.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) tcp_sw_conn->out.segment.total_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static void iscsi_sw_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) size_t hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ISCSI_SW_TCP_DBG(conn, "%s\n", conn->hdrdgst_en ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "digest enabled" : "digest disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Clear the data segment - needs to be filled in by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * caller using iscsi_tcp_send_data_prep() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) memset(&tcp_sw_conn->out.data_segment, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) sizeof(struct iscsi_segment));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* If header digest is enabled, compute the CRC and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * place the digest into the same buffer. We make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * sure that both iscsi_tcp_task and mtask have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * sufficient room.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (conn->hdrdgst_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) iscsi_tcp_dgst_header(tcp_sw_conn->tx_hash, hdr, hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) hdr + hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) hdrlen += ISCSI_DIGEST_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* Remember header pointer for later, when we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * to decide whether there's a payload to go along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * with the header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) tcp_sw_conn->out.hdr = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) iscsi_segment_init_linear(&tcp_sw_conn->out.segment, hdr, hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) iscsi_sw_tcp_send_hdr_done, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * Prepare the send buffer for the payload data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Padding and checksumming will all be taken care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * of by the iscsi_segment routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unsigned int count, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct ahash_request *tx_hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) unsigned int hdr_spec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ISCSI_SW_TCP_DBG(conn, "offset=%d, datalen=%d %s\n", offset, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) conn->datadgst_en ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) "digest enabled" : "digest disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* Make sure the datalen matches what the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) said he would send. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) hdr_spec_len = ntoh24(tcp_sw_conn->out.hdr->dlength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) WARN_ON(iscsi_padded(len) != iscsi_padded(hdr_spec_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (conn->datadgst_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) tx_hash = tcp_sw_conn->tx_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return iscsi_segment_seek_sg(&tcp_sw_conn->out.data_segment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) sg, count, offset, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) NULL, tx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct ahash_request *tx_hash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned int hdr_spec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ISCSI_SW_TCP_DBG(conn, "datalen=%zd %s\n", len, conn->datadgst_en ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) "digest enabled" : "digest disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* Make sure the datalen matches what the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) said he would send. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) hdr_spec_len = ntoh24(tcp_sw_conn->out.hdr->dlength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) WARN_ON(iscsi_padded(len) != iscsi_padded(hdr_spec_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (conn->datadgst_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) tx_hash = tcp_sw_conn->tx_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) iscsi_segment_init_linear(&tcp_sw_conn->out.data_segment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) data, len, NULL, tx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int offset, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct iscsi_conn *conn = task->conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) iscsi_sw_tcp_send_hdr_prep(conn, task->hdr, task->hdr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!task->sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct scsi_data_buffer *sdb = &task->sc->sdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) sdb->table.nents, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* got invalid offset/len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static int iscsi_sw_tcp_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct iscsi_tcp_task *tcp_task = task->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) task->hdr = task->dd_data + sizeof(*tcp_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) task->hdr_max = sizeof(struct iscsi_sw_tcp_hdrbuf) - ISCSI_DIGEST_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static struct iscsi_cls_conn *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) uint32_t conn_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct iscsi_cls_conn *cls_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct iscsi_tcp_conn *tcp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct iscsi_sw_tcp_conn *tcp_sw_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct crypto_ahash *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) cls_conn = iscsi_tcp_conn_setup(cls_session, sizeof(*tcp_sw_conn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) conn_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!cls_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (IS_ERR(tfm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto free_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tcp_sw_conn->tx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (!tcp_sw_conn->tx_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) goto free_tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ahash_request_set_callback(tcp_sw_conn->tx_hash, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) tcp_sw_conn->rx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!tcp_sw_conn->rx_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) goto free_tx_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ahash_request_set_callback(tcp_sw_conn->rx_hash, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) tcp_conn->rx_hash = tcp_sw_conn->rx_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return cls_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) free_tx_hash:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ahash_request_free(tcp_sw_conn->tx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) free_tfm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) crypto_free_ahash(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) free_conn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) iscsi_conn_printk(KERN_ERR, conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) "Could not create connection due to crc32c "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) "loading error. Make sure the crc32c "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) "module is built as a module or into the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) "kernel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) iscsi_tcp_conn_teardown(cls_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct iscsi_session *session = conn->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct socket *sock = tcp_sw_conn->sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (!sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) sock_hold(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) iscsi_sw_tcp_conn_restore_callbacks(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) sock_put(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) spin_lock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) tcp_sw_conn->sock = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_unlock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) sockfd_put(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void iscsi_sw_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) iscsi_sw_tcp_release_conn(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ahash_request_free(tcp_sw_conn->rx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (tcp_sw_conn->tx_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct crypto_ahash *tfm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) tfm = crypto_ahash_reqtfm(tcp_sw_conn->tx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ahash_request_free(tcp_sw_conn->tx_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) crypto_free_ahash(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) iscsi_tcp_conn_teardown(cls_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct socket *sock = tcp_sw_conn->sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* userspace may have goofed up and not bound us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) sock->sk->sk_err = EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) wake_up_interruptible(sk_sleep(sock->sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* stop xmit side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) iscsi_suspend_tx(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* stop recv side and release socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) iscsi_sw_tcp_release_conn(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) iscsi_conn_stop(cls_conn, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int is_leading)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct iscsi_session *session = cls_session->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct socket *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* lookup for existing socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sock = sockfd_lookup((int)transport_eph, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (!sock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) iscsi_conn_printk(KERN_ERR, conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) "sockfd_lookup failed %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto free_socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) spin_lock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* bind iSCSI connection and socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) tcp_sw_conn->sock = sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) spin_unlock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* setup Socket parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) sk->sk_reuse = SK_CAN_REUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) sk->sk_allocation = GFP_ATOMIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) sk_set_memalloc(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) iscsi_sw_tcp_conn_set_callbacks(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) tcp_sw_conn->sendpage = tcp_sw_conn->sock->ops->sendpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * set receive state machine into initial state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) iscsi_tcp_hdr_recv_prep(tcp_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) free_socket:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sockfd_put(sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) enum iscsi_param param, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) switch(param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case ISCSI_PARAM_HDRDGST_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) iscsi_set_param(cls_conn, param, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case ISCSI_PARAM_DATADGST_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) iscsi_set_param(cls_conn, param, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) tcp_sw_conn->sendpage = conn->datadgst_en ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case ISCSI_PARAM_MAX_R2T:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return iscsi_tcp_set_max_r2t(conn, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return iscsi_set_param(cls_conn, param, buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) enum iscsi_param param, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct sockaddr_in6 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct socket *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) switch(param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) case ISCSI_PARAM_CONN_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case ISCSI_PARAM_CONN_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case ISCSI_PARAM_LOCAL_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) spin_lock_bh(&conn->session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!tcp_sw_conn || !tcp_sw_conn->sock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) spin_unlock_bh(&conn->session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) sock = tcp_sw_conn->sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) sock_hold(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) spin_unlock_bh(&conn->session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (param == ISCSI_PARAM_LOCAL_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) rc = kernel_getsockname(sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) (struct sockaddr *)&addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) rc = kernel_getpeername(sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) (struct sockaddr *)&addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) sock_put(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return iscsi_conn_get_addr_param((struct sockaddr_storage *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) &addr, param, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return iscsi_conn_get_param(cls_conn, param, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) enum iscsi_host_param param, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct iscsi_session *session = tcp_sw_host->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct iscsi_conn *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct iscsi_tcp_conn *tcp_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct iscsi_sw_tcp_conn *tcp_sw_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct sockaddr_in6 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct socket *sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case ISCSI_HOST_PARAM_IPADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) spin_lock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) conn = session->leadconn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) spin_unlock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) sock = tcp_sw_conn->sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (!sock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) spin_unlock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) sock_hold(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) spin_unlock_bh(&session->frwd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) rc = kernel_getsockname(sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) (struct sockaddr *)&addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) sock_put(sock->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return iscsi_conn_get_addr_param((struct sockaddr_storage *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) &addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) (enum iscsi_param)param, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return iscsi_host_get_param(shost, param, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct iscsi_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct iscsi_conn *conn = cls_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) stats->custom_length = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) strcpy(stats->custom[0].desc, "tx_sendpage_failures");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) stats->custom[0].value = tcp_sw_conn->sendpage_failures_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) stats->custom[1].value = tcp_sw_conn->discontiguous_hdr_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) strcpy(stats->custom[2].desc, "eh_abort_cnt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) stats->custom[2].value = conn->eh_abort_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) iscsi_tcp_conn_get_stats(cls_conn, stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static struct iscsi_cls_session *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) uint16_t qdepth, uint32_t initial_cmdsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct iscsi_cls_session *cls_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct iscsi_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct iscsi_sw_tcp_host *tcp_sw_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) printk(KERN_ERR "iscsi_tcp: invalid ep %p.\n", ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) shost = iscsi_host_alloc(&iscsi_sw_tcp_sht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) sizeof(struct iscsi_sw_tcp_host), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (!shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) shost->transportt = iscsi_sw_tcp_scsi_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) shost->cmd_per_lun = qdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) shost->max_lun = iscsi_max_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) shost->max_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) shost->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (iscsi_host_add(shost, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) goto free_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) cmds_max, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) sizeof(struct iscsi_tcp_task) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) sizeof(struct iscsi_sw_tcp_hdrbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) initial_cmdsn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!cls_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) goto remove_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) session = cls_session->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) tcp_sw_host = iscsi_host_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) tcp_sw_host->session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) shost->can_queue = session->scsi_cmds_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (iscsi_tcp_r2tpool_alloc(session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) goto remove_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return cls_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) remove_session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) iscsi_session_teardown(cls_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) remove_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) iscsi_host_remove(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) free_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) iscsi_host_free(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct iscsi_session *session = cls_session->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (WARN_ON_ONCE(session->leadconn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) iscsi_tcp_r2tpool_free(cls_session->dd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) iscsi_session_teardown(cls_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) iscsi_host_remove(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) iscsi_host_free(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static umode_t iscsi_sw_tcp_attr_is_visible(int param_type, int param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) switch (param_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case ISCSI_HOST_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case ISCSI_HOST_PARAM_NETDEV_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case ISCSI_HOST_PARAM_HWADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case ISCSI_HOST_PARAM_IPADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case ISCSI_HOST_PARAM_INITIATOR_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case ISCSI_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case ISCSI_PARAM_MAX_RECV_DLENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case ISCSI_PARAM_MAX_XMIT_DLENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case ISCSI_PARAM_HDRDGST_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case ISCSI_PARAM_DATADGST_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) case ISCSI_PARAM_CONN_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) case ISCSI_PARAM_CONN_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) case ISCSI_PARAM_LOCAL_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) case ISCSI_PARAM_EXP_STATSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) case ISCSI_PARAM_PERSISTENT_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) case ISCSI_PARAM_PERSISTENT_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) case ISCSI_PARAM_PING_TMO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case ISCSI_PARAM_RECV_TMO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) case ISCSI_PARAM_INITIAL_R2T_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case ISCSI_PARAM_MAX_R2T:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) case ISCSI_PARAM_IMM_DATA_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) case ISCSI_PARAM_FIRST_BURST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case ISCSI_PARAM_MAX_BURST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) case ISCSI_PARAM_PDU_INORDER_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) case ISCSI_PARAM_DATASEQ_INORDER_EN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) case ISCSI_PARAM_ERL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) case ISCSI_PARAM_TARGET_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case ISCSI_PARAM_TPGT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) case ISCSI_PARAM_USERNAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) case ISCSI_PARAM_PASSWORD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) case ISCSI_PARAM_USERNAME_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) case ISCSI_PARAM_PASSWORD_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case ISCSI_PARAM_FAST_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case ISCSI_PARAM_ABORT_TMO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case ISCSI_PARAM_LU_RESET_TMO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) case ISCSI_PARAM_TGT_RESET_TMO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case ISCSI_PARAM_IFACE_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case ISCSI_PARAM_INITIATOR_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct iscsi_session *session = tcp_sw_host->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct iscsi_conn *conn = session->leadconn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (conn->datadgst_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) sdev->request_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) blk_queue_dma_alignment(sdev->request_queue, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static struct scsi_host_template iscsi_sw_tcp_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .name = "iSCSI Initiator over TCP/IP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .queuecommand = iscsi_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .change_queue_depth = scsi_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .sg_tablesize = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .max_sectors = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .eh_timed_out = iscsi_eh_cmd_timed_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .eh_abort_handler = iscsi_eh_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .eh_device_reset_handler= iscsi_eh_device_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .eh_target_reset_handler = iscsi_eh_recover_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .dma_boundary = PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .slave_configure = iscsi_sw_tcp_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .target_alloc = iscsi_target_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .proc_name = "iscsi_tcp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .track_queue_depth = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static struct iscsi_transport iscsi_sw_tcp_transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .name = "tcp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) | CAP_DATADGST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* session management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .create_session = iscsi_sw_tcp_session_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .destroy_session = iscsi_sw_tcp_session_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* connection management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .create_conn = iscsi_sw_tcp_conn_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .bind_conn = iscsi_sw_tcp_conn_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .destroy_conn = iscsi_sw_tcp_conn_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .attr_is_visible = iscsi_sw_tcp_attr_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .set_param = iscsi_sw_tcp_conn_set_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .get_conn_param = iscsi_sw_tcp_conn_get_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .get_session_param = iscsi_session_get_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .start_conn = iscsi_conn_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) .stop_conn = iscsi_sw_tcp_conn_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* iscsi host params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .get_host_param = iscsi_sw_tcp_host_get_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .set_host_param = iscsi_host_set_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .send_pdu = iscsi_conn_send_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .get_stats = iscsi_sw_tcp_conn_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* iscsi task/cmd helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .init_task = iscsi_tcp_task_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .xmit_task = iscsi_tcp_task_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .cleanup_task = iscsi_tcp_cleanup_task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /* low level pdu helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .xmit_pdu = iscsi_sw_tcp_pdu_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .init_pdu = iscsi_sw_tcp_pdu_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .alloc_pdu = iscsi_sw_tcp_pdu_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* recovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .session_recovery_timedout = iscsi_session_recovery_timedout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static int __init iscsi_sw_tcp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (iscsi_max_lun < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) iscsi_max_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) iscsi_sw_tcp_scsi_transport = iscsi_register_transport(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) &iscsi_sw_tcp_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (!iscsi_sw_tcp_scsi_transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static void __exit iscsi_sw_tcp_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) iscsi_unregister_transport(&iscsi_sw_tcp_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) module_init(iscsi_sw_tcp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) module_exit(iscsi_sw_tcp_exit);