Skip to content

Commit 070ec6f

Browse files
stefanhaRHmartinkpetersen
authored andcommitted
scsi: target: Don't validate ignored fields in PROUT PREEMPT
The PERSISTENT RESERVE OUT command's PREEMPT service action provides two different functions: 1. preempting persistent reservations and 2. removing registrations. In the latter case the spec says: b) ignore the contents of the SCOPE field and the TYPE field; The code currently validates the SCOPE and TYPE fields even when PREEMPT is called to remove registrations. This patch achieves spec compliance by validating the SCOPE and TYPE fields only when they will actually be used. To confirm my interpretation of the specification I tested against HPE 3PAR storage and found the TYPE field is indeed ignored in this case. Cc: Maurizio Lombardi <mlombard@redhat.com> Cc: Dmitry Bogdanov <d.bogdanov@yadro.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Link: https://patch.msgid.link/20260402180342.126583-1-stefanha@redhat.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 271aeff commit 070ec6f

1 file changed

Lines changed: 32 additions & 27 deletions

File tree

drivers/target/target_core_pr.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,7 +2809,7 @@ static void core_scsi3_release_preempt_and_abort(
28092809
}
28102810

28112811
static sense_reason_t
2812-
core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
2812+
core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
28132813
u64 sa_res_key, enum preempt_type preempt_type)
28142814
{
28152815
struct se_device *dev = cmd->se_dev;
@@ -2838,11 +2838,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
28382838
core_scsi3_put_pr_reg(pr_reg_n);
28392839
return TCM_RESERVATION_CONFLICT;
28402840
}
2841-
if (scope != PR_SCOPE_LU_SCOPE) {
2842-
pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
2843-
core_scsi3_put_pr_reg(pr_reg_n);
2844-
return TCM_INVALID_PARAMETER_LIST;
2845-
}
28462841

28472842
spin_lock(&dev->dev_reservation_lock);
28482843
pr_res_holder = dev->dev_pr_res_holder;
@@ -2856,6 +2851,37 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
28562851
core_scsi3_put_pr_reg(pr_reg_n);
28572852
return TCM_INVALID_PARAMETER_LIST;
28582853
}
2854+
2855+
/* Validate TYPE and SCOPE fields if they will be used */
2856+
if (pr_res_holder &&
2857+
(pr_res_holder->pr_res_key == sa_res_key ||
2858+
(all_reg && !sa_res_key))) {
2859+
switch (type) {
2860+
case PR_TYPE_WRITE_EXCLUSIVE:
2861+
case PR_TYPE_EXCLUSIVE_ACCESS:
2862+
case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
2863+
case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
2864+
case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
2865+
case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
2866+
break;
2867+
default:
2868+
pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
2869+
" Type: 0x%02x\n",
2870+
(preempt_type == PREEMPT_AND_ABORT) ?
2871+
"_AND_ABORT" : "", type);
2872+
spin_unlock(&dev->dev_reservation_lock);
2873+
core_scsi3_put_pr_reg(pr_reg_n);
2874+
return TCM_INVALID_CDB_FIELD;
2875+
}
2876+
2877+
if (scope != PR_SCOPE_LU_SCOPE) {
2878+
pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
2879+
spin_unlock(&dev->dev_reservation_lock);
2880+
core_scsi3_put_pr_reg(pr_reg_n);
2881+
return TCM_INVALID_PARAMETER_LIST;
2882+
}
2883+
}
2884+
28592885
/*
28602886
* From spc4r17, section 5.7.11.4.4 Removing Registrations:
28612887
*
@@ -3118,27 +3144,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
31183144
return 0;
31193145
}
31203146

3121-
static sense_reason_t
3122-
core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope,
3123-
u64 res_key, u64 sa_res_key, enum preempt_type preempt_type)
3124-
{
3125-
switch (type) {
3126-
case PR_TYPE_WRITE_EXCLUSIVE:
3127-
case PR_TYPE_EXCLUSIVE_ACCESS:
3128-
case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
3129-
case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
3130-
case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
3131-
case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
3132-
return core_scsi3_pro_preempt(cmd, type, scope, res_key,
3133-
sa_res_key, preempt_type);
3134-
default:
3135-
pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
3136-
" Type: 0x%02x\n", (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", type);
3137-
return TCM_INVALID_CDB_FIELD;
3138-
}
3139-
}
3140-
3141-
31423147
static sense_reason_t
31433148
core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
31443149
u64 sa_res_key, int aptpl, int unreg)

0 commit comments

Comments
 (0)