summaryrefslogtreecommitdiffstats
path: root/kernel/include/target/target_core_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/include/target/target_core_base.h')
-rw-r--r--kernel/include/target/target_core_base.h294
1 files changed, 156 insertions, 138 deletions
diff --git a/kernel/include/target/target_core_base.h b/kernel/include/target/target_core_base.h
index 480e9f82d..689f4d207 100644
--- a/kernel/include/target/target_core_base.h
+++ b/kernel/include/target/target_core_base.h
@@ -6,34 +6,22 @@
#include <linux/dma-mapping.h>
#include <linux/blkdev.h>
#include <linux/percpu_ida.h>
-#include <scsi/scsi_cmnd.h>
+#include <linux/t10-pi.h>
#include <net/sock.h>
#include <net/tcp.h>
-#define TARGET_CORE_MOD_VERSION "v4.1.0"
-#define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION
+#define TARGET_CORE_VERSION "v5.0"
-/* Maximum Number of LUNs per Target Portal Group */
-/* Don't raise above 511 or REPORT_LUNS needs to handle >1 page */
-#define TRANSPORT_MAX_LUNS_PER_TPG 256
/*
- * By default we use 32-byte CDBs in TCM Core and subsystem plugin code.
- *
- * Note that both include/scsi/scsi_cmnd.h:MAX_COMMAND_SIZE and
- * include/linux/blkdev.h:BLOCK_MAX_CDB as of v2.6.36-rc4 still use
- * 16-byte CDBs by default and require an extra allocation for
- * 32-byte CDBs to because of legacy issues.
- *
- * Within TCM Core there are no such legacy limitiations, so we go ahead
- * use 32-byte CDBs by default and use include/scsi/scsi.h:scsi_command_size()
- * within all TCM Core and subsystem plugin code.
+ * Maximum size of a CDB that can be stored in se_cmd without allocating
+ * memory dynamically for the CDB.
*/
#define TCM_MAX_COMMAND_SIZE 32
/*
* From include/scsi/scsi_cmnd.h:SCSI_SENSE_BUFFERSIZE, currently
* defined 96, but the real limit is 252 (or 260 including the header)
*/
-#define TRANSPORT_SENSE_BUFFER SCSI_SENSE_BUFFERSIZE
+#define TRANSPORT_SENSE_BUFFER 96
/* Used by transport_send_check_condition_and_sense() */
#define SPC_SENSE_KEY_OFFSET 2
#define SPC_ADD_SENSE_LEN_OFFSET 7
@@ -79,12 +67,6 @@
#define DA_MAX_WRITE_SAME_LEN 0
/* Use a model alias based on the configfs backend device name */
#define DA_EMULATE_MODEL_ALIAS 0
-/* Emulation for Direct Page Out */
-#define DA_EMULATE_DPO 0
-/* Emulation for Forced Unit Access WRITEs */
-#define DA_EMULATE_FUA_WRITE 1
-/* Emulation for Forced Unit Access READs */
-#define DA_EMULATE_FUA_READ 0
/* Emulation for WriteCache and SYNCHRONIZE_CACHE */
#define DA_EMULATE_WRITE_CACHE 0
/* Emulation for UNIT ATTENTION Interlock Control */
@@ -125,18 +107,6 @@ enum hba_flags_table {
HBA_FLAGS_PSCSI_MODE = 0x02,
};
-/* struct se_lun->lun_status */
-enum transport_lun_status_table {
- TRANSPORT_LUN_STATUS_FREE = 0,
- TRANSPORT_LUN_STATUS_ACTIVE = 1,
-};
-
-/* struct se_portal_group->se_tpg_type */
-enum transport_tpg_type_table {
- TRANSPORT_TPG_TYPE_NORMAL = 0,
- TRANSPORT_TPG_TYPE_DISCOVERY = 1,
-};
-
/* Special transport agnostic struct se_cmd->t_states */
enum transport_state_table {
TRANSPORT_NO_STATE = 0,
@@ -167,14 +137,14 @@ enum se_cmd_flags_table {
SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000,
SCF_COMPARE_AND_WRITE = 0x00080000,
SCF_COMPARE_AND_WRITE_POST = 0x00100000,
+ SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = 0x00200000,
+ SCF_ACK_KREF = 0x00400000,
};
/* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
enum transport_lunflags_table {
- TRANSPORT_LUNFLAGS_NO_ACCESS = 0x00,
- TRANSPORT_LUNFLAGS_INITIATOR_ACCESS = 0x01,
- TRANSPORT_LUNFLAGS_READ_ONLY = 0x02,
- TRANSPORT_LUNFLAGS_READ_WRITE = 0x04,
+ TRANSPORT_LUNFLAGS_READ_ONLY = 0x01,
+ TRANSPORT_LUNFLAGS_READ_WRITE = 0x02,
};
/*
@@ -323,22 +293,13 @@ struct t10_alua_tg_pt_gp {
struct se_device *tg_pt_gp_dev;
struct config_group tg_pt_gp_group;
struct list_head tg_pt_gp_list;
- struct list_head tg_pt_gp_mem_list;
- struct se_port *tg_pt_gp_alua_port;
+ struct list_head tg_pt_gp_lun_list;
+ struct se_lun *tg_pt_gp_alua_lun;
struct se_node_acl *tg_pt_gp_alua_nacl;
struct delayed_work tg_pt_gp_transition_work;
struct completion *tg_pt_gp_transition_complete;
};
-struct t10_alua_tg_pt_gp_member {
- bool tg_pt_gp_assoc;
- atomic_t tg_pt_gp_mem_ref_cnt;
- spinlock_t tg_pt_gp_mem_lock;
- struct t10_alua_tg_pt_gp *tg_pt_gp;
- struct se_port *tg_pt;
- struct list_head tg_pt_gp_mem_list;
-};
-
struct t10_vpd {
unsigned char device_identifier[INQUIRY_VPD_DEVICE_IDENTIFIER_LEN];
int protocol_identifier_set;
@@ -383,15 +344,16 @@ struct t10_pr_registration {
int pr_res_scope;
/* Used for fabric initiator WWPNs using a ISID */
bool isid_present_at_reg;
- u32 pr_res_mapped_lun;
- u32 pr_aptpl_target_lun;
+ u64 pr_res_mapped_lun;
+ u64 pr_aptpl_target_lun;
+ u16 tg_pt_sep_rtpi;
u32 pr_res_generation;
u64 pr_reg_bin_isid;
u64 pr_res_key;
atomic_t pr_res_holders;
struct se_node_acl *pr_reg_nacl;
+ /* Used by ALL_TG_PT=1 registration with deve->pr_ref taken */
struct se_dev_entry *pr_reg_deve;
- struct se_lun *pr_reg_tg_pt_lun;
struct list_head pr_reg_list;
struct list_head pr_reg_abort_list;
struct list_head pr_reg_aptpl_list;
@@ -431,7 +393,7 @@ struct se_tmr_req {
u8 response;
int call_transport;
/* Reference to ITT that Task Mgmt should be performed */
- u32 ref_task_tag;
+ u64 ref_task_tag;
void *fabric_tmr_ptr;
struct se_cmd *task_cmd;
struct se_device *tmr_dev;
@@ -466,12 +428,6 @@ enum target_core_dif_check {
TARGET_DIF_CHECK_REFTAG = 0x1 << 2,
};
-struct se_dif_v1_tuple {
- __be16 guard_tag;
- __be16 app_tag;
- __be32 ref_tag;
-};
-
/* for sam_task_attr */
#define TCM_SIMPLE_TAG 0x20
#define TCM_HEAD_TAG 0x21
@@ -484,6 +440,10 @@ struct se_cmd {
u8 scsi_asc;
u8 scsi_ascq;
u16 scsi_sense_length;
+ unsigned cmd_wait_set:1;
+ unsigned unknown_data_length:1;
+ bool state_active:1;
+ u64 tag; /* SAM command identifier aka task tag */
/* Delay for ALUA Active/NonOptimized state access in milliseconds */
int alua_nonop_delay;
/* See include/linux/dma-mapping.h */
@@ -494,15 +454,12 @@ struct se_cmd {
unsigned int map_tag;
/* Transport protocol dependent state, see transport_state_table */
enum transport_state_table t_state;
- unsigned cmd_wait_set:1;
- unsigned unknown_data_length:1;
/* See se_cmd_flags_table */
u32 se_cmd_flags;
- u32 se_ordered_id;
/* Total size in bytes associated with command */
u32 data_length;
u32 residual_count;
- u32 orig_fe_lun;
+ u64 orig_fe_lun;
/* Persistent Reservation key */
u64 pr_res_key;
/* Used for sense data */
@@ -510,19 +467,16 @@ struct se_cmd {
struct list_head se_delayed_node;
struct list_head se_qf_node;
struct se_device *se_dev;
- struct se_dev_entry *se_deve;
struct se_lun *se_lun;
/* Only used for internal passthrough and legacy TCM fabric modules */
struct se_session *se_sess;
struct se_tmr_req *se_tmr_req;
struct list_head se_cmd_list;
struct completion cmd_wait_comp;
- struct kref cmd_kref;
const struct target_core_fabric_ops *se_tfo;
sense_reason_t (*execute_cmd)(struct se_cmd *);
- sense_reason_t (*execute_rw)(struct se_cmd *, struct scatterlist *,
- u32, enum dma_data_direction);
- sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool);
+ sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *);
+ void *protocol_data;
unsigned char *t_task_cdb;
unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE];
@@ -537,7 +491,10 @@ struct se_cmd {
#define CMD_T_DEV_ACTIVE (1 << 7)
#define CMD_T_REQUEST_STOP (1 << 8)
#define CMD_T_BUSY (1 << 9)
+#define CMD_T_TAS (1 << 10)
+#define CMD_T_FABRIC_STOP (1 << 11)
spinlock_t t_state_lock;
+ struct kref cmd_kref;
struct completion t_transport_stop_comp;
struct work_struct work;
@@ -550,8 +507,10 @@ struct se_cmd {
struct scatterlist *t_bidi_data_sg;
unsigned int t_bidi_data_nents;
+ /* Used for lun->lun_ref counting */
+ int lun_ref_active;
+
struct list_head state_list;
- bool state_active;
/* old task stop completion, consider merging with some of the above */
struct completion task_stop_comp;
@@ -559,26 +518,22 @@ struct se_cmd {
/* backend private data */
void *priv;
- /* Used for lun->lun_ref counting */
- int lun_ref_active;
-
/* DIF related members */
enum target_prot_op prot_op;
enum target_prot_type prot_type;
u8 prot_checks;
+ bool prot_pto;
u32 prot_length;
u32 reftag_seed;
struct scatterlist *t_prot_sg;
unsigned int t_prot_nents;
sense_reason_t pi_err;
sector_t bad_sector;
- bool prot_pto;
};
struct se_ua {
u8 ua_asc;
u8 ua_ascq;
- struct se_node_acl *ua_nacl;
struct list_head ua_nacl_list;
};
@@ -594,10 +549,10 @@ struct se_node_acl {
char acl_tag[MAX_ACL_TAG_SIZE];
/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
atomic_t acl_pr_ref_count;
- struct se_dev_entry **device_list;
+ struct hlist_head lun_entry_hlist;
struct se_session *nacl_sess;
struct se_portal_group *se_tpg;
- spinlock_t device_list_lock;
+ struct mutex lun_entry_mutex;
spinlock_t nacl_sess_lock;
struct config_group acl_group;
struct config_group acl_attrib_group;
@@ -611,6 +566,36 @@ struct se_node_acl {
struct kref acl_kref;
};
+static inline struct se_node_acl *acl_to_nacl(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_node_acl,
+ acl_group);
+}
+
+static inline struct se_node_acl *attrib_to_nacl(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_node_acl,
+ acl_attrib_group);
+}
+
+static inline struct se_node_acl *auth_to_nacl(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_node_acl,
+ acl_auth_group);
+}
+
+static inline struct se_node_acl *param_to_nacl(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_node_acl,
+ acl_param_group);
+}
+
+static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_node_acl,
+ acl_fabric_stat_group);
+}
+
struct se_session {
unsigned sess_tearing_down:1;
u64 sess_bin_isid;
@@ -640,34 +625,37 @@ struct se_ml_stat_grps {
};
struct se_lun_acl {
- char initiatorname[TRANSPORT_IQN_LEN];
- u32 mapped_lun;
+ u64 mapped_lun;
struct se_node_acl *se_lun_nacl;
struct se_lun *se_lun;
- struct list_head lacl_list;
struct config_group se_lun_group;
struct se_ml_stat_grps ml_stat_grps;
};
struct se_dev_entry {
- bool def_pr_registered;
/* See transport_lunflags_table */
- u32 lun_flags;
- u32 mapped_lun;
- u32 total_cmds;
+ u64 mapped_lun;
u64 pr_res_key;
u64 creation_time;
+ u32 lun_flags;
u32 attach_count;
- u64 read_bytes;
- u64 write_bytes;
+ atomic_long_t total_cmds;
+ atomic_long_t read_bytes;
+ atomic_long_t write_bytes;
atomic_t ua_count;
/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
- atomic_t pr_ref_count;
- struct se_lun_acl *se_lun_acl;
+ struct kref pr_kref;
+ struct completion pr_comp;
+ struct se_lun_acl __rcu *se_lun_acl;
spinlock_t ua_lock;
- struct se_lun *se_lun;
+ struct se_lun __rcu *se_lun;
+#define DEF_PR_REG_ACTIVE 1
+ unsigned long deve_flags;
struct list_head alua_port_list;
+ struct list_head lun_link;
struct list_head ua_list;
+ struct hlist_node link;
+ struct rcu_head rcu_head;
};
struct se_dev_attrib {
@@ -712,25 +700,47 @@ struct se_port_stat_grps {
struct config_group scsi_transport_group;
};
+struct scsi_port_stats {
+ atomic_long_t cmd_pdus;
+ atomic_long_t tx_data_octets;
+ atomic_long_t rx_data_octets;
+};
+
struct se_lun {
+ u64 unpacked_lun;
#define SE_LUN_LINK_MAGIC 0xffff7771
u32 lun_link_magic;
- /* See transport_lun_status_table */
- enum transport_lun_status_table lun_status;
u32 lun_access;
- u32 lun_flags;
- u32 unpacked_lun;
+ u32 lun_index;
+
+ /* RELATIVE TARGET PORT IDENTIFER */
+ u16 lun_rtpi;
atomic_t lun_acl_count;
- spinlock_t lun_acl_lock;
- spinlock_t lun_sep_lock;
- struct completion lun_shutdown_comp;
- struct list_head lun_acl_list;
- struct se_device *lun_se_dev;
- struct se_port *lun_sep;
+ struct se_device __rcu *lun_se_dev;
+
+ struct list_head lun_deve_list;
+ spinlock_t lun_deve_lock;
+
+ /* ALUA state */
+ int lun_tg_pt_secondary_stat;
+ int lun_tg_pt_secondary_write_md;
+ atomic_t lun_tg_pt_secondary_offline;
+ struct mutex lun_tg_pt_md_mutex;
+
+ /* ALUA target port group linkage */
+ struct list_head lun_tg_pt_gp_link;
+ struct t10_alua_tg_pt_gp *lun_tg_pt_gp;
+ spinlock_t lun_tg_pt_gp_lock;
+
+ struct se_portal_group *lun_tpg;
+ struct scsi_port_stats lun_stats;
struct config_group lun_group;
struct se_port_stat_grps port_stat_grps;
struct completion lun_ref_comp;
struct percpu_ref lun_ref;
+ struct list_head lun_dev_link;
+ struct hlist_node link;
+ struct rcu_head rcu_head;
};
struct se_dev_stat_grps {
@@ -753,7 +763,7 @@ struct se_device {
#define DF_EMULATED_VPD_UNIT_SERIAL 0x00000004
#define DF_USING_UDEV_PATH 0x00000008
#define DF_USING_ALIAS 0x00000010
- u32 dev_port_count;
+#define DF_READ_ONLY 0x00000020
/* Physical device queue depth */
u32 queue_depth;
/* Used for SPC-2 reservations enforce of ISIDs */
@@ -767,10 +777,9 @@ struct se_device {
atomic_long_t write_bytes;
/* Active commands on this virtual SE device */
atomic_t simple_cmds;
- atomic_t dev_ordered_id;
atomic_t dev_ordered_sync;
atomic_t dev_qf_count;
- int export_count;
+ u32 export_count;
spinlock_t delayed_cmd_lock;
spinlock_t execute_task_lock;
spinlock_t dev_reservation_lock;
@@ -812,12 +821,15 @@ struct se_device {
#define SE_UDEV_PATH_LEN 512 /* must be less than PAGE_SIZE */
unsigned char udev_path[SE_UDEV_PATH_LEN];
/* Pointer to template of function pointers for transport */
- struct se_subsystem_api *transport;
+ const struct target_backend_ops *transport;
/* Linked list for struct se_hba struct se_device list */
struct list_head dev_list;
struct se_lun xcopy_lun;
/* Protection Information */
int prot_length;
+ /* For se_lun->lun_se_dev RCU read-side critical access */
+ u32 hba_index;
+ struct rcu_head rcu_head;
};
struct se_hba {
@@ -834,33 +846,7 @@ struct se_hba {
spinlock_t device_lock;
struct config_group hba_group;
struct mutex hba_access_mutex;
- struct se_subsystem_api *transport;
-};
-
-struct scsi_port_stats {
- u64 cmd_pdus;
- u64 tx_data_octets;
- u64 rx_data_octets;
-};
-
-struct se_port {
- /* RELATIVE TARGET PORT IDENTIFER */
- u16 sep_rtpi;
- int sep_tg_pt_secondary_stat;
- int sep_tg_pt_secondary_write_md;
- u32 sep_index;
- struct scsi_port_stats sep_stats;
- /* Used for ALUA Target Port Groups membership */
- atomic_t sep_tg_pt_secondary_offline;
- /* Used for PR ALL_TG_PT=1 */
- atomic_t sep_tg_pt_ref_cnt;
- spinlock_t sep_alua_lock;
- struct mutex sep_tg_pt_md_mutex;
- struct t10_alua_tg_pt_gp_member *sep_alua_tg_pt_gp_mem;
- struct se_lun *sep_lun;
- struct se_portal_group *sep_tpg;
- struct list_head sep_alua_list;
- struct list_head sep_list;
+ struct target_backend *backend;
};
struct se_tpg_np {
@@ -868,25 +854,33 @@ struct se_tpg_np {
struct config_group tpg_np_group;
};
+static inline struct se_tpg_np *to_tpg_np(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_tpg_np,
+ tpg_np_group);
+}
+
struct se_portal_group {
- /* Type of target portal group, see transport_tpg_type_table */
- enum transport_tpg_type_table se_tpg_type;
+ /*
+ * PROTOCOL IDENTIFIER value per SPC4, 7.5.1.
+ *
+ * Negative values can be used by fabric drivers for internal use TPGs.
+ */
+ int proto_id;
/* Number of ACLed Initiator Nodes for this TPG */
u32 num_node_acls;
/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
atomic_t tpg_pr_ref_count;
/* Spinlock for adding/removing ACLed Nodes */
- spinlock_t acl_node_lock;
+ struct mutex acl_node_mutex;
/* Spinlock for adding/removing sessions */
spinlock_t session_lock;
- spinlock_t tpg_lun_lock;
- /* Pointer to $FABRIC_MOD portal group */
- void *se_tpg_fabric_ptr;
+ struct mutex tpg_lun_mutex;
struct list_head se_tpg_node;
/* linked list for initiator ACL list */
struct list_head acl_node_list;
- struct se_lun **tpg_lun_list;
- struct se_lun tpg_virt_lun0;
+ struct hlist_head tpg_lun_hlist;
+ struct se_lun *tpg_virt_lun0;
/* List of TCM sessions associated wth this TPG */
struct list_head tpg_sess_list;
/* Pointer to $FABRIC_MOD dependent code */
@@ -902,6 +896,30 @@ struct se_portal_group {
struct config_group tpg_param_group;
};
+static inline struct se_portal_group *to_tpg(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_portal_group,
+ tpg_group);
+}
+
+static inline struct se_portal_group *attrib_to_tpg(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_portal_group,
+ tpg_attrib_group);
+}
+
+static inline struct se_portal_group *auth_to_tpg(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_portal_group,
+ tpg_auth_group);
+}
+
+static inline struct se_portal_group *param_to_tpg(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct se_portal_group,
+ tpg_param_group);
+}
+
struct se_wwn {
struct target_fabric_configfs *wwn_tf;
struct config_group wwn_group;