iscsi_target_core.h 24.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#ifndef ISCSI_TARGET_CORE_H
#define ISCSI_TARGET_CORE_H

#include <linux/in.h>
#include <linux/configfs.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/iscsi_proto.h>
#include <target/target_core_base.h>

12
#define ISCSIT_VERSION			"v4.1.0-rc2"
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#define ISCSI_MAX_DATASN_MISSING_COUNT	16
#define ISCSI_TX_THREAD_TCP_TIMEOUT	2
#define ISCSI_RX_THREAD_TCP_TIMEOUT	2
#define SECONDS_FOR_ASYNC_LOGOUT	10
#define SECONDS_FOR_ASYNC_TEXT		10
#define SECONDS_FOR_LOGOUT_COMP		15
#define WHITE_SPACE			" \t\v\f\n\r"

/* struct iscsi_node_attrib sanity values */
#define NA_DATAOUT_TIMEOUT		3
#define NA_DATAOUT_TIMEOUT_MAX		60
#define NA_DATAOUT_TIMEOUT_MIX		2
#define NA_DATAOUT_TIMEOUT_RETRIES	5
#define NA_DATAOUT_TIMEOUT_RETRIES_MAX	15
#define NA_DATAOUT_TIMEOUT_RETRIES_MIN	1
#define NA_NOPIN_TIMEOUT		5
#define NA_NOPIN_TIMEOUT_MAX		60
#define NA_NOPIN_TIMEOUT_MIN		3
#define NA_NOPIN_RESPONSE_TIMEOUT	5
#define NA_NOPIN_RESPONSE_TIMEOUT_MAX	60
#define NA_NOPIN_RESPONSE_TIMEOUT_MIN	3
#define NA_RANDOM_DATAIN_PDU_OFFSETS	0
#define NA_RANDOM_DATAIN_SEQ_OFFSETS	0
#define NA_RANDOM_R2T_OFFSETS		0
#define NA_DEFAULT_ERL			0
#define NA_DEFAULT_ERL_MAX		2
#define NA_DEFAULT_ERL_MIN		0

/* struct iscsi_tpg_attrib sanity values */
#define TA_AUTHENTICATION		1
#define TA_LOGIN_TIMEOUT		15
#define TA_LOGIN_TIMEOUT_MAX		30
#define TA_LOGIN_TIMEOUT_MIN		5
#define TA_NETIF_TIMEOUT		2
#define TA_NETIF_TIMEOUT_MAX		15
#define TA_NETIF_TIMEOUT_MIN		2
#define TA_GENERATE_NODE_ACLS		0
#define TA_DEFAULT_CMDSN_DEPTH		16
#define TA_DEFAULT_CMDSN_DEPTH_MAX	512
#define TA_DEFAULT_CMDSN_DEPTH_MIN	1
#define TA_CACHE_DYNAMIC_ACLS		0
/* Enabled by default in demo mode (generic_node_acls=1) */
#define TA_DEMO_MODE_WRITE_PROTECT	1
/* Disabled by default in production mode w/ explict ACLs */
#define TA_PROD_MODE_WRITE_PROTECT	0
#define TA_CACHE_CORE_NPS		0

60 61 62

#define ISCSI_IOV_DATA_BUFFER		5

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
enum tpg_np_network_transport_table {
	ISCSI_TCP				= 0,
	ISCSI_SCTP_TCP				= 1,
	ISCSI_SCTP_UDP				= 2,
	ISCSI_IWARP_TCP				= 3,
	ISCSI_IWARP_SCTP			= 4,
	ISCSI_INFINIBAND			= 5,
};

/* RFC-3720 7.1.4  Standard Connection State Diagram for a Target */
enum target_conn_state_table {
	TARG_CONN_STATE_FREE			= 0x1,
	TARG_CONN_STATE_XPT_UP			= 0x3,
	TARG_CONN_STATE_IN_LOGIN		= 0x4,
	TARG_CONN_STATE_LOGGED_IN		= 0x5,
	TARG_CONN_STATE_IN_LOGOUT		= 0x6,
	TARG_CONN_STATE_LOGOUT_REQUESTED	= 0x7,
	TARG_CONN_STATE_CLEANUP_WAIT		= 0x8,
};

/* RFC-3720 7.3.2  Session State Diagram for a Target */
enum target_sess_state_table {
	TARG_SESS_STATE_FREE			= 0x1,
	TARG_SESS_STATE_ACTIVE			= 0x2,
	TARG_SESS_STATE_LOGGED_IN		= 0x3,
	TARG_SESS_STATE_FAILED			= 0x4,
	TARG_SESS_STATE_IN_CONTINUE		= 0x5,
};

