Commit fe83558a33f509277aa07566d484096cc7149807
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Merge branch '3.3-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull target fixes from Nicholas Bellinger: "This series addresses two recently reported regression bugs related to legacy SCSI reservation usage in target core, and iscsi-target reservation conflict handling. The second patch in particular addresses possible data-corruption with SCSI reservations that is specific to iscsi-target fabric LUNs with multiple client writers. Both patches need to go into v3.2 stable ASAP, and the branch based on the last target-pending/3.3-rc-fixes HEAD. Again, thanks to Martin Svec for his help to identify and address this regression bug with iscsi-target." * '3.3-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: iscsi-target: Fix reservation conflict -EBUSY response handling bug target: Fix compatible reservation handling (CRH=1) with legacy RESERVE/RELEASE
Showing 3 changed files Side-by-side Diff
drivers/target/iscsi/iscsi_target.c
... | ... | @@ -1028,7 +1028,7 @@ |
1028 | 1028 | return iscsit_add_reject_from_cmd( |
1029 | 1029 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1030 | 1030 | 1, 1, buf, cmd); |
1031 | - } else if (transport_ret == -EINVAL) { | |
1031 | + } else if (transport_ret < 0) { | |
1032 | 1032 | /* |
1033 | 1033 | * Unsupported SAM Opcode. CHECK_CONDITION will be sent |
1034 | 1034 | * in iscsit_execute_cmd() during the CmdSN OOO Execution |
drivers/target/target_core_pr.c
... | ... | @@ -117,7 +117,7 @@ |
117 | 117 | struct se_node_acl *, struct se_session *); |
118 | 118 | static void core_scsi3_put_pr_reg(struct t10_pr_registration *); |
119 | 119 | |
120 | -static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |
120 | +static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | |
121 | 121 | { |
122 | 122 | struct se_session *se_sess = cmd->se_sess; |
123 | 123 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; |
... | ... | @@ -127,7 +127,7 @@ |
127 | 127 | int conflict = 0; |
128 | 128 | |
129 | 129 | if (!crh) |
130 | - return false; | |
130 | + return -EINVAL; | |
131 | 131 | |
132 | 132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
133 | 133 | se_sess); |
134 | 134 | |
... | ... | @@ -155,16 +155,14 @@ |
155 | 155 | */ |
156 | 156 | if (pr_reg->pr_res_holder) { |
157 | 157 | core_scsi3_put_pr_reg(pr_reg); |
158 | - *ret = 0; | |
159 | - return false; | |
158 | + return 1; | |
160 | 159 | } |
161 | 160 | if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || |
162 | 161 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || |
163 | 162 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
164 | 163 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { |
165 | 164 | core_scsi3_put_pr_reg(pr_reg); |
166 | - *ret = 0; | |
167 | - return true; | |
165 | + return 1; | |
168 | 166 | } |
169 | 167 | core_scsi3_put_pr_reg(pr_reg); |
170 | 168 | conflict = 1; |
171 | 169 | |
... | ... | @@ -189,10 +187,10 @@ |
189 | 187 | " while active SPC-3 registrations exist," |
190 | 188 | " returning RESERVATION_CONFLICT\n"); |
191 | 189 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
192 | - return true; | |
190 | + return -EBUSY; | |
193 | 191 | } |
194 | 192 | |
195 | - return false; | |
193 | + return 0; | |
196 | 194 | } |
197 | 195 | |
198 | 196 | int target_scsi2_reservation_release(struct se_task *task) |
199 | 197 | |
200 | 198 | |
... | ... | @@ -201,12 +199,18 @@ |
201 | 199 | struct se_device *dev = cmd->se_dev; |
202 | 200 | struct se_session *sess = cmd->se_sess; |
203 | 201 | struct se_portal_group *tpg = sess->se_tpg; |
204 | - int ret = 0; | |
202 | + int ret = 0, rc; | |
205 | 203 | |
206 | 204 | if (!sess || !tpg) |
207 | 205 | goto out; |
208 | - if (target_check_scsi2_reservation_conflict(cmd, &ret)) | |
206 | + rc = target_check_scsi2_reservation_conflict(cmd); | |
207 | + if (rc == 1) | |
209 | 208 | goto out; |
209 | + else if (rc < 0) { | |
210 | + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | |
211 | + ret = -EINVAL; | |
212 | + goto out; | |
213 | + } | |
210 | 214 | |
211 | 215 | ret = 0; |
212 | 216 | spin_lock(&dev->dev_reservation_lock); |
... | ... | @@ -243,7 +247,7 @@ |
243 | 247 | struct se_device *dev = cmd->se_dev; |
244 | 248 | struct se_session *sess = cmd->se_sess; |
245 | 249 | struct se_portal_group *tpg = sess->se_tpg; |
246 | - int ret = 0; | |
250 | + int ret = 0, rc; | |
247 | 251 | |
248 | 252 | if ((cmd->t_task_cdb[1] & 0x01) && |
249 | 253 | (cmd->t_task_cdb[1] & 0x02)) { |
250 | 254 | |
... | ... | @@ -259,8 +263,14 @@ |
259 | 263 | */ |
260 | 264 | if (!sess || !tpg) |
261 | 265 | goto out; |
262 | - if (target_check_scsi2_reservation_conflict(cmd, &ret)) | |
266 | + rc = target_check_scsi2_reservation_conflict(cmd); | |
267 | + if (rc == 1) | |
263 | 268 | goto out; |
269 | + else if (rc < 0) { | |
270 | + cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | |
271 | + ret = -EINVAL; | |
272 | + goto out; | |
273 | + } | |
264 | 274 | |
265 | 275 | ret = 0; |
266 | 276 | spin_lock(&dev->dev_reservation_lock); |
drivers/target/target_core_transport.c
... | ... | @@ -2539,6 +2539,7 @@ |
2539 | 2539 | cmd, cdb, pr_reg_type) != 0) { |
2540 | 2540 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
2541 | 2541 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; |
2542 | + cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | |
2542 | 2543 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2543 | 2544 | return -EBUSY; |
2544 | 2545 | } |