linux/drivers/target/iscsi/iscsi_target.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 * This file contains main functions related to the iSCSI Target Core Driver.
 *
 * (c) Copyright 2007-2013 Datera, Inc.
 *
 * Author: Nicholas A. Bellinger <[email protected]>
 *
 ******************************************************************************/

#include <crypto/hash.h>
#include <linux/string.h>
#include <linux/kthread.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/idr.h>
#include <linux/delay.h>
#include <linux/sched/signal.h>
#include <linux/unaligned.h>
#include <linux/inet.h>
#include <net/ipv6.h>
#include <scsi/scsi_proto.h>
#include <scsi/iscsi_proto.h>
#include <scsi/scsi_tcq.h>
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>

#include <target/target_core_backend.h>
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_parameters.h"
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_datain_values.h"
#include "iscsi_target_erl0.h"
#include "iscsi_target_erl1.h"
#include "iscsi_target_erl2.h"
#include "iscsi_target_login.h"
#include "iscsi_target_tmr.h"
#include "iscsi_target_tpg.h"
#include "iscsi_target_util.h"
#include "iscsi_target.h"
#include "iscsi_target_device.h"
#include <target/iscsi/iscsi_target_stat.h>

#include <target/iscsi/iscsi_transport.h>

static LIST_HEAD(g_tiqn_list);
static LIST_HEAD(g_np_list);
static DEFINE_SPINLOCK(tiqn_lock);
static DEFINE_MUTEX(np_lock);

static struct idr tiqn_idr;
DEFINE_IDA();
struct mutex auth_id_lock;

struct iscsit_global *iscsit_global;

struct kmem_cache *lio_qr_cache;
struct kmem_cache *lio_dr_cache;
struct kmem_cache *lio_ooo_cache;
struct kmem_cache *lio_r2t_cache;

static int iscsit_handle_immediate_data(struct iscsit_cmd *,
			struct iscsi_scsi_req *, u32);

struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
{}

static int iscsit_set_tiqn_shutdown(struct iscsi_tiqn *tiqn)
{}

void iscsit_put_tiqn_for_login(struct iscsi_tiqn *tiqn)
{}

/*
 * Note that IQN formatting is expected to be done in userspace, and
 * no explict IQN format checks are done here.
 */
struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf)
{}

static void iscsit_wait_for_tiqn(struct iscsi_tiqn *tiqn)
{}

void iscsit_del_tiqn(struct iscsi_tiqn *tiqn)
{}

int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
{}

void iscsit_login_kref_put(struct kref *kref)
{}

int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg,
		       struct iscsi_tpg_np *tpg_np)
{}

bool iscsit_check_np_match(
	struct sockaddr_storage *sockaddr,
	struct iscsi_np *np,
	int network_transport)
{}

static struct iscsi_np *iscsit_get_np(
	struct sockaddr_storage *sockaddr,
	int network_transport)
{}

struct iscsi_np *iscsit_add_np(
	struct sockaddr_storage *sockaddr,
	int network_transport)
{}

int iscsit_reset_np_thread(
	struct iscsi_np *np,
	struct iscsi_tpg_np *tpg_np,
	struct iscsi_portal_group *tpg,
	bool shutdown)
{}

static void iscsit_free_np(struct iscsi_np *np)
{}

int iscsit_del_np(struct iscsi_np *np)
{}

static void iscsit_get_rx_pdu(struct iscsit_conn *);

int iscsit_queue_rsp(struct iscsit_conn *conn, struct iscsit_cmd *cmd)
{}
EXPORT_SYMBOL();

void iscsit_aborted_task(struct iscsit_conn *conn, struct iscsit_cmd *cmd)
{}
EXPORT_SYMBOL();

static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *,
				      u32, u32, const void *, void *);
static void iscsit_tx_thread_wait_for_tcp(struct iscsit_conn *);

static int
iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			  const void *data_buf, u32 data_buf_len)
{}

static int iscsit_map_iovec(struct iscsit_cmd *cmd, struct kvec *iov, int nvec,
			    u32 data_offset, u32 data_length);
static void iscsit_unmap_iovec(struct iscsit_cmd *);
static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsit_cmd *,
				    u32, u32, u32, u8 *);
static int
iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
		       const struct iscsi_datain *datain)
{}

static int iscsit_xmit_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			   struct iscsi_datain_req *dr, const void *buf,
			   u32 buf_len)
{}

static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsit_conn *conn)
{}

static struct iscsit_transport iscsi_target_transport =;

static int __init iscsi_target_init_module(void)
{}

static void __exit iscsi_target_cleanup_module(void)
{}