/* struct iscsi_data_count->type */
enum data_count_type {
	ISCSI_RX_DATA	= 1,
	ISCSI_TX_DATA	= 2,
};

/* struct iscsi_datain_req->dr_complete */
enum datain_req_comp_table {
	DATAIN_COMPLETE_NORMAL			= 1,
	DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY = 2,
	DATAIN_COMPLETE_CONNECTION_RECOVERY	= 3,
};

/* struct iscsi_datain_req->recovery */
enum datain_req_rec_table {
	DATAIN_WITHIN_COMMAND_RECOVERY		= 1,
	DATAIN_CONNECTION_RECOVERY		= 2,
};

/* struct iscsi_portal_group->state */
enum tpg_state_table {
	TPG_STATE_FREE				= 0,
	TPG_STATE_ACTIVE			= 1,
	TPG_STATE_INACTIVE			= 2,
	TPG_STATE_COLD_RESET			= 3,
};

/* struct iscsi_tiqn->tiqn_state */
enum tiqn_state_table {
	TIQN_STATE_ACTIVE			= 1,
	TIQN_STATE_SHUTDOWN			= 2,
};

/* struct iscsi_cmd->cmd_flags */
enum cmd_flags_table {
	ICF_GOT_LAST_DATAOUT			= 0x00000001,
	ICF_GOT_DATACK_SNACK			= 0x00000002,
	ICF_NON_IMMEDIATE_UNSOLICITED_DATA	= 0x00000004,
	ICF_SENT_LAST_R2T			= 0x00000008,
	ICF_WITHIN_COMMAND_RECOVERY		= 0x00000010,
	ICF_CONTIG_MEMORY			= 0x00000020,
	ICF_ATTACHED_TO_RQUEUE			= 0x00000040,
	ICF_OOO_CMDSN				= 0x00000080,
	ICF_REJECT_FAIL_CONN			= 0x00000100,
};

/* struct iscsi_cmd->i_state */
enum cmd_i_state_table {
	ISTATE_NO_STATE			= 0,
	ISTATE_NEW_CMD			= 1,
	ISTATE_DEFERRED_CMD		= 2,
	ISTATE_UNSOLICITED_DATA		= 3,
	ISTATE_RECEIVE_DATAOUT		= 4,
	ISTATE_RECEIVE_DATAOUT_RECOVERY	= 5,
	ISTATE_RECEIVED_LAST_DATAOUT	= 6,
	ISTATE_WITHIN_DATAOUT_RECOVERY	= 7,
	ISTATE_IN_CONNECTION_RECOVERY	= 8,
	ISTATE_RECEIVED_TASKMGT		= 9,
	ISTATE_SEND_ASYNCMSG		= 10,
	ISTATE_SENT_ASYNCMSG		= 11,
	ISTATE_SEND_DATAIN		= 12,
	ISTATE_SEND_LAST_DATAIN		= 13,
	ISTATE_SENT_LAST_DATAIN		= 14,
	ISTATE_SEND_LOGOUTRSP		= 15,
	ISTATE_SENT_LOGOUTRSP		= 16,
	ISTATE_SEND_NOPIN		= 17,
	ISTATE_SENT_NOPIN		= 18,
	ISTATE_SEND_REJECT		= 19,
	ISTATE_SENT_REJECT		= 20,
	ISTATE_SEND_R2T			= 21,
	ISTATE_SENT_R2T			= 22,
	ISTATE_SEND_R2T_RECOVERY	= 23,
	ISTATE_SENT_R2T_RECOVERY	= 24,
	ISTATE_SEND_LAST_R2T		= 25,
	ISTATE_SENT_LAST_R2T		= 26,
	ISTATE_SEND_LAST_R2T_RECOVERY	= 27,
	ISTATE_SENT_LAST_R2T_RECOVERY	= 28,
	ISTATE_SEND_STATUS		= 29,
	ISTATE_SEND_STATUS_BROKEN_PC	= 30,
	ISTATE_SENT_STATUS		= 31,
	ISTATE_SEND_STATUS_RECOVERY	= 32,
	ISTATE_SENT_STATUS_RECOVERY	= 33,
	ISTATE_SEND_TASKMGTRSP		= 34,
	ISTATE_SENT_TASKMGTRSP		= 35,
	ISTATE_SEND_TEXTRSP		= 36,
	ISTATE_SENT_TEXTRSP		= 37,
	ISTATE_SEND_NOPIN_WANT_RESPONSE	= 38,
	ISTATE_SENT_NOPIN_WANT_RESPONSE	= 39,
	ISTATE_SEND_NOPIN_NO_RESPONSE	= 40,
	ISTATE_REMOVE			= 41,
	ISTATE_FREE			= 42,
};

