#include <linux/net.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/in.h>
#include <linux/cdrom.h>
#include <linux/module.h>
#include <linux/ratelimit.h>
#include <linux/vmalloc.h>
#include <asm/unaligned.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <scsi/scsi_proto.h>
#include <scsi/scsi_common.h>
#include <target/target_core_base.h>
#include <target/target_core_backend.h>
#include <target/target_core_fabric.h>
#include "target_core_internal.h"
#include "target_core_alua.h"
#include "target_core_pr.h"
#include "target_core_ua.h"
#define CREATE_TRACE_POINTS
#include <trace/events/target.h>
static struct workqueue_struct *target_completion_wq;
static struct workqueue_struct *target_submission_wq;
static struct kmem_cache *se_sess_cache;
struct kmem_cache *se_ua_cache;
struct kmem_cache *t10_pr_reg_cache;
struct kmem_cache *t10_alua_lu_gp_cache;
struct kmem_cache *t10_alua_lu_gp_mem_cache;
struct kmem_cache *t10_alua_tg_pt_gp_cache;
struct kmem_cache *t10_alua_lba_map_cache;
struct kmem_cache *t10_alua_lba_map_mem_cache;
static void transport_complete_task_attr(struct se_cmd *cmd);
static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason);
static void transport_handle_queue_full(struct se_cmd *cmd,
struct se_device *dev, int err, bool write_pending);
static void target_complete_ok_work(struct work_struct *work);
int init_se_kmem_caches(void)
{ … }
void release_se_kmem_caches(void)
{ … }
static DEFINE_SPINLOCK(scsi_mib_index_lock);
static u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX];
u32 scsi_get_new_index(scsi_index_t type)
{ … }
void transport_subsystem_check_init(void)
{ … }
static void target_release_cmd_refcnt(struct percpu_ref *ref)
{ … }
struct target_cmd_counter *target_alloc_cmd_counter(void)
{ … }
EXPORT_SYMBOL_GPL(…);
void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt)
{ … }
EXPORT_SYMBOL_GPL(…);
void transport_init_session(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
{ … }
EXPORT_SYMBOL(…);
int transport_alloc_session_tags(struct se_session *se_sess,
unsigned int tag_num, unsigned int tag_size)
{ … }
EXPORT_SYMBOL(…);
static struct se_session *
transport_init_session_tags(unsigned int tag_num, unsigned int tag_size,
enum target_prot_op sup_prot_ops)
{ … }
void __transport_register_session(
struct se_portal_group *se_tpg,
struct se_node_acl *se_nacl,
struct se_session *se_sess,
void *fabric_sess_ptr)
{ … }
EXPORT_SYMBOL(…);
void transport_register_session(
struct se_portal_group *se_tpg,
struct se_node_acl *se_nacl,
struct se_session *se_sess,
void *fabric_sess_ptr)
{ … }
EXPORT_SYMBOL(…);
struct se_session *
target_setup_session(struct se_portal_group *tpg,
unsigned int tag_num, unsigned int tag_size,
enum target_prot_op prot_op,
const char *initiatorname, void *private,
int (*callback)(struct se_portal_group *,
struct se_session *, void *))
{ … }
EXPORT_SYMBOL(…);
ssize_t target_show_dynamic_sessions(struct se_portal_group *se_tpg, char *page)
{ … }
EXPORT_SYMBOL(…);
static void target_complete_nacl(struct kref *kref)
{ … }
void target_put_nacl(struct se_node_acl *nacl)
{ … }
EXPORT_SYMBOL(…);
void transport_deregister_session_configfs(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
void transport_free_session(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
static int target_release_res(struct se_device *dev, void *data)
{ … }
void transport_deregister_session(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
void target_remove_session(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
static void target_remove_from_state_list(struct se_cmd *cmd)
{ … }
static void target_remove_from_tmr_list(struct se_cmd *cmd)
{ … }
static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd)
{ … }
static void transport_lun_remove_cmd(struct se_cmd *cmd)
{ … }
static void target_complete_failure_work(struct work_struct *work)
{ … }
static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
{ … }
void transport_copy_sense_to_cmd(struct se_cmd *cmd, unsigned char *sense)
{ … }
EXPORT_SYMBOL(…);
static void target_handle_abort(struct se_cmd *cmd)
{ … }
static void target_abort_work(struct work_struct *work)
{ … }
static bool target_cmd_interrupted(struct se_cmd *cmd)
{ … }
void target_complete_cmd_with_sense(struct se_cmd *cmd, u8 scsi_status,
sense_reason_t sense_reason)
{ … }
EXPORT_SYMBOL(…);
void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
{ … }
EXPORT_SYMBOL(…);
void target_set_cmd_data_length(struct se_cmd *cmd, int length)
{ … }
EXPORT_SYMBOL(…);
void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
{ … }
EXPORT_SYMBOL(…);
static void target_add_to_state_list(struct se_cmd *cmd)
{ … }
static void transport_write_pending_qf(struct se_cmd *cmd);
static void transport_complete_qf(struct se_cmd *cmd);
void target_qf_do_work(struct work_struct *work)
{ … }
unsigned char *transport_dump_cmd_direction(struct se_cmd *cmd)
{ … }
void transport_dump_dev_state(
struct se_device *dev,
char *b,
int *bl)
{ … }
void transport_dump_vpd_proto_id(
struct t10_vpd *vpd,
unsigned char *p_buf,
int p_buf_len)
{ … }
void
transport_set_vpd_proto_id(struct t10_vpd *vpd, unsigned char *page_83)
{ … }
EXPORT_SYMBOL(…);
int transport_dump_vpd_assoc(
struct t10_vpd *vpd,
unsigned char *p_buf,
int p_buf_len)
{ … }
int transport_set_vpd_assoc(struct t10_vpd *vpd, unsigned char *page_83)
{ … }
EXPORT_SYMBOL(…);
int transport_dump_vpd_ident_type(
struct t10_vpd *vpd,
unsigned char *p_buf,
int p_buf_len)
{ … }
int transport_set_vpd_ident_type(struct t10_vpd *vpd, unsigned char *page_83)
{ … }
EXPORT_SYMBOL(…);
int transport_dump_vpd_ident(
struct t10_vpd *vpd,
unsigned char *p_buf,
int p_buf_len)
{ … }
int
transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
{ … }
EXPORT_SYMBOL(…);
static sense_reason_t
target_check_max_data_sg_nents(struct se_cmd *cmd, struct se_device *dev,
unsigned int size)
{ … }
sense_reason_t
target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
{ … }
void __target_init_cmd(struct se_cmd *cmd,
const struct target_core_fabric_ops *tfo,
struct se_session *se_sess, u32 data_length,
int data_direction, int task_attr,
unsigned char *sense_buffer, u64 unpacked_lun,
struct target_cmd_counter *cmd_cnt)
{ … }
EXPORT_SYMBOL(…);
static sense_reason_t
transport_check_alloc_task_attr(struct se_cmd *cmd)
{ … }
sense_reason_t
target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb, gfp_t gfp)
{ … }
EXPORT_SYMBOL(…);
sense_reason_t
target_cmd_parse_cdb(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
static int __target_submit(struct se_cmd *cmd)
{ … }
sense_reason_t
transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count)
{ … }
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)
{ … }
EXPORT_SYMBOL_GPL(…);
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)
{ … }
EXPORT_SYMBOL_GPL(…);
void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
unsigned char *cdb, unsigned char *sense, u64 unpacked_lun,
u32 data_length, int task_attr, int data_dir, int flags)
{ … }
EXPORT_SYMBOL(…);
static struct se_dev_plug *target_plug_device(struct se_device *se_dev)
{ … }
static void target_unplug_device(struct se_dev_plug *se_plug)
{ … }
void target_queued_submit_work(struct work_struct *work)
{ … }
static void target_queue_submission(struct se_cmd *se_cmd)
{ … }
int target_submit(struct se_cmd *se_cmd)
{ … }
EXPORT_SYMBOL_GPL(…);
static void target_complete_tmr_failure(struct work_struct *work)
{ … }
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 gfp, u64 tag, int flags)
{ … }
EXPORT_SYMBOL(…);
void transport_generic_request_failure(struct se_cmd *cmd,
sense_reason_t sense_reason)
{ … }
EXPORT_SYMBOL(…);
void __target_execute_cmd(struct se_cmd *cmd, bool do_checks)
{ … }
static int target_write_prot_action(struct se_cmd *cmd)
{ … }
static bool target_handle_task_attr(struct se_cmd *cmd)
{ … }
void target_execute_cmd(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
void target_do_delayed_work(struct work_struct *work)
{ … }
static void transport_complete_task_attr(struct se_cmd *cmd)
{ … }
static void transport_complete_qf(struct se_cmd *cmd)
{ … }
static void transport_handle_queue_full(struct se_cmd *cmd, struct se_device *dev,
int err, bool write_pending)
{ … }
static bool target_read_prot_action(struct se_cmd *cmd)
{ … }
static void target_complete_ok_work(struct work_struct *work)
{ … }
void target_free_sgl(struct scatterlist *sgl, int nents)
{ … }
EXPORT_SYMBOL(…);
static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
{ … }
static inline void transport_free_pages(struct se_cmd *cmd)
{ … }
void *transport_kmap_data_sg(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
void transport_kunmap_data_sg(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
int
target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents, u32 length,
bool zero_page, bool chainable)
{ … }
EXPORT_SYMBOL(…);
sense_reason_t
transport_generic_new_cmd(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
static void transport_write_pending_qf(struct se_cmd *cmd)
{ … }
static bool
__transport_wait_for_tasks(struct se_cmd *, bool, bool *, bool *,
unsigned long *flags);
static void target_wait_free_cmd(struct se_cmd *cmd, bool *aborted, bool *tas)
{ … }
void target_put_cmd_and_wait(struct se_cmd *cmd)
{ … }
int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
{ … }
EXPORT_SYMBOL(…);
int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
{ … }
EXPORT_SYMBOL(…);
static void target_free_cmd_mem(struct se_cmd *cmd)
{ … }
static void target_release_cmd_kref(struct kref *kref)
{ … }
int target_put_sess_cmd(struct se_cmd *se_cmd)
{ … }
EXPORT_SYMBOL(…);
static const char *data_dir_name(enum dma_data_direction d)
{ … }
static const char *cmd_state_name(enum transport_state_table t)
{ … }
static void target_append_str(char **str, const char *txt)
{ … }
static char *target_ts_to_str(u32 ts)
{ … }
static const char *target_tmf_name(enum tcm_tmreq_table tmf)
{ … }
void target_show_cmd(const char *pfx, struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
static void target_stop_cmd_counter_confirm(struct percpu_ref *ref)
{ … }
void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt)
{ … }
EXPORT_SYMBOL_GPL(…);
void target_stop_session(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt)
{ … }
EXPORT_SYMBOL_GPL(…);
void target_wait_for_sess_cmds(struct se_session *se_sess)
{ … }
EXPORT_SYMBOL(…);
void transport_clear_lun_ref(struct se_lun *lun)
{ … }
static bool
__transport_wait_for_tasks(struct se_cmd *cmd, bool fabric_stop,
bool *aborted, bool *tas, unsigned long *flags)
__releases(&cmd->t_state_lock)
__acquires(&cmd->t_state_lock)
{ … }
bool transport_wait_for_tasks(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
struct sense_detail { … };
static const struct sense_detail sense_detail_table[] = …;
static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
{ … }
int
transport_send_check_condition_and_sense(struct se_cmd *cmd,
sense_reason_t reason, int from_transport)
{ … }
EXPORT_SYMBOL(…);
int target_send_busy(struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
static void target_tmr_work(struct work_struct *work)
{ … }
int transport_generic_handle_tmr(
struct se_cmd *cmd)
{ … }
EXPORT_SYMBOL(…);
bool
target_check_wce(struct se_device *dev)
{ … }
bool
target_check_fua(struct se_device *dev)
{ … }