target: pass the se_task to the CDB emulation callback
We want to be able to handle all CDBs through it and remove hacks like always using the first task in a CDB in target_report_luns. Also rename the callback to ->execute_task to better describe its use. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
617c0e06c1
commit
e76a35d6c8
@ -58,8 +58,9 @@ struct t10_alua_lu_gp *default_lu_gp;
|
|||||||
*
|
*
|
||||||
* See spc4r17 section 6.27
|
* See spc4r17 section 6.27
|
||||||
*/
|
*/
|
||||||
int core_emulate_report_target_port_groups(struct se_cmd *cmd)
|
int target_emulate_report_target_port_groups(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
|
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
|
||||||
struct se_port *port;
|
struct se_port *port;
|
||||||
struct t10_alua_tg_pt_gp *tg_pt_gp;
|
struct t10_alua_tg_pt_gp *tg_pt_gp;
|
||||||
@ -172,8 +173,9 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd)
|
|||||||
*
|
*
|
||||||
* See spc4r17 section 6.35
|
* See spc4r17 section 6.35
|
||||||
*/
|
*/
|
||||||
int core_emulate_set_target_port_groups(struct se_cmd *cmd)
|
int target_emulate_set_target_port_groups(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
struct se_device *dev = cmd->se_dev;
|
struct se_device *dev = cmd->se_dev;
|
||||||
struct se_subsystem_dev *su_dev = dev->se_sub_dev;
|
struct se_subsystem_dev *su_dev = dev->se_sub_dev;
|
||||||
struct se_port *port, *l_port = cmd->se_lun->lun_sep;
|
struct se_port *port, *l_port = cmd->se_lun->lun_sep;
|
||||||
|
@ -66,8 +66,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
|
|||||||
extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
|
extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
|
||||||
extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
|
extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
|
||||||
|
|
||||||
extern int core_emulate_report_target_port_groups(struct se_cmd *);
|
extern int target_emulate_report_target_port_groups(struct se_task *);
|
||||||
extern int core_emulate_set_target_port_groups(struct se_cmd *);
|
extern int target_emulate_set_target_port_groups(struct se_task *);
|
||||||
extern int core_alua_check_nonop_delay(struct se_cmd *);
|
extern int core_alua_check_nonop_delay(struct se_cmd *);
|
||||||
extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
|
extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
|
||||||
struct se_device *, struct se_port *,
|
struct se_device *, struct se_port *,
|
||||||
|
@ -651,23 +651,15 @@ void core_dev_unexport(
|
|||||||
lun->lun_se_dev = NULL;
|
lun->lun_se_dev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int transport_core_report_lun_response(struct se_cmd *se_cmd)
|
int target_report_luns(struct se_task *se_task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *se_cmd = se_task->task_se_cmd;
|
||||||
struct se_dev_entry *deve;
|
struct se_dev_entry *deve;
|
||||||
struct se_lun *se_lun;
|
struct se_lun *se_lun;
|
||||||
struct se_session *se_sess = se_cmd->se_sess;
|
struct se_session *se_sess = se_cmd->se_sess;
|
||||||
struct se_task *se_task;
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
|
u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
|
||||||
|
|
||||||
list_for_each_entry(se_task, &se_cmd->t_task_list, t_list)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!se_task) {
|
|
||||||
pr_err("Unable to locate struct se_task for struct se_cmd\n");
|
|
||||||
return PYX_TRANSPORT_LU_COMM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = transport_kmap_first_data_page(se_cmd);
|
buf = transport_kmap_first_data_page(se_cmd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -198,8 +198,9 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int target_scsi2_reservation_release(struct se_cmd *cmd)
|
int target_scsi2_reservation_release(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
struct se_device *dev = cmd->se_dev;
|
struct se_device *dev = cmd->se_dev;
|
||||||
struct se_session *sess = cmd->se_sess;
|
struct se_session *sess = cmd->se_sess;
|
||||||
struct se_portal_group *tpg = sess->se_tpg;
|
struct se_portal_group *tpg = sess->se_tpg;
|
||||||
@ -235,8 +236,9 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int target_scsi2_reservation_reserve(struct se_cmd *cmd)
|
int target_scsi2_reservation_reserve(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
struct se_device *dev = cmd->se_dev;
|
struct se_device *dev = cmd->se_dev;
|
||||||
struct se_session *sess = cmd->se_sess;
|
struct se_session *sess = cmd->se_sess;
|
||||||
struct se_portal_group *tpg = sess->se_tpg;
|
struct se_portal_group *tpg = sess->se_tpg;
|
||||||
@ -3734,8 +3736,9 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
|
|||||||
/*
|
/*
|
||||||
* See spc4r17 section 6.14 Table 170
|
* See spc4r17 section 6.14 Table 170
|
||||||
*/
|
*/
|
||||||
int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
|
int target_scsi3_emulate_pr_out(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
unsigned char *cdb = &cmd->t_task_cdb[0];
|
unsigned char *cdb = &cmd->t_task_cdb[0];
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
u64 res_key, sa_res_key;
|
u64 res_key, sa_res_key;
|
||||||
@ -4203,8 +4206,10 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
|
int target_scsi3_emulate_pr_in(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
struct se_cmd *cmd = task->task_se_cmd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Following spc2r20 5.5.1 Reservations overview:
|
* Following spc2r20 5.5.1 Reservations overview:
|
||||||
*
|
*
|
||||||
|
@ -47,8 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cache;
|
|||||||
|
|
||||||
extern int core_pr_dump_initiator_port(struct t10_pr_registration *,
|
extern int core_pr_dump_initiator_port(struct t10_pr_registration *,
|
||||||
char *, u32);
|
char *, u32);
|
||||||
extern int target_scsi2_reservation_release(struct se_cmd *cmd);
|
extern int target_scsi2_reservation_release(struct se_task *task);
|
||||||
extern int target_scsi2_reservation_reserve(struct se_cmd *cmd);
|
extern int target_scsi2_reservation_reserve(struct se_task *task);
|
||||||
extern int core_scsi3_alloc_aptpl_registration(
|
extern int core_scsi3_alloc_aptpl_registration(
|
||||||
struct t10_reservation *, u64,
|
struct t10_reservation *, u64,
|
||||||
unsigned char *, unsigned char *, u32,
|
unsigned char *, unsigned char *, u32,
|
||||||
@ -63,8 +63,8 @@ extern unsigned char *core_scsi3_pr_dump_type(int);
|
|||||||
extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *,
|
extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *,
|
||||||
struct se_cmd *);
|
struct se_cmd *);
|
||||||
|
|
||||||
extern int target_scsi3_emulate_pr_in(struct se_cmd *cmd);
|
extern int target_scsi3_emulate_pr_in(struct se_task *task);
|
||||||
extern int target_scsi3_emulate_pr_out(struct se_cmd *cmd);
|
extern int target_scsi3_emulate_pr_out(struct se_task *task);
|
||||||
extern int core_setup_reservations(struct se_device *, int);
|
extern int core_setup_reservations(struct se_device *, int);
|
||||||
|
|
||||||
#endif /* TARGET_CORE_PR_H */
|
#endif /* TARGET_CORE_PR_H */
|
||||||
|
@ -2156,12 +2156,12 @@ static int __transport_execute_tasks(struct se_device *dev)
|
|||||||
|
|
||||||
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
||||||
/*
|
/*
|
||||||
* The struct se_cmd->transport_emulate_cdb() function pointer is used
|
* The struct se_cmd->execute_task() function pointer is used
|
||||||
* to grab REPORT_LUNS and other CDBs we want to handle before they hit the
|
* to grab REPORT_LUNS and other CDBs we want to handle before they hit the
|
||||||
* struct se_subsystem_api->do_task() caller below.
|
* struct se_subsystem_api->do_task() caller below.
|
||||||
*/
|
*/
|
||||||
if (cmd->transport_emulate_cdb) {
|
if (cmd->execute_task) {
|
||||||
error = cmd->transport_emulate_cdb(cmd);
|
error = cmd->execute_task(task);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
cmd->transport_error_status = error;
|
cmd->transport_error_status = error;
|
||||||
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
spin_lock_irqsave(&cmd->t_state_lock, flags);
|
||||||
@ -2174,7 +2174,7 @@ static int __transport_execute_tasks(struct se_device *dev)
|
|||||||
goto check_depth;
|
goto check_depth;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Handle the successful completion for transport_emulate_cdb()
|
* Handle the successful completion for execute_task()
|
||||||
* for synchronous operation, following SCF_EMULATE_CDB_ASYNC
|
* for synchronous operation, following SCF_EMULATE_CDB_ASYNC
|
||||||
* Otherwise the caller is expected to complete the task with
|
* Otherwise the caller is expected to complete the task with
|
||||||
* proper status.
|
* proper status.
|
||||||
@ -2795,12 +2795,10 @@ static int transport_generic_cmd_sequencer(
|
|||||||
/*
|
/*
|
||||||
* Check for emulated MI_REPORT_TARGET_PGS.
|
* Check for emulated MI_REPORT_TARGET_PGS.
|
||||||
*/
|
*/
|
||||||
if (cdb[1] == MI_REPORT_TARGET_PGS) {
|
if (cdb[1] == MI_REPORT_TARGET_PGS &&
|
||||||
cmd->transport_emulate_cdb =
|
su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
|
||||||
(su_dev->t10_alua.alua_type ==
|
cmd->execute_task =
|
||||||
SPC3_ALUA_EMULATED) ?
|
target_emulate_report_target_port_groups;
|
||||||
core_emulate_report_target_port_groups :
|
|
||||||
NULL;
|
|
||||||
}
|
}
|
||||||
size = (cdb[6] << 24) | (cdb[7] << 16) |
|
size = (cdb[6] << 24) | (cdb[7] << 16) |
|
||||||
(cdb[8] << 8) | cdb[9];
|
(cdb[8] << 8) | cdb[9];
|
||||||
@ -2843,13 +2841,13 @@ static int transport_generic_cmd_sequencer(
|
|||||||
break;
|
break;
|
||||||
case PERSISTENT_RESERVE_IN:
|
case PERSISTENT_RESERVE_IN:
|
||||||
if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
|
if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
|
||||||
cmd->transport_emulate_cdb = target_scsi3_emulate_pr_in;
|
cmd->execute_task = target_scsi3_emulate_pr_in;
|
||||||
size = (cdb[7] << 8) + cdb[8];
|
size = (cdb[7] << 8) + cdb[8];
|
||||||
cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
|
||||||
break;
|
break;
|
||||||
case PERSISTENT_RESERVE_OUT:
|
case PERSISTENT_RESERVE_OUT:
|
||||||
if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
|
if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
|
||||||
cmd->transport_emulate_cdb = target_scsi3_emulate_pr_out;
|
cmd->execute_task = target_scsi3_emulate_pr_out;
|
||||||
size = (cdb[7] << 8) + cdb[8];
|
size = (cdb[7] << 8) + cdb[8];
|
||||||
cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
|
||||||
break;
|
break;
|
||||||
@ -2868,12 +2866,10 @@ static int transport_generic_cmd_sequencer(
|
|||||||
*
|
*
|
||||||
* Check for emulated MO_SET_TARGET_PGS.
|
* Check for emulated MO_SET_TARGET_PGS.
|
||||||
*/
|
*/
|
||||||
if (cdb[1] == MO_SET_TARGET_PGS) {
|
if (cdb[1] == MO_SET_TARGET_PGS &&
|
||||||
cmd->transport_emulate_cdb =
|
su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
|
||||||
(su_dev->t10_alua.alua_type ==
|
cmd->execute_task =
|
||||||
SPC3_ALUA_EMULATED) ?
|
target_emulate_set_target_port_groups;
|
||||||
core_emulate_set_target_port_groups :
|
|
||||||
NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (cdb[6] << 24) | (cdb[7] << 16) |
|
size = (cdb[6] << 24) | (cdb[7] << 16) |
|
||||||
@ -2966,10 +2962,8 @@ static int transport_generic_cmd_sequencer(
|
|||||||
* is running in SPC_PASSTHROUGH, and wants reservations
|
* is running in SPC_PASSTHROUGH, and wants reservations
|
||||||
* emulation disabled.
|
* emulation disabled.
|
||||||
*/
|
*/
|
||||||
if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) {
|
if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
|
||||||
cmd->transport_emulate_cdb =
|
cmd->execute_task = target_scsi2_reservation_reserve;
|
||||||
target_scsi2_reservation_reserve;
|
|
||||||
}
|
|
||||||
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
||||||
break;
|
break;
|
||||||
case RELEASE:
|
case RELEASE:
|
||||||
@ -2983,10 +2977,8 @@ static int transport_generic_cmd_sequencer(
|
|||||||
else
|
else
|
||||||
size = cmd->data_length;
|
size = cmd->data_length;
|
||||||
|
|
||||||
if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH) {
|
if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
|
||||||
cmd->transport_emulate_cdb =
|
cmd->execute_task = target_scsi2_reservation_release;
|
||||||
target_scsi2_reservation_release;
|
|
||||||
}
|
|
||||||
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
||||||
break;
|
break;
|
||||||
case SYNCHRONIZE_CACHE:
|
case SYNCHRONIZE_CACHE:
|
||||||
@ -3007,9 +2999,6 @@ static int transport_generic_cmd_sequencer(
|
|||||||
size = transport_get_size(sectors, cdb, cmd);
|
size = transport_get_size(sectors, cdb, cmd);
|
||||||
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
||||||
|
|
||||||
/*
|
|
||||||
* For TCM/pSCSI passthrough, skip cmd->transport_emulate_cdb()
|
|
||||||
*/
|
|
||||||
if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
|
if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
@ -3086,8 +3075,7 @@ static int transport_generic_cmd_sequencer(
|
|||||||
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
|
||||||
break;
|
break;
|
||||||
case REPORT_LUNS:
|
case REPORT_LUNS:
|
||||||
cmd->transport_emulate_cdb =
|
cmd->execute_task = target_report_luns;
|
||||||
transport_core_report_lun_response;
|
|
||||||
size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
|
size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
|
||||||
/*
|
/*
|
||||||
* Do implict HEAD_OF_QUEUE processing for REPORT_LUNS
|
* Do implict HEAD_OF_QUEUE processing for REPORT_LUNS
|
||||||
|
@ -457,7 +457,7 @@ struct se_cmd {
|
|||||||
struct list_head se_cmd_list;
|
struct list_head se_cmd_list;
|
||||||
struct completion cmd_wait_comp;
|
struct completion cmd_wait_comp;
|
||||||
struct target_core_fabric_ops *se_tfo;
|
struct target_core_fabric_ops *se_tfo;
|
||||||
int (*transport_emulate_cdb)(struct se_cmd *);
|
int (*execute_task)(struct se_task *);
|
||||||
void (*transport_complete_callback)(struct se_cmd *);
|
void (*transport_complete_callback)(struct se_cmd *);
|
||||||
|
|
||||||
unsigned char *t_task_cdb;
|
unsigned char *t_task_cdb;
|
||||||
|
@ -17,7 +17,7 @@ extern int core_dev_export(struct se_device *, struct se_portal_group *,
|
|||||||
struct se_lun *);
|
struct se_lun *);
|
||||||
extern void core_dev_unexport(struct se_device *, struct se_portal_group *,
|
extern void core_dev_unexport(struct se_device *, struct se_portal_group *,
|
||||||
struct se_lun *);
|
struct se_lun *);
|
||||||
extern int transport_core_report_lun_response(struct se_cmd *);
|
extern int target_report_luns(struct se_task *);
|
||||||
extern void se_release_device_for_hba(struct se_device *);
|
extern void se_release_device_for_hba(struct se_device *);
|
||||||
extern void se_release_vpd_for_dev(struct se_device *);
|
extern void se_release_vpd_for_dev(struct se_device *);
|
||||||
extern void se_clear_dev_ports(struct se_device *);
|
extern void se_clear_dev_ports(struct se_device *);
|
||||||
|
Loading…
Reference in New Issue
Block a user