/* Used for iscsi_recover_cmdsn() return values */
enum recover_cmdsn_ret_table {
	CMDSN_ERROR_CANNOT_RECOVER	= -1,
	CMDSN_NORMAL_OPERATION		= 0,
	CMDSN_LOWER_THAN_EXP		= 1,
	CMDSN_HIGHER_THAN_EXP		= 2,
};

/* Used for iscsi_handle_immediate_data() return values */
enum immedate_data_ret_table {
	IMMEDIATE_DATA_CANNOT_RECOVER	= -1,
	IMMEDIATE_DATA_NORMAL_OPERATION = 0,
	IMMEDIATE_DATA_ERL1_CRC_FAILURE = 1,
};

/* Used for iscsi_decide_dataout_action() return values */
enum dataout_action_ret_table {
	DATAOUT_CANNOT_RECOVER		= -1,
	DATAOUT_NORMAL			= 0,
	DATAOUT_SEND_R2T		= 1,
	DATAOUT_SEND_TO_TRANSPORT	= 2,
	DATAOUT_WITHIN_COMMAND_RECOVERY = 3,
};

/* Used for struct iscsi_node_auth->naf_flags */
enum naf_flags_table {
	NAF_USERID_SET			= 0x01,
	NAF_PASSWORD_SET		= 0x02,
	NAF_USERID_IN_SET		= 0x04,
	NAF_PASSWORD_IN_SET		= 0x08,
};

/* Used by various struct timer_list to manage iSCSI specific state */
enum iscsi_timer_flags_table {
	ISCSI_TF_RUNNING		= 0x01,
	ISCSI_TF_STOP			= 0x02,
	ISCSI_TF_EXPIRED		= 0x04,
};

/* Used for struct iscsi_np->np_flags */
enum np_flags_table {
	NPF_IP_NETWORK		= 0x00,
};

/* Used for struct iscsi_np->np_thread_state */
enum np_thread_state_table {
	ISCSI_NP_THREAD_ACTIVE		= 1,
	ISCSI_NP_THREAD_INACTIVE	= 2,
	ISCSI_NP_THREAD_RESET		= 3,
	ISCSI_NP_THREAD_SHUTDOWN	= 4,
	ISCSI_NP_THREAD_EXIT		= 5,
};

struct iscsi_conn_ops {
	u8	HeaderDigest;			/* [0,1] == [None,CRC32C] */
	u8	DataDigest;			/* [0,1] == [None,CRC32C] */
	u32	MaxRecvDataSegmentLength;	/* [512..2**24-1] */
242
	u32	MaxXmitDataSegmentLength;	/* [512..2**24-1] */
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	u8	OFMarker;			/* [0,1] == [No,Yes] */
	u8	IFMarker;			/* [0,1] == [No,Yes] */
	u32	OFMarkInt;			/* [1..65535] */
	u32	IFMarkInt;			/* [1..65535] */
};

struct iscsi_sess_ops {
	char	InitiatorName[224];
	char	InitiatorAlias[256];
	char	TargetName[224];
	char	TargetAlias[256];
	char	TargetAddress[256];
	u16	TargetPortalGroupTag;		/* [0..65535] */
	u16	MaxConnections;			/* [1..65535] */
	u8	InitialR2T;			/* [0,1] == [No,Yes] */
	u8	ImmediateData;			/* [0,1] == [No,Yes] */
	u32	MaxBurstLength;			/* [512..2**24-1] */
	u32	FirstBurstLength;		/* [512..2**24-1] */
	u16	DefaultTime2Wait;		/* [0..3600] */
	u16	DefaultTime2Retain;		/* [0..3600] */
	u16	MaxOutstandingR2T;		/* [1..65535] */
	u8	DataPDUInOrder;			/* [0,1] == [No,Yes] */
	u8	DataSequenceInOrder;		/* [0,1] == [No,Yes] */
	u8	ErrorRecoveryLevel;		/* [0..2] */
	u8	SessionType;			/* [0,1] == [Normal,Discovery]*/
};