int iscsit_add_reject(
	struct iscsit_conn *conn,
	u8 reason,
	unsigned char *buf)
{}
EXPORT_SYMBOL();

static int iscsit_add_reject_from_cmd(
	struct iscsit_cmd *cmd,
	u8 reason,
	bool add_to_conn,
	unsigned char *buf)
{}

static int iscsit_add_reject_cmd(struct iscsit_cmd *cmd, u8 reason,
				 unsigned char *buf)
{}

int iscsit_reject_cmd(struct iscsit_cmd *cmd, u8 reason, unsigned char *buf)
{}
EXPORT_SYMBOL();

/*
 * Map some portion of the allocated scatterlist to an iovec, suitable for
 * kernel sockets to copy data in/out.
 */
static int iscsit_map_iovec(struct iscsit_cmd *cmd, struct kvec *iov, int nvec,
			    u32 data_offset, u32 data_length)
{}

static void iscsit_unmap_iovec(struct iscsit_cmd *cmd)
{}

static void iscsit_ack_from_expstatsn(struct iscsit_conn *conn, u32 exp_statsn)
{}

static int iscsit_allocate_iovecs(struct iscsit_cmd *cmd)
{}

int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			  unsigned char *buf)
{}
EXPORT_SYMBOL();

void iscsit_set_unsolicited_dataout(struct iscsit_cmd *cmd)
{}
EXPORT_SYMBOL();

int iscsit_process_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			    struct iscsi_scsi_req *hdr)
{}
EXPORT_SYMBOL();

static int
iscsit_get_immediate_data(struct iscsit_cmd *cmd, struct iscsi_scsi_req *hdr,
			  bool dump_payload)
{}

static int
iscsit_handle_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			   unsigned char *buf)
{}

static u32 iscsit_do_crypto_hash_sg(
	struct ahash_request *hash,
	struct iscsit_cmd *cmd,
	u32 data_offset,
	u32 data_length,
	u32 padding,
	u8 *pad_bytes)
{}

static void iscsit_do_crypto_hash_buf(struct ahash_request *hash,
	const void *buf, u32 payload_length, u32 padding,
	const void *pad_bytes, void *data_crc)
{}

int
__iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
			   struct iscsit_cmd *cmd, u32 payload_length,
			   bool *success)
{}
EXPORT_SYMBOL();

int
iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
			 struct iscsit_cmd **out_cmd)
{}
EXPORT_SYMBOL();

static int
iscsit_get_dataout(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
		   struct iscsi_data *hdr)
{}

int
iscsit_check_dataout_payload(struct iscsit_cmd *cmd, struct iscsi_data *hdr,
			     bool data_crc_failed)
{}
EXPORT_SYMBOL();

static int iscsit_handle_data_out(struct iscsit_conn *conn, unsigned char *buf)
{}

int iscsit_setup_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			 struct iscsi_nopout *hdr)
{}
EXPORT_SYMBOL();

int iscsit_process_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			   struct iscsi_nopout *hdr)
{}
EXPORT_SYMBOL();

static int iscsit_handle_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
				 unsigned char *buf)
{}

static enum tcm_tmreq_table iscsit_convert_tmf(u8 iscsi_tmf)
{}

int
iscsit_handle_task_mgt_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			   unsigned char *buf)
{}
EXPORT_SYMBOL();

/* #warning FIXME: Support Text Command parameters besides SendTargets */
int
iscsit_setup_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
		      struct iscsi_text *hdr)
{}
EXPORT_SYMBOL();

int
iscsit_process_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			struct iscsi_text *hdr)
{}
EXPORT_SYMBOL();

static int
iscsit_handle_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
		       unsigned char *buf)
{}

