diff options
Diffstat (limited to 'include/target')
-rw-r--r-- | include/target/iscsi/iscsi_target_core.h | 110 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_transport.h | 126 | ||||
-rw-r--r-- | include/target/target_core_backend.h | 19 | ||||
-rw-r--r-- | include/target/target_core_base.h | 171 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 52 |
5 files changed, 287 insertions, 191 deletions
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 1eccb2ac7d02..51ca80abacf7 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -26,6 +26,7 @@ struct sock; #define ISCSI_RX_THREAD_NAME "iscsi_trx" #define ISCSI_TX_THREAD_NAME "iscsi_ttx" #define ISCSI_IQN_LEN 224 +#define NA_AUTHENTICATION_INHERITED -1 /* struct iscsi_node_attrib sanity values */ #define NA_DATAOUT_TIMEOUT 3 @@ -49,9 +50,6 @@ struct sock; #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 64 #define TA_DEFAULT_CMDSN_DEPTH_MAX 512 @@ -143,7 +141,7 @@ enum tiqn_state_table { TIQN_STATE_SHUTDOWN = 2, }; -/* struct iscsi_cmd->cmd_flags */ +/* struct iscsit_cmd->cmd_flags */ enum cmd_flags_table { ICF_GOT_LAST_DATAOUT = 0x00000001, ICF_GOT_DATACK_SNACK = 0x00000002, @@ -157,7 +155,7 @@ enum cmd_flags_table { ICF_SENDTARGETS_SINGLE = 0x00000200, }; -/* struct iscsi_cmd->i_state */ +/* struct iscsit_cmd->i_state */ enum cmd_i_state_table { ISTATE_NO_STATE = 0, ISTATE_NEW_CMD = 1, @@ -297,7 +295,7 @@ struct iscsi_sess_ops { struct iscsi_queue_req { int state; - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; struct list_head qr_list; }; @@ -327,7 +325,7 @@ struct iscsi_ooo_cmdsn { u32 batch_count; u32 cmdsn; u32 exp_cmdsn; - struct iscsi_cmd *cmd; + struct iscsit_cmd *cmd; struct list_head ooo_list; } ____cacheline_aligned; @@ -349,7 +347,7 @@ struct iscsi_r2t { struct list_head r2t_list; } ____cacheline_aligned; -struct iscsi_cmd { +struct iscsit_cmd { enum iscsi_timer_flags_table dataout_timer_flags; /* DataOUT timeout retries */ u8 dataout_timeout_retries; @@ -405,22 +403,22 @@ struct iscsi_cmd { u32 outstanding_r2ts; /* Next R2T Offset when DataSequenceInOrder=Yes */ u32 r2t_offset; - /* Iovec current and orig count for iscsi_cmd->iov_data */ + /* Iovec current and orig count for iscsit_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 */ + /* Number of struct iscsi_pdu in struct iscsit_cmd->pdu_list */ u32 pdu_count; - /* Next struct iscsi_pdu to send in struct iscsi_cmd->pdu_list */ + /* Next struct iscsi_pdu to send in struct iscsit_cmd->pdu_list */ u32 pdu_send_order; - /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ + /* Current struct iscsi_pdu in struct iscsit_cmd->pdu_list */ u32 pdu_start; - /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ + /* Next struct iscsi_seq to send in struct iscsit_cmd->seq_list */ u32 seq_send_order; - /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ + /* Number of struct iscsi_seq in struct iscsit_cmd->seq_list */ u32 seq_count; - /* Current struct iscsi_seq in struct iscsi_cmd->seq_list */ + /* Current struct iscsi_seq in struct iscsit_cmd->seq_list */ u32 seq_no; /* Lowest offset in current DataOUT sequence */ u32 seq_start_offset; @@ -444,12 +442,12 @@ struct iscsi_cmd { 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 */ + /* Number of times struct iscsit_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 for protecting struct iscsit_cmd->i_state */ spinlock_t istate_lock; /* spinlock for adding within command recovery entries */ spinlock_t error_lock; @@ -478,11 +476,11 @@ struct iscsi_cmd { /* 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; + struct iscsit_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; + struct iscsit_session *sess; /* list_head for connection list */ struct list_head i_conn_node; /* The TCM I/O descriptor that is accessed via container_of() */ @@ -503,12 +501,12 @@ struct iscsi_cmd { struct iscsi_tmr_req { bool task_reassign:1; u32 exp_data_sn; - struct iscsi_cmd *ref_cmd; + struct iscsit_cmd *ref_cmd; struct iscsi_conn_recovery *conn_recovery; struct se_tmr_req *se_tmr_req; }; -struct iscsi_conn { +struct iscsit_conn { wait_queue_head_t queues_wq; /* Authentication Successful for this connection */ u8 auth_complete; @@ -561,12 +559,13 @@ struct iscsi_conn { #define LOGIN_FLAGS_READ_ACTIVE 2 #define LOGIN_FLAGS_WRITE_ACTIVE 3 #define LOGIN_FLAGS_CLOSED 4 +#define LOGIN_FLAGS_WORKER_RUNNING 5 unsigned long login_flags; struct delayed_work login_work; struct iscsi_login *login; struct timer_list nopin_timer; struct timer_list nopin_response_timer; - struct timer_list transport_timer; + struct timer_list login_timer; struct task_struct *login_kworker; /* Spinlock used for add/deleting cmd's from conn_cmd_list */ spinlock_t cmd_lock; @@ -575,14 +574,14 @@ struct iscsi_conn { spinlock_t nopin_timer_lock; spinlock_t response_queue_lock; spinlock_t state_lock; - /* libcrypto RX and TX contexts for crc32c */ - struct ahash_request *conn_rx_hash; - struct ahash_request *conn_tx_hash; + spinlock_t login_timer_lock; + spinlock_t login_worker_lock; /* Used for scheduling TX and RX connection kthreads */ cpumask_var_t conn_cpumask; + cpumask_var_t allowed_cpumask; unsigned int conn_rx_reset_cpumask:1; unsigned int conn_tx_reset_cpumask:1; - /* list_head of struct iscsi_cmd for this connection */ + /* list_head of struct iscsit_cmd for this connection */ struct list_head conn_cmd_list; struct list_head immed_queue_list; struct list_head response_queue_list; @@ -597,7 +596,8 @@ struct iscsi_conn { struct iscsi_portal_group *tpg; struct iscsi_tpg_np *tpg_np; /* Pointer to parent session */ - struct iscsi_session *sess; + struct iscsit_session *sess; + struct target_cmd_counter *cmd_cnt; int bitmap_id; int rx_thread_active; struct task_struct *rx_thread; @@ -617,11 +617,11 @@ struct iscsi_conn_recovery { struct list_head conn_recovery_cmd_list; spinlock_t conn_recovery_cmd_lock; struct timer_list time2retain_timer; - struct iscsi_session *sess; + struct iscsit_session *sess; struct list_head cr_list; } ____cacheline_aligned; -struct iscsi_session { +struct iscsit_session { u8 initiator_vendor; u8 isid[6]; enum iscsi_timer_flags_table time2retain_timer_flags; @@ -709,11 +709,12 @@ struct iscsi_login { char rsp[ISCSI_HDR_LEN]; char *req_buf; char *rsp_buf; - struct iscsi_conn *conn; + struct iscsit_conn *conn; struct iscsi_np *np; } ____cacheline_aligned; struct iscsi_node_attrib { + s32 authentication; u32 dataout_timeout; u32 dataout_timeout_retries; u32 default_erl; @@ -757,10 +758,15 @@ struct iscsi_node_acl { struct iscsi_node_stat_grps node_stat_grps; }; +static inline struct iscsi_node_acl * +to_iscsi_nacl(struct se_node_acl *se_nacl) +{ + return container_of(se_nacl, struct iscsi_node_acl, se_node_acl); +} + struct iscsi_tpg_attrib { u32 authentication; u32 login_timeout; - u32 netif_timeout; u32 generate_node_acls; u32 cache_dynamic_acls; u32 default_cmdsn_depth; @@ -782,7 +788,6 @@ struct iscsi_np { enum np_thread_state_table np_thread_state; bool enabled; atomic_t np_reset_count; - enum iscsi_timer_flags_table np_login_timer_flags; u32 np_exports; enum np_flags_table np_flags; spinlock_t np_thread_lock; @@ -790,7 +795,6 @@ struct iscsi_np { struct socket *np_socket; struct sockaddr_storage np_sockaddr; struct task_struct *np_thread; - struct timer_list np_login_timer; void *np_context; struct iscsit_transport *np_transport; struct list_head np_list; @@ -838,6 +842,12 @@ struct iscsi_portal_group { struct list_head tpg_list; } ____cacheline_aligned; +static inline struct iscsi_portal_group * +to_iscsi_tpg(struct se_portal_group *se_tpg) +{ + return container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg); +} + struct iscsi_wwn_stat_grps { struct config_group iscsi_stat_group; struct config_group iscsi_instance_group; @@ -878,12 +888,13 @@ struct iscsit_global { /* Thread Set bitmap pointer */ unsigned long *ts_bitmap; spinlock_t ts_bitmap_lock; + cpumask_var_t allowed_cpumask; /* Used for iSCSI discovery session authentication */ struct iscsi_node_acl discovery_acl; struct iscsi_portal_group *discovery_tpg; }; -static inline u32 session_get_next_ttt(struct iscsi_session *session) +static inline u32 session_get_next_ttt(struct iscsit_session *session) { u32 ttt; @@ -896,31 +907,10 @@ static inline u32 session_get_next_ttt(struct iscsi_session *session) return ttt; } -extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t); +extern struct iscsit_cmd *iscsit_find_cmd_from_itt(struct iscsit_conn *, itt_t); + +extern void iscsit_thread_check_cpumask(struct iscsit_conn *conn, + struct task_struct *p, + int mode); -static inline void iscsit_thread_check_cpumask( - struct iscsi_conn *conn, - struct task_struct *p, - int mode) -{ - /* - * mode == 1 signals iscsi_target_tx_thread() usage. - * mode == 0 signals iscsi_target_rx_thread() usage. - */ - if (mode == 1) { - if (!conn->conn_tx_reset_cpumask) - return; - conn->conn_tx_reset_cpumask = 0; - } else { - if (!conn->conn_rx_reset_cpumask) - return; - conn->conn_rx_reset_cpumask = 0; - } - /* - * Update the CPU mask for this single kthread so that - * both TX and RX kthreads are scheduled to run on the - * same CPU. - */ - set_cpus_allowed_ptr(p, conn->conn_cpumask); -} #endif /* ISCSI_TARGET_CORE_H */ diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index b8feba7ffebc..42cfe02ea909 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#include "iscsi_target_core.h" /* struct iscsi_cmd */ +#include "iscsi_target_core.h" /* struct iscsit_cmd */ struct sockaddr_storage; @@ -12,29 +12,29 @@ struct iscsit_transport { struct module *owner; struct list_head t_node; int (*iscsit_setup_np)(struct iscsi_np *, struct sockaddr_storage *); - int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); + int (*iscsit_accept_np)(struct iscsi_np *, struct iscsit_conn *); void (*iscsit_free_np)(struct iscsi_np *); - void (*iscsit_wait_conn)(struct iscsi_conn *); - void (*iscsit_free_conn)(struct iscsi_conn *); - int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); - int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); - int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); - int (*iscsit_response_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); - int (*iscsit_get_dataout)(struct iscsi_conn *, struct iscsi_cmd *, bool); - int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); - int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); - void (*iscsit_aborted_task)(struct iscsi_conn *, struct iscsi_cmd *); - int (*iscsit_xmit_pdu)(struct iscsi_conn *, struct iscsi_cmd *, + void (*iscsit_wait_conn)(struct iscsit_conn *); + void (*iscsit_free_conn)(struct iscsit_conn *); + int (*iscsit_get_login_rx)(struct iscsit_conn *, struct iscsi_login *); + int (*iscsit_put_login_tx)(struct iscsit_conn *, struct iscsi_login *, u32); + int (*iscsit_immediate_queue)(struct iscsit_conn *, struct iscsit_cmd *, int); + int (*iscsit_response_queue)(struct iscsit_conn *, struct iscsit_cmd *, int); + int (*iscsit_get_dataout)(struct iscsit_conn *, struct iscsit_cmd *, bool); + int (*iscsit_queue_data_in)(struct iscsit_conn *, struct iscsit_cmd *); + int (*iscsit_queue_status)(struct iscsit_conn *, struct iscsit_cmd *); + void (*iscsit_aborted_task)(struct iscsit_conn *, struct iscsit_cmd *); + int (*iscsit_xmit_pdu)(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_datain_req *, const void *, u32); - void (*iscsit_unmap_cmd)(struct iscsi_conn *, struct iscsi_cmd *); - void (*iscsit_get_rx_pdu)(struct iscsi_conn *); - int (*iscsit_validate_params)(struct iscsi_conn *); - void (*iscsit_get_r2t_ttt)(struct iscsi_conn *, struct iscsi_cmd *, + void (*iscsit_unmap_cmd)(struct iscsit_conn *, struct iscsit_cmd *); + void (*iscsit_get_rx_pdu)(struct iscsit_conn *); + int (*iscsit_validate_params)(struct iscsit_conn *); + void (*iscsit_get_r2t_ttt)(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_r2t *); - enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); + enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsit_conn *); }; -static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd) +static inline void *iscsit_priv_cmd(struct iscsit_cmd *cmd) { return (void *)(cmd + 1); } @@ -51,100 +51,100 @@ extern void iscsit_put_transport(struct iscsit_transport *); /* * From iscsi_target.c */ -extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_setup_scsi_cmd(struct iscsit_conn *, struct iscsit_cmd *, unsigned char *); -extern void iscsit_set_unsolicited_dataout(struct iscsi_cmd *); -extern int iscsit_process_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern void iscsit_set_unsolicited_dataout(struct iscsit_cmd *); +extern int iscsit_process_scsi_cmd(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_scsi_req *); extern int -__iscsit_check_dataout_hdr(struct iscsi_conn *, void *, - struct iscsi_cmd *, u32, bool *); +__iscsit_check_dataout_hdr(struct iscsit_conn *, void *, + struct iscsit_cmd *, u32, bool *); extern int -iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf, - struct iscsi_cmd **out_cmd); -extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *, +iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf, + struct iscsit_cmd **out_cmd); +extern int iscsit_check_dataout_payload(struct iscsit_cmd *, struct iscsi_data *, bool); -extern int iscsit_setup_nop_out(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_setup_nop_out(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_nopout *); -extern int iscsit_process_nop_out(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_process_nop_out(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_nopout *); -extern int iscsit_handle_logout_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_handle_logout_cmd(struct iscsit_conn *, struct iscsit_cmd *, unsigned char *); -extern int iscsit_handle_task_mgt_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_handle_task_mgt_cmd(struct iscsit_conn *, struct iscsit_cmd *, unsigned char *); -extern int iscsit_setup_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_setup_text_cmd(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_text *); -extern int iscsit_process_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_process_text_cmd(struct iscsit_conn *, struct iscsit_cmd *, struct iscsi_text *); -extern void iscsit_build_rsp_pdu(struct iscsi_cmd *, struct iscsi_conn *, +extern void iscsit_build_rsp_pdu(struct iscsit_cmd *, struct iscsit_conn *, bool, struct iscsi_scsi_rsp *); -extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *, +extern void iscsit_build_nopin_rsp(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_nopin *, bool); -extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, +extern void iscsit_build_task_mgt_rsp(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_tm_rsp *); -extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *, +extern int iscsit_build_text_rsp(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_text_rsp *, enum iscsit_transport_type); -extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, +extern void iscsit_build_reject(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_reject *); -extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, +extern int iscsit_build_logout_rsp(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_logout_rsp *); -extern int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *); -extern int iscsit_queue_rsp(struct iscsi_conn *, struct iscsi_cmd *); -extern void iscsit_aborted_task(struct iscsi_conn *, struct iscsi_cmd *); -extern int iscsit_add_reject(struct iscsi_conn *, u8, unsigned char *); -extern int iscsit_reject_cmd(struct iscsi_cmd *, u8, unsigned char *); -extern int iscsit_handle_snack(struct iscsi_conn *, unsigned char *); -extern void iscsit_build_datain_pdu(struct iscsi_cmd *, struct iscsi_conn *, +extern int iscsit_logout_post_handler(struct iscsit_cmd *, struct iscsit_conn *); +extern int iscsit_queue_rsp(struct iscsit_conn *, struct iscsit_cmd *); +extern void iscsit_aborted_task(struct iscsit_conn *, struct iscsit_cmd *); +extern int iscsit_add_reject(struct iscsit_conn *, u8, unsigned char *); +extern int iscsit_reject_cmd(struct iscsit_cmd *, u8, unsigned char *); +extern int iscsit_handle_snack(struct iscsit_conn *, unsigned char *); +extern void iscsit_build_datain_pdu(struct iscsit_cmd *, struct iscsit_conn *, struct iscsi_datain *, struct iscsi_data_rsp *, bool); -extern int iscsit_build_r2ts_for_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern int iscsit_build_r2ts_for_cmd(struct iscsit_conn *, struct iscsit_cmd *, bool); -extern int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, int); -extern int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int); +extern int iscsit_immediate_queue(struct iscsit_conn *, struct iscsit_cmd *, int); +extern int iscsit_response_queue(struct iscsit_conn *, struct iscsit_cmd *, int); /* * From iscsi_target_device.c */ -extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); +extern void iscsit_increment_maxcmdsn(struct iscsit_cmd *, struct iscsit_session *); /* * From iscsi_target_erl0.c */ -extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); +extern void iscsit_cause_connection_reinstatement(struct iscsit_conn *, int); /* * From iscsi_target_erl1.c */ -extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); +extern void iscsit_stop_dataout_timer(struct iscsit_cmd *); /* * From iscsi_target_tmr.c */ -extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *); +extern int iscsit_tmr_post_handler(struct iscsit_cmd *, struct iscsit_conn *); /* * From iscsi_target_util.c */ -extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, int); -extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, +extern struct iscsit_cmd *iscsit_allocate_cmd(struct iscsit_conn *, int); +extern int iscsit_sequence_cmd(struct iscsit_conn *, struct iscsit_cmd *, unsigned char *, __be32); -extern void iscsit_release_cmd(struct iscsi_cmd *); -extern void iscsit_free_cmd(struct iscsi_cmd *, bool); -extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, - struct iscsi_conn *, u8); -extern struct iscsi_cmd * -iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *conn, +extern void iscsit_release_cmd(struct iscsit_cmd *); +extern void iscsit_free_cmd(struct iscsit_cmd *, bool); +extern void iscsit_add_cmd_to_immediate_queue(struct iscsit_cmd *, + struct iscsit_conn *, u8); +extern struct iscsit_cmd * +iscsit_find_cmd_from_itt_or_dump(struct iscsit_conn *conn, itt_t init_task_tag, u32 length); /* * From iscsi_target_nego.c */ -extern int iscsi_target_check_login_request(struct iscsi_conn *, +extern int iscsi_target_check_login_request(struct iscsit_conn *, struct iscsi_login *); /* * From iscsi_target_login.c */ extern __printf(2, 3) int iscsi_change_param_sprintf( - struct iscsi_conn *, const char *, ...); + struct iscsit_conn *, const char *, ...); /* * From iscsi_target_parameters.c diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 6336780d83a7..4063a701081b 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -3,7 +3,7 @@ #define TARGET_CORE_BACKEND_H #include <linux/types.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include <target/target_core_base.h> #define TRANSPORT_FLAG_PASSTHROUGH 0x1 @@ -14,7 +14,7 @@ #define TRANSPORT_FLAG_PASSTHROUGH_ALUA 0x2 #define TRANSPORT_FLAG_PASSTHROUGH_PGR 0x4 -struct request_queue; +struct block_device; struct scatterlist; struct target_backend_ops { @@ -34,7 +34,10 @@ struct target_backend_ops { int (*configure_device)(struct se_device *); void (*destroy_device)(struct se_device *); void (*free_device)(struct se_device *device); + struct se_dev_plug *(*plug_device)(struct se_device *se_dev); + void (*unplug_device)(struct se_dev_plug *se_plug); + bool (*configure_unmap)(struct se_device *se_dev); ssize_t (*set_configfs_dev_params)(struct se_device *, const char *, ssize_t); ssize_t (*show_configfs_dev_params)(struct se_device *, char *); @@ -59,19 +62,25 @@ struct target_backend_ops { struct configfs_attribute **tb_dev_action_attrs; }; -struct sbc_ops { +struct exec_cmd_ops { sense_reason_t (*execute_rw)(struct se_cmd *cmd, struct scatterlist *, u32, enum dma_data_direction); sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd); sense_reason_t (*execute_write_same)(struct se_cmd *cmd); sense_reason_t (*execute_unmap)(struct se_cmd *cmd, sector_t lba, sector_t nolb); + sense_reason_t (*execute_pr_out)(struct se_cmd *cmd, u8 sa, u64 key, + u64 sa_key, u8 type, bool aptpl); + sense_reason_t (*execute_pr_in)(struct se_cmd *cmd, u8 sa, + unsigned char *param_data); }; int transport_backend_register(const struct target_backend_ops *); void target_backend_unregister(const struct target_backend_ops *); void target_complete_cmd(struct se_cmd *, u8); +void target_set_cmd_data_length(struct se_cmd *, int); +void target_complete_cmd_with_sense(struct se_cmd *, u8, sense_reason_t); void target_complete_cmd_with_length(struct se_cmd *, u8, int); void transport_copy_sense_to_cmd(struct se_cmd *, unsigned char *); @@ -81,7 +90,7 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); sense_reason_t spc_emulate_inquiry_std(struct se_cmd *, unsigned char *); sense_reason_t spc_emulate_evpd_83(struct se_cmd *, unsigned char *); -sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops); +sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct exec_cmd_ops *ops); u32 sbc_get_device_rev(struct se_device *dev); u32 sbc_get_device_type(struct se_device *dev); sector_t sbc_get_write_same_sectors(struct se_cmd *cmd); @@ -113,7 +122,7 @@ sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd, bool target_sense_desc_format(struct se_device *dev); sector_t target_to_linux_sector(struct se_device *dev, sector_t lb); bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib, - struct request_queue *q); + struct block_device *bdev); static inline bool target_dev_configured(struct se_device *se_dev) { diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 549947d407cf..c4d9116904aa 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -91,6 +91,8 @@ #define DA_EMULATE_ALUA 0 /* Emulate SCSI2 RESERVE/RELEASE and Persistent Reservations by default */ #define DA_EMULATE_PR 1 +/* Emulation for REPORT SUPPORTED OPERATION CODES */ +#define DA_EMULATE_RSOC 1 /* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */ #define DA_ENFORCE_PR_ISIDS 1 /* Force SPC-3 PR Activate Persistence across Target Power Loss */ @@ -106,6 +108,15 @@ #define SE_MODE_PAGE_BUF 512 #define SE_SENSE_BUF 96 +enum target_submit_type { + /* Use the fabric driver's default submission type */ + TARGET_FABRIC_DEFAULT_SUBMIT, + /* Submit from the calling context */ + TARGET_DIRECT_SUBMIT, + /* Defer submission to the LIO workqueue */ + TARGET_QUEUE_SUBMIT, +}; + /* struct se_hba->hba_flags */ enum hba_flags_table { HBA_FLAGS_INTERNAL_USE = 0x01, @@ -127,25 +138,26 @@ enum transport_state_table { /* Used for struct se_cmd->se_cmd_flags */ enum se_cmd_flags_table { - SCF_SUPPORTED_SAM_OPCODE = 0x00000001, - SCF_TRANSPORT_TASK_SENSE = 0x00000002, - SCF_EMULATED_TASK_SENSE = 0x00000004, - SCF_SCSI_DATA_CDB = 0x00000008, - SCF_SCSI_TMR_CDB = 0x00000010, - SCF_FUA = 0x00000080, - SCF_SE_LUN_CMD = 0x00000100, - SCF_BIDI = 0x00000400, - SCF_SENT_CHECK_CONDITION = 0x00000800, - SCF_OVERFLOW_BIT = 0x00001000, - SCF_UNDERFLOW_BIT = 0x00002000, - SCF_ALUA_NON_OPTIMIZED = 0x00008000, - SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000, - SCF_COMPARE_AND_WRITE = 0x00080000, - SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = 0x00200000, - SCF_ACK_KREF = 0x00400000, - SCF_USE_CPUID = 0x00800000, - SCF_TASK_ATTR_SET = 0x01000000, - SCF_TREAT_READ_AS_NORMAL = 0x02000000, + SCF_SUPPORTED_SAM_OPCODE = (1 << 0), + SCF_TRANSPORT_TASK_SENSE = (1 << 1), + SCF_EMULATED_TASK_SENSE = (1 << 2), + SCF_SCSI_DATA_CDB = (1 << 3), + SCF_SCSI_TMR_CDB = (1 << 4), + SCF_FUA = (1 << 5), + SCF_SE_LUN_CMD = (1 << 6), + SCF_BIDI = (1 << 7), + SCF_SENT_CHECK_CONDITION = (1 << 8), + SCF_OVERFLOW_BIT = (1 << 9), + SCF_UNDERFLOW_BIT = (1 << 10), + SCF_ALUA_NON_OPTIMIZED = (1 << 11), + SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = (1 << 12), + SCF_COMPARE_AND_WRITE = (1 << 13), + SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = (1 << 14), + SCF_ACK_KREF = (1 << 15), + SCF_USE_CPUID = (1 << 16), + SCF_TASK_ATTR_SET = (1 << 17), + SCF_TREAT_READ_AS_NORMAL = (1 << 18), + SCF_TASK_ORDERED_SYNC = (1 << 19), }; /* @@ -171,7 +183,7 @@ enum tcm_sense_reason_table { TCM_WRITE_PROTECTED = R(0x0c), TCM_CHECK_CONDITION_ABORT_CMD = R(0x0d), TCM_CHECK_CONDITION_UNIT_ATTENTION = R(0x0e), - TCM_CHECK_CONDITION_NOT_READY = R(0x0f), + TCM_RESERVATION_CONFLICT = R(0x10), TCM_ADDRESS_OUT_OF_RANGE = R(0x11), TCM_OUT_OF_RESOURCES = R(0x12), @@ -187,6 +199,11 @@ enum tcm_sense_reason_table { TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE = R(0x1c), TCM_INSUFFICIENT_REGISTRATION_RESOURCES = R(0x1d), TCM_LUN_BUSY = R(0x1e), + TCM_INVALID_FIELD_IN_COMMAND_IU = R(0x1f), + TCM_ALUA_TG_PT_STANDBY = R(0x20), + TCM_ALUA_TG_PT_UNAVAILABLE = R(0x21), + TCM_ALUA_STATE_TRANSITION = R(0x22), + TCM_ALUA_OFFLINE = R(0x23), #undef R }; @@ -195,7 +212,6 @@ enum target_sc_flags_table { TARGET_SCF_ACK_KREF = 0x02, TARGET_SCF_UNKNOWN_SIZE = 0x04, TARGET_SCF_USE_CPUID = 0x08, - TARGET_SCF_LOOKUP_LUN_FROM_TAG = 0x10, }; /* fabric independent task management function values */ @@ -326,6 +342,7 @@ struct t10_wwn { char model[INQUIRY_MODEL_LEN + 1]; char revision[INQUIRY_REVISION_LEN + 1]; char unit_serial[INQUIRY_VPD_SERIAL_LEN]; + u32 company_id; spinlock_t t10_vpd_lock; struct se_device *t10_dev; struct config_group t10_wwn_group; @@ -452,10 +469,10 @@ enum target_core_dif_check { #define TCM_ACA_TAG 0x24 struct se_cmd { + /* Used for fail with specific sense codes */ + sense_reason_t sense_reason; /* SAM response code being sent to initiator */ u8 scsi_status; - u8 scsi_asc; - u8 scsi_ascq; u16 scsi_sense_length; unsigned unknown_data_length:1; bool state_active:1; @@ -487,8 +504,9 @@ struct se_cmd { struct se_lun *se_lun; /* Only used for internal passthrough and legacy TCM fabric modules */ struct se_session *se_sess; + struct target_cmd_counter *cmd_cnt; struct se_tmr_req *se_tmr_req; - struct list_head se_cmd_list; + struct llist_node se_cmd_list; struct completion *free_compl; struct completion *abrt_compl; const struct target_core_fabric_ops *se_tfo; @@ -540,7 +558,11 @@ struct se_cmd { struct scatterlist *t_prot_sg; unsigned int t_prot_nents; sense_reason_t pi_err; - sector_t bad_sector; + u64 sense_info; + /* + * CPU LIO will execute the cmd on. Defaults to the CPU the cmd is + * initialized on. Drivers can override. + */ int cpuid; }; @@ -608,22 +630,26 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item) acl_fabric_stat_group); } +struct target_cmd_counter { + struct percpu_ref refcnt; + wait_queue_head_t refcnt_wq; + struct completion stop_done; + atomic_t stopped; +}; + struct se_session { - unsigned sess_tearing_down:1; u64 sess_bin_isid; enum target_prot_op sup_prot_ops; enum target_prot_type sess_prot_type; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; void *fabric_sess_ptr; - struct percpu_ref cmd_count; struct list_head sess_list; struct list_head sess_acl_list; - struct list_head sess_cmd_list; spinlock_t sess_cmd_lock; - wait_queue_head_t cmd_list_wq; void *sess_cmd_map; struct sbitmap_queue sess_tag_pool; + struct target_cmd_counter *cmd_cnt; }; struct se_device; @@ -644,21 +670,25 @@ struct se_lun_acl { struct se_ml_stat_grps ml_stat_grps; }; +struct se_dev_entry_io_stats { + u32 total_cmds; + u32 read_bytes; + u32 write_bytes; +}; + struct se_dev_entry { u64 mapped_lun; u64 pr_res_key; u64 creation_time; bool lun_access_ro; u32 attach_count; - atomic_long_t total_cmds; - atomic_long_t read_bytes; - atomic_long_t write_bytes; + struct se_dev_entry_io_stats __percpu *stats; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ struct kref pr_kref; struct completion pr_comp; - struct se_lun_acl __rcu *se_lun_acl; + struct se_lun_acl *se_lun_acl; spinlock_t ua_lock; - struct se_lun __rcu *se_lun; + struct se_lun *se_lun; #define DEF_PR_REG_ACTIVE 1 unsigned long deve_flags; struct list_head alua_port_list; @@ -681,6 +711,7 @@ struct se_dev_attrib { bool emulate_caw; bool emulate_3pc; bool emulate_pr; + bool emulate_rsoc; enum target_prot_type pi_prot_type; enum target_prot_type hw_pi_prot_type; bool pi_prot_verify; @@ -700,7 +731,7 @@ struct se_dev_attrib { u32 unmap_granularity; u32 unmap_granularity_alignment; u32 max_write_same_len; - u32 max_bytes_per_io; + u8 submit_type; struct se_device *da_dev; struct config_group da_group; }; @@ -724,8 +755,6 @@ struct se_lun { bool lun_access_ro; u32 lun_index; - /* RELATIVE TARGET PORT IDENTIFER */ - u16 lun_rtpi; atomic_t lun_acl_count; struct se_device __rcu *lun_se_dev; @@ -740,7 +769,7 @@ struct se_lun { /* ALUA target port group linkage */ struct list_head lun_tg_pt_gp_link; - struct t10_alua_tg_pt_gp *lun_tg_pt_gp; + struct t10_alua_tg_pt_gp __rcu *lun_tg_pt_gp; spinlock_t lun_tg_pt_gp_lock; struct se_portal_group *lun_tpg; @@ -761,9 +790,28 @@ struct se_dev_stat_grps { struct config_group scsi_lu_group; }; +struct se_cmd_queue { + struct llist_head cmd_list; + struct work_struct work; +}; + +struct se_dev_plug { + struct se_device *se_dev; +}; + +struct se_device_queue { + struct list_head state_list; + spinlock_t lock; + struct se_cmd_queue sq; +}; + +struct se_dev_io_stats { + u32 total_cmds; + u32 read_bytes; + u32 write_bytes; +}; + struct se_device { - /* RELATIVE TARGET PORT IDENTIFER Counter */ - u16 dev_rpti_counter; /* Used for SAM Task Attribute ordering */ u32 dev_cur_ordered_id; u32 dev_flags; @@ -784,16 +832,13 @@ struct se_device { atomic_long_t num_resets; atomic_long_t aborts_complete; atomic_long_t aborts_no_task; - atomic_long_t num_cmds; - atomic_long_t read_bytes; - atomic_long_t write_bytes; + struct se_dev_io_stats __percpu *stats; /* Active commands on this virtual SE device */ - atomic_t simple_cmds; - atomic_t dev_ordered_sync; + struct percpu_ref non_ordered; + bool ordered_sync_in_progress; atomic_t dev_qf_count; u32 export_count; spinlock_t delayed_cmd_lock; - spinlock_t execute_task_lock; spinlock_t dev_reservation_lock; unsigned int dev_reservation_flags; #define DRF_SPC2_RESERVATIONS 0x00000001 @@ -811,8 +856,8 @@ struct se_device { struct list_head dev_sep_list; struct list_head dev_tmr_list; struct work_struct qf_work_queue; + struct work_struct delayed_cmd_work; struct list_head delayed_cmd_list; - struct list_head state_list; struct list_head qf_cmd_list; /* Pointer to associated SE HBA */ struct se_hba *se_hba; @@ -839,6 +884,25 @@ struct se_device { /* For se_lun->lun_se_dev RCU read-side critical access */ u32 hba_index; struct rcu_head rcu_head; + int queue_cnt; + struct se_device_queue *queues; + struct mutex lun_reset_mutex; +}; + +struct target_opcode_descriptor { + u8 support:3; + u8 serv_action_valid:1; + u8 opcode; + u16 service_action; + u32 cdb_size; + u8 specific_timeout; + u16 nominal_timeout; + u16 recommended_timeout; + bool (*enabled)(const struct target_opcode_descriptor *descr, + struct se_cmd *cmd); + void (*update_usage_bits)(u8 *usage_bits, + struct se_device *dev); + u8 usage_bits[]; }; struct se_hba { @@ -876,6 +940,10 @@ struct se_portal_group { * Negative values can be used by fabric drivers for internal use TPGs. */ int proto_id; + bool enabled; + /* RELATIVE TARGET PORT IDENTIFIER */ + u16 tpg_rtpi; + bool rtpi_manual; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t tpg_pr_ref_count; /* Spinlock for adding/removing ACLed Nodes */ @@ -925,11 +993,20 @@ static inline struct se_portal_group *param_to_tpg(struct config_item *item) tpg_param_group); } +enum { + /* Use se_cmd's cpuid for completion */ + SE_COMPL_AFFINITY_CPUID = -1, + /* Complete on current CPU */ + SE_COMPL_AFFINITY_CURR_CPU = -2, +}; + struct se_wwn { struct target_fabric_configfs *wwn_tf; void *priv; struct config_group wwn_group; struct config_group fabric_stat_group; + struct config_group param_group; + int cmd_compl_affinity; }; static inline void atomic_inc_mb(atomic_t *v) diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 6adf4d71acf6..3378ff9ee271 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -89,6 +89,7 @@ struct target_core_fabric_ops { void (*add_wwn_groups)(struct se_wwn *); struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *, const char *); + int (*fabric_enable_tpg)(struct se_portal_group *se_tpg, bool enable); void (*fabric_drop_tpg)(struct se_portal_group *); int (*fabric_post_link)(struct se_portal_group *, struct se_lun *); @@ -112,11 +113,20 @@ struct target_core_fabric_ops { struct configfs_attribute **tfc_tpg_nacl_param_attrs; /* - * Set this member variable to true if the SCSI transport protocol + * Set this member variable if the SCSI transport protocol * (e.g. iSCSI) requires that the Data-Out buffer is transferred in * its entirety before a command is aborted. */ - bool write_pending_must_be_called; + unsigned int write_pending_must_be_called:1; + /* + * Set this if the driver supports submitting commands to the backend + * from target_submit/target_submit_cmd. + */ + unsigned int direct_submit_supp:1; + /* + * Set this to a target_submit_type value. + */ + u8 default_submit_type; }; int target_register_template(const struct target_core_fabric_ops *fo); @@ -132,7 +142,12 @@ struct se_session *target_setup_session(struct se_portal_group *, struct se_session *, void *)); void target_remove_session(struct se_session *); -int transport_init_session(struct se_session *se_sess); +void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt); +void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt); +struct target_cmd_counter *target_alloc_cmd_counter(void); +void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt); + +void transport_init_session(struct se_session *se_sess); struct se_session *transport_alloc_session(enum target_prot_op); int transport_alloc_session_tags(struct se_session *, unsigned int, unsigned int); @@ -148,23 +163,30 @@ void transport_deregister_session_configfs(struct se_session *); void transport_deregister_session(struct se_session *); -void transport_init_se_cmd(struct se_cmd *, - const struct target_core_fabric_ops *, - struct se_session *, u32, int, int, unsigned char *, u64); +void __target_init_cmd(struct se_cmd *cmd, + const struct target_core_fabric_ops *tfo, + struct se_session *sess, u32 data_length, int data_direction, + int task_attr, unsigned char *sense_buffer, u64 unpacked_lun, + struct target_cmd_counter *cmd_cnt); +int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + unsigned char *sense, u64 unpacked_lun, u32 data_length, + int task_attr, int data_dir, int flags); +int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, + struct scatterlist *sgl, u32 sgl_count, + struct scatterlist *sgl_bidi, u32 sgl_bidi_count, + struct scatterlist *sgl_prot, u32 sgl_prot_count, gfp_t gfp); +int target_submit(struct se_cmd *se_cmd); sense_reason_t transport_lookup_cmd_lun(struct se_cmd *); -sense_reason_t target_cmd_init_cdb(struct se_cmd *, unsigned char *); +sense_reason_t target_cmd_init_cdb(struct se_cmd *se_cmd, unsigned char *cdb, + gfp_t gfp); sense_reason_t target_cmd_parse_cdb(struct se_cmd *); -int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, - unsigned char *, unsigned char *, u64, u32, int, int, int, - struct scatterlist *, u32, struct scatterlist *, u32, - struct scatterlist *, u32); -int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, +void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u64, u32, int, int, int); + int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t, u64, int); -int transport_handle_cdb_direct(struct se_cmd *); sense_reason_t transport_generic_new_cmd(struct se_cmd *); void target_put_cmd_and_wait(struct se_cmd *cmd); @@ -178,12 +200,10 @@ int transport_send_check_condition_and_sense(struct se_cmd *, int target_send_busy(struct se_cmd *cmd); int target_get_sess_cmd(struct se_cmd *, bool); int target_put_sess_cmd(struct se_cmd *); -void target_sess_cmd_list_set_waiting(struct se_session *); +void target_stop_session(struct se_session *se_sess); void target_wait_for_sess_cmds(struct se_session *); void target_show_cmd(const char *pfx, struct se_cmd *cmd); -int core_alua_check_nonop_delay(struct se_cmd *); - int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); void core_tmr_release_req(struct se_tmr_req *); int transport_generic_handle_tmr(struct se_cmd *); |