struct iscsi_queue_req {
	int			state;
	struct iscsi_cmd	*cmd;
	struct list_head	qr_list;
};

struct iscsi_data_count {
	int			data_length;
	int			sync_and_steering;
	enum data_count_type	type;
	u32			iov_count;
	u32			ss_iov_count;
	u32			ss_marker_count;
	struct kvec		*iov;
};

struct iscsi_param_list {
	struct list_head	param_list;
	struct list_head	extra_response_list;
};

struct iscsi_datain_req {
	enum datain_req_comp_table dr_complete;
	int			generate_recovery_values;
	enum datain_req_rec_table recovery;
	u32			begrun;
	u32			runlength;
	u32			data_length;
	u32			data_offset;
	u32			data_sn;
	u32			next_burst_len;
	u32			read_data_done;
	u32			seq_send_order;
303
	struct list_head	cmd_datain_node;
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
} ____cacheline_aligned;

struct iscsi_ooo_cmdsn {
	u16			cid;
	u32			batch_count;
	u32			cmdsn;
	u32			exp_cmdsn;
	struct iscsi_cmd	*cmd;
	struct list_head	ooo_list;
} ____cacheline_aligned;

struct iscsi_datain {
	u8			flags;
	u32			data_sn;
	u32			length;
	u32			offset;
} ____cacheline_aligned;

struct iscsi_r2t {
	int			seq_complete;
	int			recovery_r2t;
	int			sent_r2t;
	u32			r2t_sn;
	u32			offset;
	u32			targ_xfer_tag;
	u32			xfer_len;
	struct list_head	r2t_list;
} ____cacheline_aligned;

