Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Stefan Hajnoczi and committed by
Martin K. Petersen
070ec6f6 271aeff2

+32 -27
+32 -27
drivers/target/target_core_pr.c
··· 2809 2809 } 2810 2810 2811 2811 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, 2813 2813 u64 sa_res_key, enum preempt_type preempt_type) 2814 2814 { 2815 2815 struct se_device *dev = cmd->se_dev; ··· 2838 2838 core_scsi3_put_pr_reg(pr_reg_n); 2839 2839 return TCM_RESERVATION_CONFLICT; 2840 2840 } 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 - } 2846 2841 2847 2842 spin_lock(&dev->dev_reservation_lock); 2848 2843 pr_res_holder = dev->dev_pr_res_holder; ··· 2851 2856 core_scsi3_put_pr_reg(pr_reg_n); 2852 2857 return TCM_INVALID_PARAMETER_LIST; 2853 2858 } 2859 + 2860 + /* Validate TYPE and SCOPE fields if they will be used */ 2861 + if (pr_res_holder && 2862 + (pr_res_holder->pr_res_key == sa_res_key || 2863 + (all_reg && !sa_res_key))) { 2864 + switch (type) { 2865 + case PR_TYPE_WRITE_EXCLUSIVE: 2866 + case PR_TYPE_EXCLUSIVE_ACCESS: 2867 + case PR_TYPE_WRITE_EXCLUSIVE_REGONLY: 2868 + case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: 2869 + case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: 2870 + case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: 2871 + break; 2872 + default: 2873 + pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" 2874 + " Type: 0x%02x\n", 2875 + (preempt_type == PREEMPT_AND_ABORT) ? 2876 + "_AND_ABORT" : "", type); 2877 + spin_unlock(&dev->dev_reservation_lock); 2878 + core_scsi3_put_pr_reg(pr_reg_n); 2879 + return TCM_INVALID_CDB_FIELD; 2880 + } 2881 + 2882 + if (scope != PR_SCOPE_LU_SCOPE) { 2883 + pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); 2884 + spin_unlock(&dev->dev_reservation_lock); 2885 + core_scsi3_put_pr_reg(pr_reg_n); 2886 + return TCM_INVALID_PARAMETER_LIST; 2887 + } 2888 + } 2889 + 2854 2890 /* 2855 2891 * From spc4r17, section 5.7.11.4.4 Removing Registrations: 2856 2892 * ··· 3143 3117 core_scsi3_pr_generation(cmd->se_dev); 3144 3118 return 0; 3145 3119 } 3146 - 3147 - static sense_reason_t 3148 - core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, 3149 - u64 res_key, u64 sa_res_key, enum preempt_type preempt_type) 3150 - { 3151 - switch (type) { 3152 - case PR_TYPE_WRITE_EXCLUSIVE: 3153 - case PR_TYPE_EXCLUSIVE_ACCESS: 3154 - case PR_TYPE_WRITE_EXCLUSIVE_REGONLY: 3155 - case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY: 3156 - case PR_TYPE_WRITE_EXCLUSIVE_ALLREG: 3157 - case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG: 3158 - return core_scsi3_pro_preempt(cmd, type, scope, res_key, 3159 - sa_res_key, preempt_type); 3160 - default: 3161 - pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" 3162 - " Type: 0x%02x\n", (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "", type); 3163 - return TCM_INVALID_CDB_FIELD; 3164 - } 3165 - } 3166 - 3167 3120 3168 3121 static sense_reason_t 3169 3122 core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,