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.chris...@oracle.com>
---
 drivers/target/target_core_pr.c  | 17 ++++++++
 drivers/target/target_core_spc.c | 75 +++++++++++++++++++++++---------
 2 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index e16ef7d676af..7a3f07979a02 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -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;
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index caf8d1325007..053bd2eea0e6 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -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]) {
-- 
2.25.1

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to