struct iscsi_cmd {
	enum iscsi_timer_flags_table dataout_timer_flags;
	/* DataOUT timeout retries */
	u8			dataout_timeout_retries;
	/* Within command recovery count */
	u8			error_recovery_count;
	/* iSCSI dependent state for out or order CmdSNs */
	enum cmd_i_state_table	deferred_i_state;
	/* iSCSI dependent state */
	enum cmd_i_state_table	i_state;
	/* Command is an immediate command (ISCSI_OP_IMMEDIATE set) */
	u8			immediate_cmd;
	/* Immediate data present */
	u8			immediate_data;
	/* iSCSI Opcode */
	u8			iscsi_opcode;
	/* iSCSI Response Code */
	u8			iscsi_response;
	/* Logout reason when iscsi_opcode == ISCSI_INIT_LOGOUT_CMND */
	u8			logout_reason;
	/* Logout response code when iscsi_opcode == ISCSI_INIT_LOGOUT_CMND */
	u8			logout_response;
	/* MaxCmdSN has been incremented */
	u8			maxcmdsn_inc;
	/* Immediate Unsolicited Dataout */
	u8			unsolicited_data;
	/* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */
	u16			logout_cid;
	/* Command flags */
	enum cmd_flags_table	cmd_flags;
	/* Initiator Task Tag assigned from Initiator */
	u32			init_task_tag;
	/* Target Transfer Tag assigned from Target */
	u32			targ_xfer_tag;
	/* CmdSN assigned from Initiator */
	u32			cmd_sn;
	/* ExpStatSN assigned from Initiator */
	u32			exp_stat_sn;
	/* StatSN assigned to this ITT */
	u32			stat_sn;
	/* DataSN Counter */
	u32			data_sn;
	/* R2TSN Counter */
	u32			r2t_sn;
	/* Last DataSN acknowledged via DataAck SNACK */
	u32			acked_data_sn;
	/* Used for echoing NOPOUT ping data */
	u32			buf_ptr_size;
	/* Used to store DataDigest */
	u32			data_crc;
	/* Counter for MaxOutstandingR2T */
	u32			outstanding_r2ts;
	/* Next R2T Offset when DataSequenceInOrder=Yes */
	u32			r2t_offset;
	/* Iovec current and orig count for iscsi_cmd->iov_data */
	u32			iov_data_count;
	u32			orig_iov_data_count;
	/* Number of miscellaneous iovecs used for IP stack calls */
	u32			iov_misc_count;
	/* Number of struct iscsi_pdu in struct iscsi_cmd->pdu_list */
	u32			pdu_count;
	/* Next struct iscsi_pdu to send in struct iscsi_cmd->pdu_list */
	u32			pdu_send_order;
	/* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */
	u32			pdu_start;
	/* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */
	u32			seq_send_order;
	/* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */
	u32			seq_count;
	/* Current struct iscsi_seq in struct iscsi_cmd->seq_list */
	u32			seq_no;
	/* Lowest offset in current DataOUT sequence */
	u32			seq_start_offset;
	/* Highest offset in current DataOUT sequence */
	u32			seq_end_offset;
	/* Total size in bytes received so far of READ data */
	u32			read_data_done;
	/* Total size in bytes received so far of WRITE data */
	u32			write_data_done;
	/* Counter for FirstBurstLength key */
	u32			first_burst_len;
	/* Counter for MaxBurstLength key */
	u32			next_burst_len;
	/* Transfer size used for IP stack calls */
	u32			tx_size;
	/* Buffer used for various purposes */
	void			*buf_ptr;
	/* See include/linux/dma-mapping.h */
	enum dma_data_direction	data_direction;
	/* iSCSI PDU Header + CRC */
	unsigned char		pdu[ISCSI_HDR_LEN + ISCSI_CRC_LEN];
	/* Number of times struct iscsi_cmd is present in immediate queue */
	atomic_t		immed_queue_count;
	atomic_t		response_queue_count;
	spinlock_t		datain_lock;
	spinlock_t		dataout_timeout_lock;
	/* spinlock for protecting struct iscsi_cmd->i_state */
	spinlock_t		istate_lock;
	/* spinlock for adding within command recovery entries */
	spinlock_t		error_lock;
	/* spinlock for adding R2Ts */
	spinlock_t		r2t_lock;
	/* DataIN List */
	struct list_head	datain_list;
	/* R2T List */
	struct list_head	cmd_r2t_list;
	struct completion	reject_comp;
	/* Timer for DataOUT */
	struct timer_list	dataout_timer;
	/* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */
	struct kvec		*iov_data;
	/* Iovecs for miscellaneous purposes */
#define ISCSI_MISC_IOVECS			5
	struct kvec		iov_misc[ISCSI_MISC_IOVECS];
	/* Array of struct iscsi_pdu used for DataPDUInOrder=No */
	struct iscsi_pdu	*pdu_list;
	/* Current struct iscsi_pdu used for DataPDUInOrder=No */
	struct iscsi_pdu	*pdu_ptr;
	/* Array of struct iscsi_seq used for DataSequenceInOrder=No */
	struct iscsi_seq	*seq_list;
	/* Current struct iscsi_seq used for DataSequenceInOrder=No */
	struct iscsi_seq	*seq_ptr;
	/* TMR Request when iscsi_opcode == ISCSI_OP_SCSI_TMFUNC */
	struct iscsi_tmr_req	*tmr_req;
	/* Connection this command is alligient to */
	struct iscsi_conn	*conn;
	/* Pointer to connection recovery entry */
	struct iscsi_conn_recovery *cr;
	/* Session the command is part of,  used for connection recovery */
	struct iscsi_session	*sess;
	/* list_head for connection list */
464
	struct list_head	i_conn_node;
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
	/* The TCM I/O descriptor that is accessed via container_of() */
	struct se_cmd		se_cmd;
	/* Sense buffer that will be mapped into outgoing status */
#define ISCSI_SENSE_BUFFER_LEN          (TRANSPORT_SENSE_BUFFER + 2)
	unsigned char		sense_buffer[ISCSI_SENSE_BUFFER_LEN];

	u32			padding;
	u8			pad_bytes[4];

	struct scatterlist	*first_data_sg;
	u32			first_data_sg_off;
	u32			kmapped_nents;

}  ____cacheline_aligned;

struct iscsi_tmr_req {
	bool			task_reassign:1;
	u32			ref_cmd_sn;
	u32			exp_data_sn;
484
	struct iscsi_cmd	*ref_cmd;
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
	struct iscsi_conn_recovery *conn_recovery;
	struct se_tmr_req	*se_tmr_req;
};