int iscsit_logout_closesession(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

int iscsit_logout_closeconnection(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

int iscsit_logout_removeconnforrecovery(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

int
iscsit_handle_logout_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
			unsigned char *buf)
{}
EXPORT_SYMBOL();

int iscsit_handle_snack(
	struct iscsit_conn *conn,
	unsigned char *buf)
{}
EXPORT_SYMBOL();

static void iscsit_rx_thread_wait_for_tcp(struct iscsit_conn *conn)
{}

static int iscsit_handle_immediate_data(
	struct iscsit_cmd *cmd,
	struct iscsi_scsi_req *hdr,
	u32 length)
{}

/* #warning iscsi_build_conn_drop_async_message() only sends out on connections
	with active network interface */
static void iscsit_build_conn_drop_async_message(struct iscsit_conn *conn)
{}

static int iscsit_send_conn_drop_async_message(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn)
{}

static void iscsit_tx_thread_wait_for_tcp(struct iscsit_conn *conn)
{}

void
iscsit_build_datain_pdu(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
			struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
			bool set_statsn)
{}
EXPORT_SYMBOL();

static int iscsit_send_datain(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

int
iscsit_build_logout_rsp(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
			struct iscsi_logout_rsp *hdr)
{}
EXPORT_SYMBOL();

static int
iscsit_send_logout(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

void
iscsit_build_nopin_rsp(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
		       struct iscsi_nopin *hdr, bool nopout_response)
{}
EXPORT_SYMBOL();

/*
 *	Unsolicited NOPIN, either requesting a response or not.
 */
static int iscsit_send_unsolicited_nopin(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn,
	int want_response)
{}

static int
iscsit_send_nopin(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

static int iscsit_send_r2t(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn)
{}

/*
 *	@recovery: If called from iscsi_task_reassign_complete_write() for
 *		connection recovery.
 */
int iscsit_build_r2ts_for_cmd(
	struct iscsit_conn *conn,
	struct iscsit_cmd *cmd,
	bool recovery)
{}
EXPORT_SYMBOL();

void iscsit_build_rsp_pdu(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
			bool inc_stat_sn, struct iscsi_scsi_rsp *hdr)
{}
EXPORT_SYMBOL();

static int iscsit_send_response(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr)
{}

void
iscsit_build_task_mgt_rsp(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
			  struct iscsi_tm_rsp *hdr)
{}
EXPORT_SYMBOL();

static int
iscsit_send_task_mgt_rsp(struct iscsit_cmd *cmd, struct iscsit_conn *conn)
{}

#define SENDTARGETS_BUF_LIMIT

static int
iscsit_build_sendtargets_response(struct iscsit_cmd *cmd,
				  enum iscsit_transport_type network_transport,
				  int skip_bytes, bool *completed)
{}

int
iscsit_build_text_rsp(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
		      struct iscsi_text_rsp *hdr,
		      enum iscsit_transport_type network_transport)
{}
EXPORT_SYMBOL();

static int iscsit_send_text_rsp(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn)
{}

void
iscsit_build_reject(struct iscsit_cmd *cmd, struct iscsit_conn *conn,
		    struct iscsi_reject *hdr)
{}
EXPORT_SYMBOL();

static int iscsit_send_reject(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn)
{}

void iscsit_thread_get_cpumask(struct iscsit_conn *conn)
{}

static void iscsit_thread_reschedule(struct iscsit_conn *conn)
{}

void iscsit_thread_check_cpumask(
	struct iscsit_conn *conn,
	struct task_struct *p,
	int mode)
{}
EXPORT_SYMBOL();

int
iscsit_immediate_queue(struct iscsit_conn *conn, struct iscsit_cmd *cmd, int state)
{}
EXPORT_SYMBOL();

static int
iscsit_handle_immediate_queue(struct iscsit_conn *conn)
{}

int
iscsit_response_queue(struct iscsit_conn *conn, struct iscsit_cmd *cmd, int state)
{}
EXPORT_SYMBOL();

static int iscsit_handle_response_queue(struct iscsit_conn *conn)
{}

int iscsi_target_tx_thread(void *arg)
{}

static int iscsi_target_rx_opcode(struct iscsit_conn *conn, unsigned char *buf)
{}

static bool iscsi_target_check_conn_state(struct iscsit_conn *conn)
{}

static void iscsit_get_rx_pdu(struct iscsit_conn *conn)
{}

int iscsi_target_rx_thread(void *arg)
{}

static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
{}

static void iscsit_stop_timers_for_cmds(
	struct iscsit_conn *conn)
{}

int iscsit_close_connection(
	struct iscsit_conn *conn)
{}

/*
 * If the iSCSI Session for the iSCSI Initiator Node exists,
 * forcefully shutdown the iSCSI NEXUS.
 */
int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
{}

static void iscsit_logout_post_handler_closesession(
	struct iscsit_conn *conn)
{}

static void iscsit_logout_post_handler_samecid(
	struct iscsit_conn *conn)
{}

static void iscsit_logout_post_handler_diffcid(
	struct iscsit_conn *conn,
	u16 cid)
{}

/*
 *	Return of 0 causes the TX thread to restart.
 */
int iscsit_logout_post_handler(
	struct iscsit_cmd *cmd,
	struct iscsit_conn *conn)
{}
EXPORT_SYMBOL();

void iscsit_fail_session(struct iscsit_session *sess)
{}

void iscsit_stop_session(
	struct iscsit_session *sess,
	int session_sleep,
	int connection_sleep)
{}

int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
{}

MODULE_DESCRIPTION();
MODULE_VERSION();
MODULE_AUTHOR();
MODULE_LICENSE();

module_init();
module_exit(iscsi_target_cleanup_module);