scsi: target: Report and detect unsupported PR commands
The backend modules don't know about ports and I_T nexuses and the pr_ops callouts the modules will use don't support the old RESERVE/RELEASE commands. This patch has us report we don't support those types of commands and fail them. Signed-off-by: Mike Christie <michael.christie@oracle.com> Link: https://lore.kernel.org/r/20230407200551.12660-18-michael.christie@oracle.com Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
d9b3275bdd
commit
8455799d2d
|
@ -3554,6 +3554,18 @@ target_try_pr_out_pt(struct se_cmd *cmd, u8 sa, u64 res_key, u64 sa_res_key,
|
|||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
}
|
||||
|
||||
switch (sa) {
|
||||
case PRO_REGISTER_AND_MOVE:
|
||||
case PRO_REPLACE_LOST_RESERVATION:
|
||||
pr_err("SPC-3 PR: PRO_REGISTER_AND_MOVE and PRO_REPLACE_LOST_RESERVATION are not supported by PR passthrough.\n");
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
}
|
||||
|
||||
if (spec_i_pt || all_tg_pt) {
|
||||
pr_err("SPC-3 PR: SPEC_I_PT and ALL_TG_PT are not supported by PR passthrough.\n");
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
}
|
||||
|
||||
return ops->execute_pr_out(cmd, sa, res_key, sa_res_key, type, aptpl);
|
||||
}
|
||||
|
||||
|
@ -4082,6 +4094,11 @@ static sense_reason_t target_try_pr_in_pt(struct se_cmd *cmd, u8 sa)
|
|||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
}
|
||||
|
||||
if (sa == PRI_READ_FULL_STATUS) {
|
||||
pr_err("SPC-3 PR: PRI_READ_FULL_STATUS is not supported by PR passthrough.\n");
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
}
|
||||
|
||||
buf = transport_kmap_data_sg(cmd);
|
||||
if (!buf)
|
||||
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
|
|
|
@ -1672,7 +1672,41 @@ static bool tcm_is_pr_enabled(struct target_opcode_descriptor *descr,
|
|||
{
|
||||
struct se_device *dev = cmd->se_dev;
|
||||
|
||||
return dev->dev_attrib.emulate_pr;
|
||||
if (!dev->dev_attrib.emulate_pr)
|
||||
return false;
|
||||
|
||||
if (!(dev->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR))
|
||||
return true;
|
||||
|
||||
switch (descr->opcode) {
|
||||
case RESERVE:
|
||||
case RESERVE_10:
|
||||
case RELEASE:
|
||||
case RELEASE_10:
|
||||
/*
|
||||
* The pr_ops which are used by the backend modules don't
|
||||
* support these commands.
|
||||
*/
|
||||
return false;
|
||||
case PERSISTENT_RESERVE_OUT:
|
||||
switch (descr->service_action) {
|
||||
case PRO_REGISTER_AND_MOVE:
|
||||
case PRO_REPLACE_LOST_RESERVATION:
|
||||
/*
|
||||
* The backend modules don't have access to ports and
|
||||
* I_T nexuses so they can't handle these type of
|
||||
* requests.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PERSISTENT_RESERVE_IN:
|
||||
if (descr->service_action == PRI_READ_FULL_STATUS)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_pri_read_caps = {
|
||||
|
@ -1797,22 +1831,13 @@ static struct target_opcode_descriptor tcm_opcode_pro_register_move = {
|
|||
.enabled = tcm_is_pr_enabled,
|
||||
};
|
||||
|
||||
static bool
|
||||
tcm_is_scsi2_reservations_enabled(struct target_opcode_descriptor *descr,
|
||||
struct se_cmd *cmd)
|
||||
{
|
||||
struct se_device *dev = cmd->se_dev;
|
||||
|
||||
return dev->dev_attrib.emulate_pr;
|
||||
}
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_release = {
|
||||
.support = SCSI_SUPPORT_FULL,
|
||||
.opcode = RELEASE,
|
||||
.cdb_size = 6,
|
||||
.usage_bits = {RELEASE, 0x00, 0x00, 0x00,
|
||||
0x00, SCSI_CONTROL_MASK},
|
||||
.enabled = tcm_is_scsi2_reservations_enabled,
|
||||
.enabled = tcm_is_pr_enabled,
|
||||
};
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_release10 = {
|
||||
|
@ -1822,7 +1847,7 @@ static struct target_opcode_descriptor tcm_opcode_release10 = {
|
|||
.usage_bits = {RELEASE_10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0xff, SCSI_CONTROL_MASK},
|
||||
.enabled = tcm_is_scsi2_reservations_enabled,
|
||||
.enabled = tcm_is_pr_enabled,
|
||||
};
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_reserve = {
|
||||
|
@ -1831,7 +1856,7 @@ static struct target_opcode_descriptor tcm_opcode_reserve = {
|
|||
.cdb_size = 6,
|
||||
.usage_bits = {RESERVE, 0x00, 0x00, 0x00,
|
||||
0x00, SCSI_CONTROL_MASK},
|
||||
.enabled = tcm_is_scsi2_reservations_enabled,
|
||||
.enabled = tcm_is_pr_enabled,
|
||||
};
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_reserve10 = {
|
||||
|
@ -1841,7 +1866,7 @@ static struct target_opcode_descriptor tcm_opcode_reserve10 = {
|
|||
.usage_bits = {RESERVE_10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff,
|
||||
0xff, SCSI_CONTROL_MASK},
|
||||
.enabled = tcm_is_scsi2_reservations_enabled,
|
||||
.enabled = tcm_is_pr_enabled,
|
||||
};
|
||||
|
||||
static struct target_opcode_descriptor tcm_opcode_request_sense = {
|
||||
|
@ -2246,12 +2271,22 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
|
|||
struct se_device *dev = cmd->se_dev;
|
||||
unsigned char *cdb = cmd->t_task_cdb;
|
||||
|
||||
if (!dev->dev_attrib.emulate_pr &&
|
||||
((cdb[0] == PERSISTENT_RESERVE_IN) ||
|
||||
(cdb[0] == PERSISTENT_RESERVE_OUT) ||
|
||||
(cdb[0] == RELEASE || cdb[0] == RELEASE_10) ||
|
||||
(cdb[0] == RESERVE || cdb[0] == RESERVE_10))) {
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
switch (cdb[0]) {
|
||||
case RESERVE:
|
||||
case RESERVE_10:
|
||||
case RELEASE:
|
||||
case RELEASE_10:
|
||||
if (!dev->dev_attrib.emulate_pr)
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
|
||||
if (dev->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_PGR)
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
break;
|
||||
case PERSISTENT_RESERVE_IN:
|
||||
case PERSISTENT_RESERVE_OUT:
|
||||
if (!dev->dev_attrib.emulate_pr)
|
||||
return TCM_UNSUPPORTED_SCSI_OPCODE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cdb[0]) {
|
||||
|
|
Loading…
Reference in New Issue