struct iscsi_conn {
	/* Authentication Successful for this connection */
	u8			auth_complete;
	/* State connection is currently in */
	u8			conn_state;
	u8			conn_logout_reason;
	u8			network_transport;
	enum iscsi_timer_flags_table nopin_timer_flags;
	enum iscsi_timer_flags_table nopin_response_timer_flags;
	/* Used to know what thread encountered a transport failure */
	u8			which_thread;
	/* connection id assigned by the Initiator */
	u16			cid;
	/* Remote TCP Port */
	u16			login_port;
504
	u16			local_port;
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
	int			net_size;
	u32			auth_id;
	u32			conn_flags;
	/* Used for iscsi_tx_login_rsp() */
	u32			login_itt;
	u32			exp_statsn;
	/* Per connection status sequence number */
	u32			stat_sn;
	/* IFMarkInt's Current Value */
	u32			if_marker;
	/* OFMarkInt's Current Value */
	u32			of_marker;
	/* Used for calculating OFMarker offset to next PDU */
	u32			of_marker_offset;
	/* Complete Bad PDU for sending reject */
	unsigned char		bad_hdr[ISCSI_HDR_LEN];
#define IPV6_ADDRESS_SPACE				48
	unsigned char		login_ip[IPV6_ADDRESS_SPACE];
523
	unsigned char		local_ip[IPV6_ADDRESS_SPACE];
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
	int			conn_usage_count;
	int			conn_waiting_on_uc;
	atomic_t		check_immediate_queue;
	atomic_t		conn_logout_remove;
	atomic_t		connection_exit;
	atomic_t		connection_recovery;
	atomic_t		connection_reinstatement;
	atomic_t		connection_wait_rcfr;
	atomic_t		sleep_on_conn_wait_comp;
	atomic_t		transport_failed;
	struct completion	conn_post_wait_comp;
	struct completion	conn_wait_comp;
	struct completion	conn_wait_rcfr_comp;
	struct completion	conn_waiting_on_uc_comp;
	struct completion	conn_logout_comp;
	struct completion	tx_half_close_comp;
	struct completion	rx_half_close_comp;
	/* socket used by this connection */
	struct socket		*sock;
	struct timer_list	nopin_timer;
	struct timer_list	nopin_response_timer;
	struct timer_list	transport_timer;
	/* Spinlock used for add/deleting cmd's from conn_cmd_list */
	spinlock_t		cmd_lock;
	spinlock_t		conn_usage_lock;
	spinlock_t		immed_queue_lock;
	spinlock_t		nopin_timer_lock;
	spinlock_t		response_queue_lock;
	spinlock_t		state_lock;
	/* libcrypto RX and TX contexts for crc32c */
	struct hash_desc	conn_rx_hash;
	struct hash_desc	conn_tx_hash;
	/* Used for scheduling TX and RX connection kthreads */
	cpumask_var_t		conn_cpumask;
558 559
	unsigned int		conn_rx_reset_cpumask:1;
	unsigned int		conn_tx_reset_cpumask:1;
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
	/* list_head of struct iscsi_cmd for this connection */
	struct list_head	conn_cmd_list;
	struct list_head	immed_queue_list;
	struct list_head	response_queue_list;
	struct iscsi_conn_ops	*conn_ops;
	struct iscsi_param_list	*param_list;
	/* Used for per connection auth state machine */
	void			*auth_protocol;
	struct iscsi_login_thread_s *login_thread;
	struct iscsi_portal_group *tpg;
	/* Pointer to parent session */
	struct iscsi_session	*sess;
	/* Pointer to thread_set in use for this conn's threads */
	struct iscsi_thread_set	*thread_set;
	/* list_head for session connection list */
	struct list_head	conn_list;
} ____cacheline_aligned;

struct iscsi_conn_recovery {
	u16			cid;
	u32			cmd_count;
	u32			maxrecvdatasegmentlength;
	int			ready_for_reallegiance;
	struct list_head	conn_recovery_cmd_list;
	spinlock_t		conn_recovery_cmd_lock;
	struct timer_list	time2retain_timer;
	struct iscsi_session	*sess;
	struct list_head	cr_list;
}  ____cacheline_aligned;

struct iscsi_session {
	u8			initiator_vendor;
	u8			isid[6];
	enum iscsi_timer_flags_table time2retain_timer_flags;
	u8			version_active;
	u16			cid_called;
	u16			conn_recovery_count;
	u16			tsih;
	/* state session is currently in */
	u32			session_state;
	/* session wide counter: initiator assigned task tag */
	u32			init_task_tag;
	/* session wide counter: target assigned task tag */
	u32			targ_xfer_tag;
	u32			cmdsn_window;

	/* protects cmdsn values */
	struct mutex		cmdsn_mutex;
	/* session wide counter: expected command sequence number */
	u32			exp_cmd_sn;
	/* session wide counter: maximum allowed command sequence number */
	u32			max_cmd_sn;
	struct list_head	sess_ooo_cmdsn_list;

