mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-10 16:39:25 +00:00
Merge patch series "add virtual remote fabric"
Dmitry Bogdanov <d.bogdanov@yadro.com> says: The patchset is based on 6.4/scsi-staging branch. The first 11 patches are just a refactoring to reduce code duplication in fabric drivers. They make several callouts be optional in fabric ops. Make a default implementation of the optional ops and remove such implementations in the fabric drivers. The last patch is a new virtual remote fabric driver. It has a valueble sence with patchset "scsi: target: make RTPI an TPG identifier" to configure RPTI on remote/tpgt_x same as on tpgt_y on other nodes in a storage cluster. That allows to report the same ports in RTPG from each node and to have a clusterwide tpg/acl/lun view in kernel. Link: https://lore.kernel.org/r/20230313181110.20566-1-d.bogdanov@yadro.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
commit
c5797fda21
@ -3300,11 +3300,6 @@ static int srpt_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int srpt_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg)
|
static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg)
|
||||||
{
|
{
|
||||||
return tpg->se_tpg_wwn->priv;
|
return tpg->se_tpg_wwn->priv;
|
||||||
@ -3334,11 +3329,6 @@ static u16 srpt_get_tag(struct se_portal_group *tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void srpt_release_cmd(struct se_cmd *se_cmd)
|
static void srpt_release_cmd(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct srpt_send_ioctx *ioctx = container_of(se_cmd,
|
struct srpt_send_ioctx *ioctx = container_of(se_cmd,
|
||||||
@ -3378,24 +3368,6 @@ static void srpt_close_session(struct se_session *se_sess)
|
|||||||
srpt_disconnect_ch_sync(ch);
|
srpt_disconnect_ch_sync(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB)
|
|
||||||
* @se_sess: SCSI target session.
|
|
||||||
*
|
|
||||||
* A quote from RFC 4455 (SCSI-MIB) about this MIB object:
|
|
||||||
* This object represents an arbitrary integer used to uniquely identify a
|
|
||||||
* particular attached remote initiator port to a particular SCSI target port
|
|
||||||
* within a particular SCSI target device within a particular SCSI instance.
|
|
||||||
*/
|
|
||||||
static u32 srpt_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void srpt_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: only used from inside debug printk's by the TCM core. */
|
/* Note: only used from inside debug printk's by the TCM core. */
|
||||||
static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd)
|
static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
@ -3866,18 +3838,13 @@ static const struct target_core_fabric_ops srpt_template = {
|
|||||||
.fabric_name = "srpt",
|
.fabric_name = "srpt",
|
||||||
.tpg_get_wwn = srpt_get_fabric_wwn,
|
.tpg_get_wwn = srpt_get_fabric_wwn,
|
||||||
.tpg_get_tag = srpt_get_tag,
|
.tpg_get_tag = srpt_get_tag,
|
||||||
.tpg_check_demo_mode = srpt_check_false,
|
|
||||||
.tpg_check_demo_mode_cache = srpt_check_true,
|
.tpg_check_demo_mode_cache = srpt_check_true,
|
||||||
.tpg_check_demo_mode_write_protect = srpt_check_true,
|
.tpg_check_demo_mode_write_protect = srpt_check_true,
|
||||||
.tpg_check_prod_mode_write_protect = srpt_check_false,
|
|
||||||
.tpg_get_inst_index = srpt_tpg_get_inst_index,
|
|
||||||
.release_cmd = srpt_release_cmd,
|
.release_cmd = srpt_release_cmd,
|
||||||
.check_stop_free = srpt_check_stop_free,
|
.check_stop_free = srpt_check_stop_free,
|
||||||
.close_session = srpt_close_session,
|
.close_session = srpt_close_session,
|
||||||
.sess_get_index = srpt_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = srpt_write_pending,
|
.write_pending = srpt_write_pending,
|
||||||
.set_default_node_attributes = srpt_set_default_node_attrs,
|
|
||||||
.get_cmd_state = srpt_get_tcm_cmd_state,
|
.get_cmd_state = srpt_get_tcm_cmd_state,
|
||||||
.queue_data_in = srpt_queue_data_in,
|
.queue_data_in = srpt_queue_data_in,
|
||||||
.queue_status = srpt_queue_status,
|
.queue_status = srpt_queue_status,
|
||||||
|
|||||||
@ -285,11 +285,6 @@ efct_lio_npiv_check_prod_write_protect(struct se_portal_group *se_tpg)
|
|||||||
return tpg->tpg_attrib.prod_mode_write_protect;
|
return tpg->tpg_attrib.prod_mode_write_protect;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 efct_lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int efct_lio_check_stop_free(struct se_cmd *se_cmd)
|
static int efct_lio_check_stop_free(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct efct_scsi_tgt_io *ocp =
|
struct efct_scsi_tgt_io *ocp =
|
||||||
@ -355,15 +350,6 @@ static void efct_lio_close_session(struct se_session *se_sess)
|
|||||||
efc_node_post_shutdown(node, NULL);
|
efc_node_post_shutdown(node, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 efct_lio_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void efct_lio_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int efct_lio_get_cmd_state(struct se_cmd *cmd)
|
static int efct_lio_get_cmd_state(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct efct_scsi_tgt_io *ocp =
|
struct efct_scsi_tgt_io *ocp =
|
||||||
@ -1607,14 +1593,11 @@ static const struct target_core_fabric_ops efct_lio_ops = {
|
|||||||
.tpg_check_demo_mode_cache = efct_lio_check_demo_mode_cache,
|
.tpg_check_demo_mode_cache = efct_lio_check_demo_mode_cache,
|
||||||
.tpg_check_demo_mode_write_protect = efct_lio_check_demo_write_protect,
|
.tpg_check_demo_mode_write_protect = efct_lio_check_demo_write_protect,
|
||||||
.tpg_check_prod_mode_write_protect = efct_lio_check_prod_write_protect,
|
.tpg_check_prod_mode_write_protect = efct_lio_check_prod_write_protect,
|
||||||
.tpg_get_inst_index = efct_lio_tpg_get_inst_index,
|
|
||||||
.check_stop_free = efct_lio_check_stop_free,
|
.check_stop_free = efct_lio_check_stop_free,
|
||||||
.aborted_task = efct_lio_aborted_task,
|
.aborted_task = efct_lio_aborted_task,
|
||||||
.release_cmd = efct_lio_release_cmd,
|
.release_cmd = efct_lio_release_cmd,
|
||||||
.close_session = efct_lio_close_session,
|
.close_session = efct_lio_close_session,
|
||||||
.sess_get_index = efct_lio_sess_get_index,
|
|
||||||
.write_pending = efct_lio_write_pending,
|
.write_pending = efct_lio_write_pending,
|
||||||
.set_default_node_attributes = efct_lio_set_default_node_attrs,
|
|
||||||
.get_cmd_state = efct_lio_get_cmd_state,
|
.get_cmd_state = efct_lio_get_cmd_state,
|
||||||
.queue_data_in = efct_lio_queue_data_in,
|
.queue_data_in = efct_lio_queue_data_in,
|
||||||
.queue_status = efct_lio_queue_status,
|
.queue_status = efct_lio_queue_status,
|
||||||
@ -1644,14 +1627,11 @@ static const struct target_core_fabric_ops efct_lio_npiv_ops = {
|
|||||||
efct_lio_npiv_check_demo_write_protect,
|
efct_lio_npiv_check_demo_write_protect,
|
||||||
.tpg_check_prod_mode_write_protect =
|
.tpg_check_prod_mode_write_protect =
|
||||||
efct_lio_npiv_check_prod_write_protect,
|
efct_lio_npiv_check_prod_write_protect,
|
||||||
.tpg_get_inst_index = efct_lio_tpg_get_inst_index,
|
|
||||||
.check_stop_free = efct_lio_check_stop_free,
|
.check_stop_free = efct_lio_check_stop_free,
|
||||||
.aborted_task = efct_lio_aborted_task,
|
.aborted_task = efct_lio_aborted_task,
|
||||||
.release_cmd = efct_lio_release_cmd,
|
.release_cmd = efct_lio_release_cmd,
|
||||||
.close_session = efct_lio_close_session,
|
.close_session = efct_lio_close_session,
|
||||||
.sess_get_index = efct_lio_sess_get_index,
|
|
||||||
.write_pending = efct_lio_write_pending,
|
.write_pending = efct_lio_write_pending,
|
||||||
.set_default_node_attributes = efct_lio_set_default_node_attrs,
|
|
||||||
.get_cmd_state = efct_lio_get_cmd_state,
|
.get_cmd_state = efct_lio_get_cmd_state,
|
||||||
.queue_data_in = efct_lio_queue_data_in,
|
.queue_data_in = efct_lio_queue_data_in,
|
||||||
.queue_status = efct_lio_queue_status,
|
.queue_status = efct_lio_queue_status,
|
||||||
|
|||||||
@ -3698,16 +3698,6 @@ static int ibmvscsis_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ibmvscsis_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ibmvscsis_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
|
static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
return target_put_sess_cmd(se_cmd);
|
return target_put_sess_cmd(se_cmd);
|
||||||
@ -3726,11 +3716,6 @@ static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)
|
|||||||
spin_unlock_bh(&vscsi->intr_lock);
|
spin_unlock_bh(&vscsi->intr_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 ibmvscsis_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
|
static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
|
struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
|
||||||
@ -3765,15 +3750,6 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ibmvscsis_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ibmvscsis_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd)
|
static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
|
struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
|
||||||
@ -3982,15 +3958,9 @@ static const struct target_core_fabric_ops ibmvscsis_ops = {
|
|||||||
.tpg_get_default_depth = ibmvscsis_get_default_depth,
|
.tpg_get_default_depth = ibmvscsis_get_default_depth,
|
||||||
.tpg_check_demo_mode = ibmvscsis_check_true,
|
.tpg_check_demo_mode = ibmvscsis_check_true,
|
||||||
.tpg_check_demo_mode_cache = ibmvscsis_check_true,
|
.tpg_check_demo_mode_cache = ibmvscsis_check_true,
|
||||||
.tpg_check_demo_mode_write_protect = ibmvscsis_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = ibmvscsis_check_false,
|
|
||||||
.tpg_get_inst_index = ibmvscsis_tpg_get_inst_index,
|
|
||||||
.check_stop_free = ibmvscsis_check_stop_free,
|
.check_stop_free = ibmvscsis_check_stop_free,
|
||||||
.release_cmd = ibmvscsis_release_cmd,
|
.release_cmd = ibmvscsis_release_cmd,
|
||||||
.sess_get_index = ibmvscsis_sess_get_index,
|
|
||||||
.write_pending = ibmvscsis_write_pending,
|
.write_pending = ibmvscsis_write_pending,
|
||||||
.set_default_node_attributes = ibmvscsis_set_default_node_attrs,
|
|
||||||
.get_cmd_state = ibmvscsis_get_cmd_state,
|
|
||||||
.queue_data_in = ibmvscsis_queue_data_in,
|
.queue_data_in = ibmvscsis_queue_data_in,
|
||||||
.queue_status = ibmvscsis_queue_status,
|
.queue_status = ibmvscsis_queue_status,
|
||||||
.queue_tm_rsp = ibmvscsis_queue_tm_rsp,
|
.queue_tm_rsp = ibmvscsis_queue_tm_rsp,
|
||||||
|
|||||||
@ -377,11 +377,6 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
|
|||||||
tcm_qla2xxx_put_sess(sess);
|
tcm_qla2xxx_put_sess(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
|
static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct qla_tgt_cmd *cmd = container_of(se_cmd,
|
struct qla_tgt_cmd *cmd = container_of(se_cmd,
|
||||||
@ -421,11 +416,6 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
|
|||||||
return qlt_rdy_to_xfer(cmd);
|
return qlt_rdy_to_xfer(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd)
|
static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
if (!(se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
|
if (!(se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
|
||||||
@ -1811,10 +1801,8 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
|
|||||||
.check_stop_free = tcm_qla2xxx_check_stop_free,
|
.check_stop_free = tcm_qla2xxx_check_stop_free,
|
||||||
.release_cmd = tcm_qla2xxx_release_cmd,
|
.release_cmd = tcm_qla2xxx_release_cmd,
|
||||||
.close_session = tcm_qla2xxx_close_session,
|
.close_session = tcm_qla2xxx_close_session,
|
||||||
.sess_get_index = tcm_qla2xxx_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = tcm_qla2xxx_write_pending,
|
.write_pending = tcm_qla2xxx_write_pending,
|
||||||
.set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs,
|
|
||||||
.get_cmd_state = tcm_qla2xxx_get_cmd_state,
|
.get_cmd_state = tcm_qla2xxx_get_cmd_state,
|
||||||
.queue_data_in = tcm_qla2xxx_queue_data_in,
|
.queue_data_in = tcm_qla2xxx_queue_data_in,
|
||||||
.queue_status = tcm_qla2xxx_queue_status,
|
.queue_status = tcm_qla2xxx_queue_status,
|
||||||
@ -1852,10 +1840,8 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
|
|||||||
.check_stop_free = tcm_qla2xxx_check_stop_free,
|
.check_stop_free = tcm_qla2xxx_check_stop_free,
|
||||||
.release_cmd = tcm_qla2xxx_release_cmd,
|
.release_cmd = tcm_qla2xxx_release_cmd,
|
||||||
.close_session = tcm_qla2xxx_close_session,
|
.close_session = tcm_qla2xxx_close_session,
|
||||||
.sess_get_index = tcm_qla2xxx_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = tcm_qla2xxx_write_pending,
|
.write_pending = tcm_qla2xxx_write_pending,
|
||||||
.set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs,
|
|
||||||
.get_cmd_state = tcm_qla2xxx_get_cmd_state,
|
.get_cmd_state = tcm_qla2xxx_get_cmd_state,
|
||||||
.queue_data_in = tcm_qla2xxx_queue_data_in,
|
.queue_data_in = tcm_qla2xxx_queue_data_in,
|
||||||
.queue_status = tcm_qla2xxx_queue_status,
|
.queue_status = tcm_qla2xxx_queue_status,
|
||||||
|
|||||||
@ -47,5 +47,6 @@ source "drivers/target/loopback/Kconfig"
|
|||||||
source "drivers/target/tcm_fc/Kconfig"
|
source "drivers/target/tcm_fc/Kconfig"
|
||||||
source "drivers/target/iscsi/Kconfig"
|
source "drivers/target/iscsi/Kconfig"
|
||||||
source "drivers/target/sbp/Kconfig"
|
source "drivers/target/sbp/Kconfig"
|
||||||
|
source "drivers/target/tcm_remote/Kconfig"
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@ -30,3 +30,4 @@ obj-$(CONFIG_LOOPBACK_TARGET) += loopback/
|
|||||||
obj-$(CONFIG_TCM_FC) += tcm_fc/
|
obj-$(CONFIG_TCM_FC) += tcm_fc/
|
||||||
obj-$(CONFIG_ISCSI_TARGET) += iscsi/
|
obj-$(CONFIG_ISCSI_TARGET) += iscsi/
|
||||||
obj-$(CONFIG_SBP_TARGET) += sbp/
|
obj-$(CONFIG_SBP_TARGET) += sbp/
|
||||||
|
obj-$(CONFIG_REMOTE_TARGET) += tcm_remote/
|
||||||
|
|||||||
@ -480,30 +480,6 @@ static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allow I_T Nexus full READ-WRITE access without explict Initiator Node ACLs for
|
|
||||||
* local virtual Linux/SCSI LLD passthrough into VM hypervisor guest
|
|
||||||
*/
|
|
||||||
static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Because TCM_Loop does not use explict ACLs and MappedLUNs, this will
|
|
||||||
* never be called for TCM_Loop by target_core_fabric_configfs.c code.
|
|
||||||
* It has been added here as a nop for target_fabric_tf_ops_check()
|
|
||||||
*/
|
|
||||||
static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
||||||
{
|
{
|
||||||
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
|
struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg,
|
||||||
@ -511,21 +487,11 @@ static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
|||||||
return tl_tpg->tl_fabric_prot_type;
|
return tl_tpg->tl_fabric_prot_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
|
static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
|
static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
|
struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
|
||||||
@ -1124,18 +1090,11 @@ static const struct target_core_fabric_ops loop_ops = {
|
|||||||
.tpg_get_wwn = tcm_loop_get_endpoint_wwn,
|
.tpg_get_wwn = tcm_loop_get_endpoint_wwn,
|
||||||
.tpg_get_tag = tcm_loop_get_tag,
|
.tpg_get_tag = tcm_loop_get_tag,
|
||||||
.tpg_check_demo_mode = tcm_loop_check_demo_mode,
|
.tpg_check_demo_mode = tcm_loop_check_demo_mode,
|
||||||
.tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
|
|
||||||
.tpg_check_demo_mode_write_protect =
|
|
||||||
tcm_loop_check_demo_mode_write_protect,
|
|
||||||
.tpg_check_prod_mode_write_protect =
|
|
||||||
tcm_loop_check_prod_mode_write_protect,
|
|
||||||
.tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
|
.tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
|
||||||
.tpg_get_inst_index = tcm_loop_get_inst_index,
|
|
||||||
.check_stop_free = tcm_loop_check_stop_free,
|
.check_stop_free = tcm_loop_check_stop_free,
|
||||||
.release_cmd = tcm_loop_release_cmd,
|
.release_cmd = tcm_loop_release_cmd,
|
||||||
.sess_get_index = tcm_loop_sess_get_index,
|
.sess_get_index = tcm_loop_sess_get_index,
|
||||||
.write_pending = tcm_loop_write_pending,
|
.write_pending = tcm_loop_write_pending,
|
||||||
.set_default_node_attributes = tcm_loop_set_default_node_attributes,
|
|
||||||
.get_cmd_state = tcm_loop_get_cmd_state,
|
.get_cmd_state = tcm_loop_get_cmd_state,
|
||||||
.queue_data_in = tcm_loop_queue_data_in,
|
.queue_data_in = tcm_loop_queue_data_in,
|
||||||
.queue_status = tcm_loop_queue_status,
|
.queue_status = tcm_loop_queue_status,
|
||||||
|
|||||||
@ -1673,11 +1673,6 @@ static int sbp_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sbp_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg)
|
static char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg)
|
||||||
{
|
{
|
||||||
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg);
|
||||||
@ -1692,11 +1687,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg)
|
|||||||
return tpg->tport_tpgt;
|
return tpg->tport_tpgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sbp_release_cmd(struct se_cmd *se_cmd)
|
static void sbp_release_cmd(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct sbp_target_request *req = container_of(se_cmd,
|
struct sbp_target_request *req = container_of(se_cmd,
|
||||||
@ -1705,11 +1695,6 @@ static void sbp_release_cmd(struct se_cmd *se_cmd)
|
|||||||
sbp_free_request(req);
|
sbp_free_request(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 sbp_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sbp_write_pending(struct se_cmd *se_cmd)
|
static int sbp_write_pending(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct sbp_target_request *req = container_of(se_cmd,
|
struct sbp_target_request *req = container_of(se_cmd,
|
||||||
@ -1733,16 +1718,6 @@ static int sbp_write_pending(struct se_cmd *se_cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sbp_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sbp_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sbp_queue_data_in(struct se_cmd *se_cmd)
|
static int sbp_queue_data_in(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct sbp_target_request *req = container_of(se_cmd,
|
struct sbp_target_request *req = container_of(se_cmd,
|
||||||
@ -2281,14 +2256,8 @@ static const struct target_core_fabric_ops sbp_ops = {
|
|||||||
.tpg_get_tag = sbp_get_tag,
|
.tpg_get_tag = sbp_get_tag,
|
||||||
.tpg_check_demo_mode = sbp_check_true,
|
.tpg_check_demo_mode = sbp_check_true,
|
||||||
.tpg_check_demo_mode_cache = sbp_check_true,
|
.tpg_check_demo_mode_cache = sbp_check_true,
|
||||||
.tpg_check_demo_mode_write_protect = sbp_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = sbp_check_false,
|
|
||||||
.tpg_get_inst_index = sbp_tpg_get_inst_index,
|
|
||||||
.release_cmd = sbp_release_cmd,
|
.release_cmd = sbp_release_cmd,
|
||||||
.sess_get_index = sbp_sess_get_index,
|
|
||||||
.write_pending = sbp_write_pending,
|
.write_pending = sbp_write_pending,
|
||||||
.set_default_node_attributes = sbp_set_default_node_attrs,
|
|
||||||
.get_cmd_state = sbp_get_cmd_state,
|
|
||||||
.queue_data_in = sbp_queue_data_in,
|
.queue_data_in = sbp_queue_data_in,
|
||||||
.queue_status = sbp_queue_status,
|
.queue_status = sbp_queue_status,
|
||||||
.queue_tm_rsp = sbp_queue_tm_rsp,
|
.queue_tm_rsp = sbp_queue_tm_rsp,
|
||||||
|
|||||||
@ -335,6 +335,29 @@ EXPORT_SYMBOL(target_undepend_item);
|
|||||||
/*##############################################################################
|
/*##############################################################################
|
||||||
// Start functions called by external Target Fabrics Modules
|
// Start functions called by external Target Fabrics Modules
|
||||||
//############################################################################*/
|
//############################################################################*/
|
||||||
|
static int target_disable_feature(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 target_default_get_inst_index(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 target_default_sess_get_index(struct se_session *se_sess)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void target_set_default_node_attributes(struct se_node_acl *se_acl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int target_default_get_cmd_state(struct se_cmd *se_cmd)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
|
static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
|
||||||
{
|
{
|
||||||
@ -362,46 +385,14 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
|
|||||||
pr_err("Missing tfo->tpg_get_tag()\n");
|
pr_err("Missing tfo->tpg_get_tag()\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!tfo->tpg_check_demo_mode) {
|
|
||||||
pr_err("Missing tfo->tpg_check_demo_mode()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->tpg_check_demo_mode_cache) {
|
|
||||||
pr_err("Missing tfo->tpg_check_demo_mode_cache()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->tpg_check_demo_mode_write_protect) {
|
|
||||||
pr_err("Missing tfo->tpg_check_demo_mode_write_protect()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->tpg_check_prod_mode_write_protect) {
|
|
||||||
pr_err("Missing tfo->tpg_check_prod_mode_write_protect()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->tpg_get_inst_index) {
|
|
||||||
pr_err("Missing tfo->tpg_get_inst_index()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->release_cmd) {
|
if (!tfo->release_cmd) {
|
||||||
pr_err("Missing tfo->release_cmd()\n");
|
pr_err("Missing tfo->release_cmd()\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!tfo->sess_get_index) {
|
|
||||||
pr_err("Missing tfo->sess_get_index()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->write_pending) {
|
if (!tfo->write_pending) {
|
||||||
pr_err("Missing tfo->write_pending()\n");
|
pr_err("Missing tfo->write_pending()\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (!tfo->set_default_node_attributes) {
|
|
||||||
pr_err("Missing tfo->set_default_node_attributes()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->get_cmd_state) {
|
|
||||||
pr_err("Missing tfo->get_cmd_state()\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!tfo->queue_data_in) {
|
if (!tfo->queue_data_in) {
|
||||||
pr_err("Missing tfo->queue_data_in()\n");
|
pr_err("Missing tfo->queue_data_in()\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -447,8 +438,36 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void target_set_default_ops(struct target_core_fabric_ops *tfo)
|
||||||
|
{
|
||||||
|
if (!tfo->tpg_check_demo_mode)
|
||||||
|
tfo->tpg_check_demo_mode = target_disable_feature;
|
||||||
|
|
||||||
|
if (!tfo->tpg_check_demo_mode_cache)
|
||||||
|
tfo->tpg_check_demo_mode_cache = target_disable_feature;
|
||||||
|
|
||||||
|
if (!tfo->tpg_check_demo_mode_write_protect)
|
||||||
|
tfo->tpg_check_demo_mode_write_protect = target_disable_feature;
|
||||||
|
|
||||||
|
if (!tfo->tpg_check_prod_mode_write_protect)
|
||||||
|
tfo->tpg_check_prod_mode_write_protect = target_disable_feature;
|
||||||
|
|
||||||
|
if (!tfo->tpg_get_inst_index)
|
||||||
|
tfo->tpg_get_inst_index = target_default_get_inst_index;
|
||||||
|
|
||||||
|
if (!tfo->sess_get_index)
|
||||||
|
tfo->sess_get_index = target_default_sess_get_index;
|
||||||
|
|
||||||
|
if (!tfo->set_default_node_attributes)
|
||||||
|
tfo->set_default_node_attributes = target_set_default_node_attributes;
|
||||||
|
|
||||||
|
if (!tfo->get_cmd_state)
|
||||||
|
tfo->get_cmd_state = target_default_get_cmd_state;
|
||||||
|
}
|
||||||
|
|
||||||
int target_register_template(const struct target_core_fabric_ops *fo)
|
int target_register_template(const struct target_core_fabric_ops *fo)
|
||||||
{
|
{
|
||||||
|
struct target_core_fabric_ops *tfo;
|
||||||
struct target_fabric_configfs *tf;
|
struct target_fabric_configfs *tf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -461,10 +480,18 @@ int target_register_template(const struct target_core_fabric_ops *fo)
|
|||||||
pr_err("%s: could not allocate memory!\n", __func__);
|
pr_err("%s: could not allocate memory!\n", __func__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
tfo = kzalloc(sizeof(struct target_core_fabric_ops), GFP_KERNEL);
|
||||||
|
if (!tfo) {
|
||||||
|
kfree(tf);
|
||||||
|
pr_err("%s: could not allocate memory!\n", __func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(tfo, fo, sizeof(*tfo));
|
||||||
|
target_set_default_ops(tfo);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&tf->tf_list);
|
INIT_LIST_HEAD(&tf->tf_list);
|
||||||
atomic_set(&tf->tf_access_cnt, 0);
|
atomic_set(&tf->tf_access_cnt, 0);
|
||||||
tf->tf_ops = fo;
|
tf->tf_ops = tfo;
|
||||||
target_fabric_setup_cits(tf);
|
target_fabric_setup_cits(tf);
|
||||||
|
|
||||||
mutex_lock(&g_tf_lock);
|
mutex_lock(&g_tf_lock);
|
||||||
@ -492,6 +519,7 @@ void target_unregister_template(const struct target_core_fabric_ops *fo)
|
|||||||
*/
|
*/
|
||||||
rcu_barrier();
|
rcu_barrier();
|
||||||
kfree(t->tf_tpg_base_cit.ct_attrs);
|
kfree(t->tf_tpg_base_cit.ct_attrs);
|
||||||
|
kfree(t->tf_ops);
|
||||||
kfree(t);
|
kfree(t);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -146,7 +146,6 @@ void ft_release_cmd(struct se_cmd *);
|
|||||||
int ft_queue_status(struct se_cmd *);
|
int ft_queue_status(struct se_cmd *);
|
||||||
int ft_queue_data_in(struct se_cmd *);
|
int ft_queue_data_in(struct se_cmd *);
|
||||||
int ft_write_pending(struct se_cmd *);
|
int ft_write_pending(struct se_cmd *);
|
||||||
int ft_get_cmd_state(struct se_cmd *);
|
|
||||||
void ft_queue_tm_resp(struct se_cmd *);
|
void ft_queue_tm_resp(struct se_cmd *);
|
||||||
void ft_aborted_task(struct se_cmd *);
|
void ft_aborted_task(struct se_cmd *);
|
||||||
|
|
||||||
|
|||||||
@ -223,11 +223,6 @@ int ft_write_pending(struct se_cmd *se_cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ft_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FC sequence response handler for follow-on sequences (data) and aborts.
|
* FC sequence response handler for follow-on sequences (data) and aborts.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -398,15 +398,6 @@ static u16 ft_get_tag(struct se_portal_group *se_tpg)
|
|||||||
return ft_tpg(se_tpg)->index;
|
return ft_tpg(se_tpg)->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ft_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ft_set_default_node_attr(struct se_node_acl *se_nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
||||||
{
|
{
|
||||||
return ft_tpg(se_tpg)->index;
|
return ft_tpg(se_tpg)->index;
|
||||||
@ -418,10 +409,6 @@ static const struct target_core_fabric_ops ft_fabric_ops = {
|
|||||||
.node_acl_size = sizeof(struct ft_node_acl),
|
.node_acl_size = sizeof(struct ft_node_acl),
|
||||||
.tpg_get_wwn = ft_get_fabric_wwn,
|
.tpg_get_wwn = ft_get_fabric_wwn,
|
||||||
.tpg_get_tag = ft_get_tag,
|
.tpg_get_tag = ft_get_tag,
|
||||||
.tpg_check_demo_mode = ft_check_false,
|
|
||||||
.tpg_check_demo_mode_cache = ft_check_false,
|
|
||||||
.tpg_check_demo_mode_write_protect = ft_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = ft_check_false,
|
|
||||||
.tpg_get_inst_index = ft_tpg_get_inst_index,
|
.tpg_get_inst_index = ft_tpg_get_inst_index,
|
||||||
.check_stop_free = ft_check_stop_free,
|
.check_stop_free = ft_check_stop_free,
|
||||||
.release_cmd = ft_release_cmd,
|
.release_cmd = ft_release_cmd,
|
||||||
@ -429,8 +416,6 @@ static const struct target_core_fabric_ops ft_fabric_ops = {
|
|||||||
.sess_get_index = ft_sess_get_index,
|
.sess_get_index = ft_sess_get_index,
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = ft_write_pending,
|
.write_pending = ft_write_pending,
|
||||||
.set_default_node_attributes = ft_set_default_node_attr,
|
|
||||||
.get_cmd_state = ft_get_cmd_state,
|
|
||||||
.queue_data_in = ft_queue_data_in,
|
.queue_data_in = ft_queue_data_in,
|
||||||
.queue_status = ft_queue_status,
|
.queue_status = ft_queue_status,
|
||||||
.queue_tm_rsp = ft_queue_tm_resp,
|
.queue_tm_rsp = ft_queue_tm_resp,
|
||||||
|
|||||||
8
drivers/target/tcm_remote/Kconfig
Normal file
8
drivers/target/tcm_remote/Kconfig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
config REMOTE_TARGET
|
||||||
|
tristate "TCM Virtual Remote target"
|
||||||
|
depends on SCSI
|
||||||
|
help
|
||||||
|
Say Y here to enable the TCM Virtual Remote fabric
|
||||||
|
That fabric is a dummy fabric to tell TCM about configuration
|
||||||
|
of TPG/ACL/LUN on peer nodes in a cluster.
|
||||||
2
drivers/target/tcm_remote/Makefile
Normal file
2
drivers/target/tcm_remote/Makefile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
obj-$(CONFIG_REMOTE_TARGET) += tcm_remote.o
|
||||||
268
drivers/target/tcm_remote/tcm_remote.c
Normal file
268
drivers/target/tcm_remote/tcm_remote.c
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/configfs.h>
|
||||||
|
#include <scsi/scsi.h>
|
||||||
|
#include <scsi/scsi_tcq.h>
|
||||||
|
#include <scsi/scsi_host.h>
|
||||||
|
#include <scsi/scsi_device.h>
|
||||||
|
#include <scsi/scsi_cmnd.h>
|
||||||
|
|
||||||
|
#include <target/target_core_base.h>
|
||||||
|
#include <target/target_core_fabric.h>
|
||||||
|
|
||||||
|
#include "tcm_remote.h"
|
||||||
|
|
||||||
|
static inline struct tcm_remote_tpg *remote_tpg(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
return container_of(se_tpg, struct tcm_remote_tpg, remote_se_tpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *tcm_remote_get_endpoint_wwn(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Return the passed NAA identifier for the Target Port
|
||||||
|
*/
|
||||||
|
return &remote_tpg(se_tpg)->remote_hba->remote_wwn_address[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 tcm_remote_get_tag(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This Tag is used when forming SCSI Name identifier in EVPD=1 0x83
|
||||||
|
* to represent the SCSI Target Port.
|
||||||
|
*/
|
||||||
|
return remote_tpg(se_tpg)->remote_tpgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcm_remote_dummy_cmd_fn(struct se_cmd *se_cmd)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_remote_dummy_cmd_void_fn(struct se_cmd *se_cmd)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *tcm_remote_dump_proto_id(struct tcm_remote_hba *remote_hba)
|
||||||
|
{
|
||||||
|
switch (remote_hba->remote_proto_id) {
|
||||||
|
case SCSI_PROTOCOL_SAS:
|
||||||
|
return "SAS";
|
||||||
|
case SCSI_PROTOCOL_SRP:
|
||||||
|
return "SRP";
|
||||||
|
case SCSI_PROTOCOL_FCP:
|
||||||
|
return "FCP";
|
||||||
|
case SCSI_PROTOCOL_ISCSI:
|
||||||
|
return "iSCSI";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcm_remote_port_link(
|
||||||
|
struct se_portal_group *se_tpg,
|
||||||
|
struct se_lun *lun)
|
||||||
|
{
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Port Link LUN %lld Successful\n",
|
||||||
|
lun->unpacked_lun);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_remote_port_unlink(
|
||||||
|
struct se_portal_group *se_tpg,
|
||||||
|
struct se_lun *lun)
|
||||||
|
{
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Port Unlink LUN %lld Successful\n",
|
||||||
|
lun->unpacked_lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct se_portal_group *tcm_remote_make_tpg(
|
||||||
|
struct se_wwn *wwn,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
struct tcm_remote_hba *remote_hba = container_of(wwn,
|
||||||
|
struct tcm_remote_hba, remote_hba_wwn);
|
||||||
|
struct tcm_remote_tpg *remote_tpg;
|
||||||
|
unsigned long tpgt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (strstr(name, "tpgt_") != name) {
|
||||||
|
pr_err("Unable to locate \"tpgt_#\" directory group\n");
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
if (kstrtoul(name + 5, 10, &tpgt))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
|
if (tpgt >= TL_TPGS_PER_HBA) {
|
||||||
|
pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n",
|
||||||
|
tpgt, TL_TPGS_PER_HBA);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
remote_tpg = &remote_hba->remote_hba_tpgs[tpgt];
|
||||||
|
remote_tpg->remote_hba = remote_hba;
|
||||||
|
remote_tpg->remote_tpgt = tpgt;
|
||||||
|
/*
|
||||||
|
* Register the remote_tpg as a emulated TCM Target Endpoint
|
||||||
|
*/
|
||||||
|
ret = core_tpg_register(wwn, &remote_tpg->remote_se_tpg,
|
||||||
|
remote_hba->remote_proto_id);
|
||||||
|
if (ret < 0)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n",
|
||||||
|
tcm_remote_dump_proto_id(remote_hba),
|
||||||
|
config_item_name(&wwn->wwn_group.cg_item), tpgt);
|
||||||
|
return &remote_tpg->remote_se_tpg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_remote_drop_tpg(struct se_portal_group *se_tpg)
|
||||||
|
{
|
||||||
|
struct se_wwn *wwn = se_tpg->se_tpg_wwn;
|
||||||
|
struct tcm_remote_tpg *remote_tpg = container_of(se_tpg,
|
||||||
|
struct tcm_remote_tpg, remote_se_tpg);
|
||||||
|
struct tcm_remote_hba *remote_hba;
|
||||||
|
unsigned short tpgt;
|
||||||
|
|
||||||
|
remote_hba = remote_tpg->remote_hba;
|
||||||
|
tpgt = remote_tpg->remote_tpgt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deregister the remote_tpg as a emulated TCM Target Endpoint
|
||||||
|
*/
|
||||||
|
core_tpg_deregister(se_tpg);
|
||||||
|
|
||||||
|
remote_tpg->remote_hba = NULL;
|
||||||
|
remote_tpg->remote_tpgt = 0;
|
||||||
|
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n",
|
||||||
|
tcm_remote_dump_proto_id(remote_hba),
|
||||||
|
config_item_name(&wwn->wwn_group.cg_item), tpgt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct se_wwn *tcm_remote_make_wwn(
|
||||||
|
struct target_fabric_configfs *tf,
|
||||||
|
struct config_group *group,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
struct tcm_remote_hba *remote_hba;
|
||||||
|
char *ptr;
|
||||||
|
int ret, off = 0;
|
||||||
|
|
||||||
|
remote_hba = kzalloc(sizeof(*remote_hba), GFP_KERNEL);
|
||||||
|
if (!remote_hba)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the emulated Protocol Identifier and Target Port Name
|
||||||
|
* based on the incoming configfs directory name.
|
||||||
|
*/
|
||||||
|
ptr = strstr(name, "naa.");
|
||||||
|
if (ptr) {
|
||||||
|
remote_hba->remote_proto_id = SCSI_PROTOCOL_SAS;
|
||||||
|
goto check_len;
|
||||||
|
}
|
||||||
|
ptr = strstr(name, "fc.");
|
||||||
|
if (ptr) {
|
||||||
|
remote_hba->remote_proto_id = SCSI_PROTOCOL_FCP;
|
||||||
|
off = 3; /* Skip over "fc." */
|
||||||
|
goto check_len;
|
||||||
|
}
|
||||||
|
ptr = strstr(name, "0x");
|
||||||
|
if (ptr) {
|
||||||
|
remote_hba->remote_proto_id = SCSI_PROTOCOL_SRP;
|
||||||
|
off = 2; /* Skip over "0x" */
|
||||||
|
goto check_len;
|
||||||
|
}
|
||||||
|
ptr = strstr(name, "iqn.");
|
||||||
|
if (!ptr) {
|
||||||
|
pr_err("Unable to locate prefix for emulated Target Port: %s\n",
|
||||||
|
name);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
remote_hba->remote_proto_id = SCSI_PROTOCOL_ISCSI;
|
||||||
|
|
||||||
|
check_len:
|
||||||
|
if (strlen(name) >= TL_WWN_ADDR_LEN) {
|
||||||
|
pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n",
|
||||||
|
name, tcm_remote_dump_proto_id(remote_hba), TL_WWN_ADDR_LEN);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
snprintf(&remote_hba->remote_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
|
||||||
|
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Allocated emulated Target %s Address: %s\n",
|
||||||
|
tcm_remote_dump_proto_id(remote_hba), name);
|
||||||
|
return &remote_hba->remote_hba_wwn;
|
||||||
|
out:
|
||||||
|
kfree(remote_hba);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcm_remote_drop_wwn(struct se_wwn *wwn)
|
||||||
|
{
|
||||||
|
struct tcm_remote_hba *remote_hba = container_of(wwn,
|
||||||
|
struct tcm_remote_hba, remote_hba_wwn);
|
||||||
|
|
||||||
|
pr_debug("TCM_Remote_ConfigFS: Deallocating emulated Target %s Address: %s\n",
|
||||||
|
tcm_remote_dump_proto_id(remote_hba),
|
||||||
|
remote_hba->remote_wwn_address);
|
||||||
|
kfree(remote_hba);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t tcm_remote_wwn_version_show(struct config_item *item, char *page)
|
||||||
|
{
|
||||||
|
return sprintf(page, "TCM Remote Fabric module %s\n", TCM_REMOTE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIGFS_ATTR_RO(tcm_remote_wwn_, version);
|
||||||
|
|
||||||
|
static struct configfs_attribute *tcm_remote_wwn_attrs[] = {
|
||||||
|
&tcm_remote_wwn_attr_version,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct target_core_fabric_ops remote_ops = {
|
||||||
|
.module = THIS_MODULE,
|
||||||
|
.fabric_name = "remote",
|
||||||
|
.tpg_get_wwn = tcm_remote_get_endpoint_wwn,
|
||||||
|
.tpg_get_tag = tcm_remote_get_tag,
|
||||||
|
.check_stop_free = tcm_remote_dummy_cmd_fn,
|
||||||
|
.release_cmd = tcm_remote_dummy_cmd_void_fn,
|
||||||
|
.write_pending = tcm_remote_dummy_cmd_fn,
|
||||||
|
.queue_data_in = tcm_remote_dummy_cmd_fn,
|
||||||
|
.queue_status = tcm_remote_dummy_cmd_fn,
|
||||||
|
.queue_tm_rsp = tcm_remote_dummy_cmd_void_fn,
|
||||||
|
.aborted_task = tcm_remote_dummy_cmd_void_fn,
|
||||||
|
.fabric_make_wwn = tcm_remote_make_wwn,
|
||||||
|
.fabric_drop_wwn = tcm_remote_drop_wwn,
|
||||||
|
.fabric_make_tpg = tcm_remote_make_tpg,
|
||||||
|
.fabric_drop_tpg = tcm_remote_drop_tpg,
|
||||||
|
.fabric_post_link = tcm_remote_port_link,
|
||||||
|
.fabric_pre_unlink = tcm_remote_port_unlink,
|
||||||
|
.tfc_wwn_attrs = tcm_remote_wwn_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init tcm_remote_fabric_init(void)
|
||||||
|
{
|
||||||
|
return target_register_template(&remote_ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit tcm_remote_fabric_exit(void)
|
||||||
|
{
|
||||||
|
target_unregister_template(&remote_ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("TCM virtual remote target");
|
||||||
|
MODULE_AUTHOR("Dmitry Bogdanov <d.bogdanov@yadro.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
module_init(tcm_remote_fabric_init);
|
||||||
|
module_exit(tcm_remote_fabric_exit);
|
||||||
20
drivers/target/tcm_remote/tcm_remote.h
Normal file
20
drivers/target/tcm_remote/tcm_remote.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
|
||||||
|
#define TCM_REMOTE_VERSION "v0.1"
|
||||||
|
#define TL_WWN_ADDR_LEN 256
|
||||||
|
#define TL_TPGS_PER_HBA 32
|
||||||
|
|
||||||
|
struct tcm_remote_tpg {
|
||||||
|
unsigned short remote_tpgt;
|
||||||
|
struct se_portal_group remote_se_tpg;
|
||||||
|
struct tcm_remote_hba *remote_hba;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tcm_remote_hba {
|
||||||
|
u8 remote_proto_id;
|
||||||
|
unsigned char remote_wwn_address[TL_WWN_ADDR_LEN];
|
||||||
|
struct tcm_remote_tpg remote_hba_tpgs[TL_TPGS_PER_HBA];
|
||||||
|
struct se_wwn remote_hba_wwn;
|
||||||
|
};
|
||||||
@ -1253,11 +1253,6 @@ static int usbg_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usbg_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg)
|
static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg)
|
||||||
{
|
{
|
||||||
struct usbg_tpg *tpg = container_of(se_tpg,
|
struct usbg_tpg *tpg = container_of(se_tpg,
|
||||||
@ -1274,11 +1269,6 @@ static u16 usbg_get_tag(struct se_portal_group *se_tpg)
|
|||||||
return tpg->tport_tpgt;
|
return tpg->tport_tpgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usbg_release_cmd(struct se_cmd *se_cmd)
|
static void usbg_release_cmd(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
|
struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
|
||||||
@ -1289,20 +1279,6 @@ static void usbg_release_cmd(struct se_cmd *se_cmd)
|
|||||||
target_free_tag(se_sess, se_cmd);
|
target_free_tag(se_sess, se_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 usbg_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usbg_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usbg_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usbg_queue_tm_rsp(struct se_cmd *se_cmd)
|
static void usbg_queue_tm_rsp(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1691,16 +1667,9 @@ static const struct target_core_fabric_ops usbg_ops = {
|
|||||||
.tpg_get_wwn = usbg_get_fabric_wwn,
|
.tpg_get_wwn = usbg_get_fabric_wwn,
|
||||||
.tpg_get_tag = usbg_get_tag,
|
.tpg_get_tag = usbg_get_tag,
|
||||||
.tpg_check_demo_mode = usbg_check_true,
|
.tpg_check_demo_mode = usbg_check_true,
|
||||||
.tpg_check_demo_mode_cache = usbg_check_false,
|
|
||||||
.tpg_check_demo_mode_write_protect = usbg_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = usbg_check_false,
|
|
||||||
.tpg_get_inst_index = usbg_tpg_get_inst_index,
|
|
||||||
.release_cmd = usbg_release_cmd,
|
.release_cmd = usbg_release_cmd,
|
||||||
.sess_get_index = usbg_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = usbg_send_write_request,
|
.write_pending = usbg_send_write_request,
|
||||||
.set_default_node_attributes = usbg_set_default_node_attrs,
|
|
||||||
.get_cmd_state = usbg_get_cmd_state,
|
|
||||||
.queue_data_in = usbg_send_read_response,
|
.queue_data_in = usbg_send_read_response,
|
||||||
.queue_status = usbg_send_status_response,
|
.queue_status = usbg_send_status_response,
|
||||||
.queue_tm_rsp = usbg_queue_tm_rsp,
|
.queue_tm_rsp = usbg_queue_tm_rsp,
|
||||||
|
|||||||
@ -294,11 +294,6 @@ static int vhost_scsi_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vhost_scsi_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *vhost_scsi_get_fabric_wwn(struct se_portal_group *se_tpg)
|
static char *vhost_scsi_get_fabric_wwn(struct se_portal_group *se_tpg)
|
||||||
{
|
{
|
||||||
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
struct vhost_scsi_tpg *tpg = container_of(se_tpg,
|
||||||
@ -323,11 +318,6 @@ static int vhost_scsi_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
|||||||
return tpg->tv_fabric_prot_type;
|
return tpg->tv_fabric_prot_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 vhost_scsi_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd)
|
static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct vhost_scsi_cmd *tv_cmd = container_of(se_cmd,
|
struct vhost_scsi_cmd *tv_cmd = container_of(se_cmd,
|
||||||
@ -378,11 +368,6 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 vhost_scsi_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vhost_scsi_write_pending(struct se_cmd *se_cmd)
|
static int vhost_scsi_write_pending(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
/* Go ahead and process the write immediately */
|
/* Go ahead and process the write immediately */
|
||||||
@ -390,16 +375,6 @@ static int vhost_scsi_write_pending(struct se_cmd *se_cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vhost_scsi_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vhost_scsi_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vhost_scsi_queue_data_in(struct se_cmd *se_cmd)
|
static int vhost_scsi_queue_data_in(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
transport_generic_free_cmd(se_cmd, 0);
|
transport_generic_free_cmd(se_cmd, 0);
|
||||||
@ -2460,17 +2435,11 @@ static const struct target_core_fabric_ops vhost_scsi_ops = {
|
|||||||
.tpg_get_tag = vhost_scsi_get_tpgt,
|
.tpg_get_tag = vhost_scsi_get_tpgt,
|
||||||
.tpg_check_demo_mode = vhost_scsi_check_true,
|
.tpg_check_demo_mode = vhost_scsi_check_true,
|
||||||
.tpg_check_demo_mode_cache = vhost_scsi_check_true,
|
.tpg_check_demo_mode_cache = vhost_scsi_check_true,
|
||||||
.tpg_check_demo_mode_write_protect = vhost_scsi_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = vhost_scsi_check_false,
|
|
||||||
.tpg_check_prot_fabric_only = vhost_scsi_check_prot_fabric_only,
|
.tpg_check_prot_fabric_only = vhost_scsi_check_prot_fabric_only,
|
||||||
.tpg_get_inst_index = vhost_scsi_tpg_get_inst_index,
|
|
||||||
.release_cmd = vhost_scsi_release_cmd,
|
.release_cmd = vhost_scsi_release_cmd,
|
||||||
.check_stop_free = vhost_scsi_check_stop_free,
|
.check_stop_free = vhost_scsi_check_stop_free,
|
||||||
.sess_get_index = vhost_scsi_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = vhost_scsi_write_pending,
|
.write_pending = vhost_scsi_write_pending,
|
||||||
.set_default_node_attributes = vhost_scsi_set_default_node_attrs,
|
|
||||||
.get_cmd_state = vhost_scsi_get_cmd_state,
|
|
||||||
.queue_data_in = vhost_scsi_queue_data_in,
|
.queue_data_in = vhost_scsi_queue_data_in,
|
||||||
.queue_status = vhost_scsi_queue_status,
|
.queue_status = vhost_scsi_queue_status,
|
||||||
.queue_tm_rsp = vhost_scsi_queue_tm_rsp,
|
.queue_tm_rsp = vhost_scsi_queue_tm_rsp,
|
||||||
|
|||||||
@ -1406,11 +1406,6 @@ static void scsiback_drop_tport(struct se_wwn *wwn)
|
|||||||
kfree(tport);
|
kfree(tport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scsiback_check_stop_free(struct se_cmd *se_cmd)
|
static int scsiback_check_stop_free(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
return transport_generic_free_cmd(se_cmd, 0);
|
return transport_generic_free_cmd(se_cmd, 0);
|
||||||
@ -1421,11 +1416,6 @@ static void scsiback_release_cmd(struct se_cmd *se_cmd)
|
|||||||
target_free_tag(se_cmd->se_sess, se_cmd);
|
target_free_tag(se_cmd->se_sess, se_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 scsiback_sess_get_index(struct se_session *se_sess)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scsiback_write_pending(struct se_cmd *se_cmd)
|
static int scsiback_write_pending(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
/* Go ahead and process the write immediately */
|
/* Go ahead and process the write immediately */
|
||||||
@ -1434,15 +1424,6 @@ static int scsiback_write_pending(struct se_cmd *se_cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsiback_set_default_node_attrs(struct se_node_acl *nacl)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scsiback_get_cmd_state(struct se_cmd *se_cmd)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scsiback_queue_data_in(struct se_cmd *se_cmd)
|
static int scsiback_queue_data_in(struct se_cmd *se_cmd)
|
||||||
{
|
{
|
||||||
struct vscsibk_pend *pending_req = container_of(se_cmd,
|
struct vscsibk_pend *pending_req = container_of(se_cmd,
|
||||||
@ -1822,11 +1803,6 @@ static int scsiback_check_true(struct se_portal_group *se_tpg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scsiback_check_false(struct se_portal_group *se_tpg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct target_core_fabric_ops scsiback_ops = {
|
static const struct target_core_fabric_ops scsiback_ops = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.fabric_name = "xen-pvscsi",
|
.fabric_name = "xen-pvscsi",
|
||||||
@ -1834,16 +1810,10 @@ static const struct target_core_fabric_ops scsiback_ops = {
|
|||||||
.tpg_get_tag = scsiback_get_tag,
|
.tpg_get_tag = scsiback_get_tag,
|
||||||
.tpg_check_demo_mode = scsiback_check_true,
|
.tpg_check_demo_mode = scsiback_check_true,
|
||||||
.tpg_check_demo_mode_cache = scsiback_check_true,
|
.tpg_check_demo_mode_cache = scsiback_check_true,
|
||||||
.tpg_check_demo_mode_write_protect = scsiback_check_false,
|
|
||||||
.tpg_check_prod_mode_write_protect = scsiback_check_false,
|
|
||||||
.tpg_get_inst_index = scsiback_tpg_get_inst_index,
|
|
||||||
.check_stop_free = scsiback_check_stop_free,
|
.check_stop_free = scsiback_check_stop_free,
|
||||||
.release_cmd = scsiback_release_cmd,
|
.release_cmd = scsiback_release_cmd,
|
||||||
.sess_get_index = scsiback_sess_get_index,
|
|
||||||
.sess_get_initiator_sid = NULL,
|
.sess_get_initiator_sid = NULL,
|
||||||
.write_pending = scsiback_write_pending,
|
.write_pending = scsiback_write_pending,
|
||||||
.set_default_node_attributes = scsiback_set_default_node_attrs,
|
|
||||||
.get_cmd_state = scsiback_get_cmd_state,
|
|
||||||
.queue_data_in = scsiback_queue_data_in,
|
.queue_data_in = scsiback_queue_data_in,
|
||||||
.queue_status = scsiback_queue_status,
|
.queue_status = scsiback_queue_status,
|
||||||
.queue_tm_rsp = scsiback_queue_tm_rsp,
|
.queue_tm_rsp = scsiback_queue_tm_rsp,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user