	/* LIO specific session ID */
	u32			sid;
	char			auth_type[8];
	/* unique within the target */
	int			session_index;
	/* Used for session reference counting */
	int			session_usage_count;
	int			session_waiting_on_uc;
	u32			cmd_pdus;
	u32			rsp_pdus;
	u64			tx_data_octets;
	u64			rx_data_octets;
	u32			conn_digest_errors;
	u32			conn_timeout_errors;
	u64			creation_time;
	spinlock_t		session_stats_lock;
	/* Number of active connections */
	atomic_t		nconn;
	atomic_t		session_continuation;
	atomic_t		session_fall_back_to_erl0;
	atomic_t		session_logout;
	atomic_t		session_reinstatement;
	atomic_t		session_stop_active;
	atomic_t		sleep_on_sess_wait_comp;
	/* connection list */
	struct list_head	sess_conn_list;
	struct list_head	cr_active_list;
	struct list_head	cr_inactive_list;
	spinlock_t		conn_lock;
	spinlock_t		cr_a_lock;
	spinlock_t		cr_i_lock;
	spinlock_t		session_usage_lock;
	spinlock_t		ttt_lock;
	struct completion	async_msg_comp;
	struct completion	reinstatement_comp;
	struct completion	session_wait_comp;
	struct completion	session_waiting_on_uc_comp;
	struct timer_list	time2retain_timer;
	struct iscsi_sess_ops	*sess_ops;
	struct se_session	*se_sess;
	struct iscsi_portal_group *tpg;
} ____cacheline_aligned;

struct iscsi_login {
	u8 auth_complete;
	u8 checked_for_existing;
	u8 current_stage;
	u8 leading_connection;
	u8 first_request;
	u8 version_min;
	u8 version_max;
	char isid[6];
	u32 cmd_sn;
	u32 init_task_tag;
	u32 initial_exp_statsn;
	u32 rsp_length;
	u16 cid;
	u16 tsih;
	char *req;
	char *rsp;
	char *req_buf;
	char *rsp_buf;
} ____cacheline_aligned;

struct iscsi_node_attrib {
	u32			dataout_timeout;
	u32			dataout_timeout_retries;
	u32			default_erl;
	u32			nopin_timeout;
	u32			nopin_response_timeout;
	u32			random_datain_pdu_offsets;
	u32			random_datain_seq_offsets;
	u32			random_r2t_offsets;
	u32			tmr_cold_reset;
	u32			tmr_warm_reset;
	struct iscsi_node_acl *nacl;
};

struct se_dev_entry_s;

struct iscsi_node_auth {
	enum naf_flags_table	naf_flags;
	int			authenticate_target;
	/* Used for iscsit_global->discovery_auth,
	 * set to zero (auth disabled) by default */
	int			enforce_discovery_auth;
#define MAX_USER_LEN				256
#define MAX_PASS_LEN				256
	char			userid[MAX_USER_LEN];
	char			password[MAX_PASS_LEN];
	char			userid_mutual[MAX_USER_LEN];
	char			password_mutual[MAX_PASS_LEN];
};

#include "iscsi_target_stat.h"

struct iscsi_node_stat_grps {
	struct config_group	iscsi_sess_stats_group;
	struct config_group	iscsi_conn_stats_group;
};

struct iscsi_node_acl {
	struct iscsi_node_attrib node_attrib;
	struct iscsi_node_auth	node_auth;
	struct iscsi_node_stat_grps node_stat_grps;
	struct se_node_acl	se_node_acl;
};

#define NODE_STAT_GRPS(nacl)	(&(nacl)->node_stat_grps)

#define ISCSI_NODE_ATTRIB(t)	(&(t)->node_attrib)
#define ISCSI_NODE_AUTH(t)	(&(t)->node_auth)

struct iscsi_tpg_attrib {
	u32			authentication;
	u32			login_timeout;
	u32			netif_timeout;
	u32			generate_node_acls;
	u32			cache_dynamic_acls;
	u32			default_cmdsn_depth;
	u32			demo_mode_write_protect;
	u32			prod_mode_write_protect;
	struct iscsi_portal_group *tpg;
};

struct iscsi_np {
	int			np_network_transport;
	int			np_ip_proto;
	int			np_sock_type;
	enum np_thread_state_table np_thread_state;
	enum iscsi_timer_flags_table np_login_timer_flags;
	u32			np_exports;
	enum np_flags_table	np_flags;
	unsigned char		np_ip[IPV6_ADDRESS_SPACE];
	u16			np_port;
	spinlock_t		np_thread_lock;
	struct completion	np_restart_comp;
	struct socket		*np_socket;
	struct __kernel_sockaddr_storage np_sockaddr;
	struct task_struct	*np_thread;
	struct timer_list	np_login_timer;
	struct iscsi_portal_group *np_login_tpg;
	struct list_head	np_list;
} ____cacheline_aligned;

struct iscsi_tpg_np {
	struct iscsi_np		*tpg_np;
	struct iscsi_portal_group *tpg;
	struct iscsi_tpg_np	*tpg_np_parent;
	struct list_head	tpg_np_list;
	struct list_head	tpg_np_child_list;
	struct list_head	tpg_np_parent_list;
	struct se_tpg_np	se_tpg_np;
	spinlock_t		tpg_np_parent_lock;
};

struct iscsi_portal_group {
	unsigned char		tpg_chap_id;
	/* TPG State */
	enum tpg_state_table	tpg_state;
	/* Target Portal Group Tag */
	u16			tpgt;
	/* Id assigned to target sessions */
	u16			ntsih;
	/* Number of active sessions */
	u32			nsessions;
	/* Number of Network Portals available for this TPG */
	u32			num_tpg_nps;
	/* Per TPG LIO specific session ID. */
	u32			sid;
	/* Spinlock for adding/removing Network Portals */
	spinlock_t		tpg_np_lock;
	spinlock_t		tpg_state_lock;
	struct se_portal_group tpg_se_tpg;
	struct mutex		tpg_access_lock;
	struct mutex		np_login_lock;
	struct iscsi_tpg_attrib	tpg_attrib;
	/* Pointer to default list of iSCSI parameters for TPG */
	struct iscsi_param_list	*param_list;
	struct iscsi_tiqn	*tpg_tiqn;
	struct list_head	tpg_gnp_list;
	struct list_head	tpg_list;
} ____cacheline_aligned;

#define ISCSI_TPG_C(c)		((struct iscsi_portal_group *)(c)->tpg)
#define ISCSI_TPG_LUN(c, l)  ((iscsi_tpg_list_t *)(c)->tpg->tpg_lun_list_t[l])
#define ISCSI_TPG_S(s)		((struct iscsi_portal_group *)(s)->tpg)
#define ISCSI_TPG_ATTRIB(t)	(&(t)->tpg_attrib)
#define SE_TPG(tpg)		(&(tpg)->tpg_se_tpg)

struct iscsi_wwn_stat_grps {
	struct config_group	iscsi_stat_group;
	struct config_group	iscsi_instance_group;
	struct config_group	iscsi_sess_err_group;
	struct config_group	iscsi_tgt_attr_group;
	struct config_group	iscsi_login_stats_group;
	struct config_group	iscsi_logout_stats_group;
};

struct iscsi_tiqn {
#define ISCSI_IQN_LEN				224
	unsigned char		tiqn[ISCSI_IQN_LEN];
	enum tiqn_state_table	tiqn_state;
	int			tiqn_access_count;
	u32			tiqn_active_tpgs;
	u32			tiqn_ntpgs;
	u32			tiqn_num_tpg_nps;
	u32			tiqn_nsessions;
	struct list_head	tiqn_list;
	struct list_head	tiqn_tpg_list;
	spinlock_t		tiqn_state_lock;
	spinlock_t		tiqn_tpg_lock;
	struct se_wwn		tiqn_wwn;
	struct iscsi_wwn_stat_grps tiqn_stat_grps;
	int			tiqn_index;
	struct iscsi_sess_err_stats  sess_err_stats;
	struct iscsi_login_stats     login_stats;
	struct iscsi_logout_stats    logout_stats;
} ____cacheline_aligned;

#define WWN_STAT_GRPS(tiqn)	(&(tiqn)->tiqn_stat_grps)

struct iscsit_global {
	/* In core shutdown */
	u32			in_shutdown;
	u32			active_ts;
	/* Unique identifier used for the authentication daemon */
	u32			auth_id;
	u32			inactive_ts;
	/* Thread Set bitmap count */
	int			ts_bitmap_count;
	/* Thread Set bitmap pointer */
	unsigned long		*ts_bitmap;
	/* Used for iSCSI discovery session authentication */
	struct iscsi_node_acl	discovery_acl;
	struct iscsi_portal_group	*discovery_tpg;
};

#endif /* ISCSI_TARGET_CORE_H */