diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-11-03 17:50:44 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-11-04 06:43:35 -0400 |
commit | d29a5b6acc4b63d4e05ff554509df6fbeaf527cd (patch) | |
tree | edd94dc0420982dea35a811827757b3145689df0 /drivers/target | |
parent | 6ed5a557905f1c4e9ca5f8a6d607303a12d097e1 (diff) |
target: remove SCF_EMULATE_CDB_ASYNC
All ->execute_task instances now need to complete the I/O explicitly,
which can either happen synchronously or asynchronously.
Note that a lot of the CDB emulations appear to return success even if
some lowlevel operations failed. Given that this is an existing issue
this patch doesn't change that fact.
(nab: Adding missing switch breaks in PR-IN + PR_OUT)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_alua.c | 5 | ||||
-rw-r--r-- | drivers/target/target_core_cdb.c | 58 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 129 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 47 |
5 files changed, 142 insertions, 99 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 14668d05ea0d..2739b93983a2 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -165,6 +165,8 @@ int target_emulate_report_target_port_groups(struct se_task *task) | |||
165 | 165 | ||
166 | transport_kunmap_first_data_page(cmd); | 166 | transport_kunmap_first_data_page(cmd); |
167 | 167 | ||
168 | task->task_scsi_status = GOOD; | ||
169 | transport_complete_task(task, 1); | ||
168 | return 0; | 170 | return 0; |
169 | } | 171 | } |
170 | 172 | ||
@@ -343,7 +345,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
343 | 345 | ||
344 | out: | 346 | out: |
345 | transport_kunmap_first_data_page(cmd); | 347 | transport_kunmap_first_data_page(cmd); |
346 | 348 | task->task_scsi_status = GOOD; | |
349 | transport_complete_task(task, 1); | ||
347 | return 0; | 350 | return 0; |
348 | } | 351 | } |
349 | 352 | ||
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index ff2dfa383735..5a03085304e5 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -688,8 +688,10 @@ target_emulate_inquiry(struct se_task *task) | |||
688 | unsigned char *cdb = cmd->t_task_cdb; | 688 | unsigned char *cdb = cmd->t_task_cdb; |
689 | int p, ret; | 689 | int p, ret; |
690 | 690 | ||
691 | if (!(cdb[1] & 0x1)) | 691 | if (!(cdb[1] & 0x1)) { |
692 | return target_emulate_inquiry_std(cmd); | 692 | ret = target_emulate_inquiry_std(cmd); |
693 | goto out; | ||
694 | } | ||
693 | 695 | ||
694 | /* | 696 | /* |
695 | * Make sure we at least have 4 bytes of INQUIRY response | 697 | * Make sure we at least have 4 bytes of INQUIRY response |
@@ -708,17 +710,25 @@ target_emulate_inquiry(struct se_task *task) | |||
708 | 710 | ||
709 | buf[0] = dev->transport->get_device_type(dev); | 711 | buf[0] = dev->transport->get_device_type(dev); |
710 | 712 | ||
711 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) | 713 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { |
712 | if (cdb[2] == evpd_handlers[p].page) { | 714 | if (cdb[2] == evpd_handlers[p].page) { |
713 | buf[1] = cdb[2]; | 715 | buf[1] = cdb[2]; |
714 | ret = evpd_handlers[p].emulate(cmd, buf); | 716 | ret = evpd_handlers[p].emulate(cmd, buf); |
715 | transport_kunmap_first_data_page(cmd); | 717 | goto out_unmap; |
716 | return ret; | ||
717 | } | 718 | } |
719 | } | ||
718 | 720 | ||
719 | transport_kunmap_first_data_page(cmd); | ||
720 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 721 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
721 | return -EINVAL; | 722 | ret = -EINVAL; |
723 | |||
724 | out_unmap: | ||
725 | transport_kunmap_first_data_page(cmd); | ||
726 | out: | ||
727 | if (!ret) { | ||
728 | task->task_scsi_status = GOOD; | ||
729 | transport_complete_task(task, 1); | ||
730 | } | ||
731 | return ret; | ||
722 | } | 732 | } |
723 | 733 | ||
724 | static int | 734 | static int |
@@ -753,6 +763,8 @@ target_emulate_readcapacity(struct se_task *task) | |||
753 | 763 | ||
754 | transport_kunmap_first_data_page(cmd); | 764 | transport_kunmap_first_data_page(cmd); |
755 | 765 | ||
766 | task->task_scsi_status = GOOD; | ||
767 | transport_complete_task(task, 1); | ||
756 | return 0; | 768 | return 0; |
757 | } | 769 | } |
758 | 770 | ||
@@ -787,6 +799,8 @@ target_emulate_readcapacity_16(struct se_task *task) | |||
787 | 799 | ||
788 | transport_kunmap_first_data_page(cmd); | 800 | transport_kunmap_first_data_page(cmd); |
789 | 801 | ||
802 | task->task_scsi_status = GOOD; | ||
803 | transport_complete_task(task, 1); | ||
790 | return 0; | 804 | return 0; |
791 | } | 805 | } |
792 | 806 | ||
@@ -1000,6 +1014,8 @@ target_emulate_modesense(struct se_task *task) | |||
1000 | memcpy(rbuf, buf, offset); | 1014 | memcpy(rbuf, buf, offset); |
1001 | transport_kunmap_first_data_page(cmd); | 1015 | transport_kunmap_first_data_page(cmd); |
1002 | 1016 | ||
1017 | task->task_scsi_status = GOOD; | ||
1018 | transport_complete_task(task, 1); | ||
1003 | return 0; | 1019 | return 0; |
1004 | } | 1020 | } |
1005 | 1021 | ||
@@ -1065,7 +1081,8 @@ target_emulate_request_sense(struct se_task *task) | |||
1065 | 1081 | ||
1066 | end: | 1082 | end: |
1067 | transport_kunmap_first_data_page(cmd); | 1083 | transport_kunmap_first_data_page(cmd); |
1068 | 1084 | task->task_scsi_status = GOOD; | |
1085 | transport_complete_task(task, 1); | ||
1069 | return 0; | 1086 | return 0; |
1070 | } | 1087 | } |
1071 | 1088 | ||
@@ -1122,7 +1139,10 @@ target_emulate_unmap(struct se_task *task) | |||
1122 | 1139 | ||
1123 | err: | 1140 | err: |
1124 | transport_kunmap_first_data_page(cmd); | 1141 | transport_kunmap_first_data_page(cmd); |
1125 | 1142 | if (!ret) { | |
1143 | task->task_scsi_status = GOOD; | ||
1144 | transport_complete_task(task, 1); | ||
1145 | } | ||
1126 | return ret; | 1146 | return ret; |
1127 | } | 1147 | } |
1128 | 1148 | ||
@@ -1171,6 +1191,8 @@ target_emulate_write_same(struct se_task *task) | |||
1171 | return ret; | 1191 | return ret; |
1172 | } | 1192 | } |
1173 | 1193 | ||
1194 | task->task_scsi_status = GOOD; | ||
1195 | transport_complete_task(task, 1); | ||
1174 | return 0; | 1196 | return 0; |
1175 | } | 1197 | } |
1176 | 1198 | ||
@@ -1189,6 +1211,14 @@ target_emulate_synchronize_cache(struct se_task *task) | |||
1189 | return 0; | 1211 | return 0; |
1190 | } | 1212 | } |
1191 | 1213 | ||
1214 | static int | ||
1215 | target_emulate_noop(struct se_task *task) | ||
1216 | { | ||
1217 | task->task_scsi_status = GOOD; | ||
1218 | transport_complete_task(task, 1); | ||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1192 | int | 1222 | int |
1193 | transport_emulate_control_cdb(struct se_task *task) | 1223 | transport_emulate_control_cdb(struct se_task *task) |
1194 | { | 1224 | { |
@@ -1259,6 +1289,7 @@ transport_emulate_control_cdb(struct se_task *task) | |||
1259 | case TEST_UNIT_READY: | 1289 | case TEST_UNIT_READY: |
1260 | case VERIFY: | 1290 | case VERIFY: |
1261 | case WRITE_FILEMARKS: | 1291 | case WRITE_FILEMARKS: |
1292 | ret = target_emulate_noop(task); | ||
1262 | break; | 1293 | break; |
1263 | default: | 1294 | default: |
1264 | pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n", | 1295 | pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n", |
@@ -1268,15 +1299,6 @@ transport_emulate_control_cdb(struct se_task *task) | |||
1268 | 1299 | ||
1269 | if (ret < 0) | 1300 | if (ret < 0) |
1270 | return ret; | 1301 | return ret; |
1271 | /* | ||
1272 | * Handle the successful completion here unless a caller | ||
1273 | * has explictly requested an asychronous completion. | ||
1274 | */ | ||
1275 | if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) { | ||
1276 | task->task_scsi_status = GOOD; | ||
1277 | transport_complete_task(task, 1); | ||
1278 | } | ||
1279 | |||
1280 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 1302 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; |
1281 | } | 1303 | } |
1282 | 1304 | ||
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index ffbb1d6532e9..28d2c808c56b 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -705,6 +705,8 @@ done: | |||
705 | buf[2] = ((lun_count >> 8) & 0xff); | 705 | buf[2] = ((lun_count >> 8) & 0xff); |
706 | buf[3] = (lun_count & 0xff); | 706 | buf[3] = (lun_count & 0xff); |
707 | 707 | ||
708 | se_task->task_scsi_status = GOOD; | ||
709 | transport_complete_task(se_task, 1); | ||
708 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 710 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; |
709 | } | 711 | } |
710 | 712 | ||
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 09e1e3e896c6..5a4ebfc3a54f 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -204,23 +204,21 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
204 | struct se_device *dev = cmd->se_dev; | 204 | struct se_device *dev = cmd->se_dev; |
205 | struct se_session *sess = cmd->se_sess; | 205 | struct se_session *sess = cmd->se_sess; |
206 | struct se_portal_group *tpg = sess->se_tpg; | 206 | struct se_portal_group *tpg = sess->se_tpg; |
207 | int ret; | 207 | int ret = 0; |
208 | 208 | ||
209 | if (!sess || !tpg) | 209 | if (!sess || !tpg) |
210 | return 0; | 210 | goto out; |
211 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 211 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) |
212 | return ret; | 212 | goto out; |
213 | 213 | ||
214 | ret = 0; | ||
214 | spin_lock(&dev->dev_reservation_lock); | 215 | spin_lock(&dev->dev_reservation_lock); |
215 | if (!dev->dev_reserved_node_acl || !sess) { | 216 | if (!dev->dev_reserved_node_acl || !sess) |
216 | spin_unlock(&dev->dev_reservation_lock); | 217 | goto out_unlock; |
217 | return 0; | 218 | |
218 | } | 219 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
220 | goto out_unlock; | ||
219 | 221 | ||
220 | if (dev->dev_reserved_node_acl != sess->se_node_acl) { | ||
221 | spin_unlock(&dev->dev_reservation_lock); | ||
222 | return 0; | ||
223 | } | ||
224 | dev->dev_reserved_node_acl = NULL; | 222 | dev->dev_reserved_node_acl = NULL; |
225 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; | 223 | dev->dev_flags &= ~DF_SPC2_RESERVATIONS; |
226 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { | 224 | if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) { |
@@ -231,9 +229,15 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
231 | " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 229 | " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
232 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, | 230 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, |
233 | sess->se_node_acl->initiatorname); | 231 | sess->se_node_acl->initiatorname); |
234 | spin_unlock(&dev->dev_reservation_lock); | ||
235 | 232 | ||
236 | return 0; | 233 | out_unlock: |
234 | spin_unlock(&dev->dev_reservation_lock); | ||
235 | out: | ||
236 | if (!ret) { | ||
237 | task->task_scsi_status = GOOD; | ||
238 | transport_complete_task(task, 1); | ||
239 | } | ||
240 | return ret; | ||
237 | } | 241 | } |
238 | 242 | ||
239 | int target_scsi2_reservation_reserve(struct se_task *task) | 243 | int target_scsi2_reservation_reserve(struct se_task *task) |
@@ -242,23 +246,25 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
242 | struct se_device *dev = cmd->se_dev; | 246 | struct se_device *dev = cmd->se_dev; |
243 | struct se_session *sess = cmd->se_sess; | 247 | struct se_session *sess = cmd->se_sess; |
244 | struct se_portal_group *tpg = sess->se_tpg; | 248 | struct se_portal_group *tpg = sess->se_tpg; |
245 | int ret; | 249 | int ret = 0; |
246 | 250 | ||
247 | if ((cmd->t_task_cdb[1] & 0x01) && | 251 | if ((cmd->t_task_cdb[1] & 0x01) && |
248 | (cmd->t_task_cdb[1] & 0x02)) { | 252 | (cmd->t_task_cdb[1] & 0x02)) { |
249 | pr_err("LongIO and Obselete Bits set, returning" | 253 | pr_err("LongIO and Obselete Bits set, returning" |
250 | " ILLEGAL_REQUEST\n"); | 254 | " ILLEGAL_REQUEST\n"); |
251 | return PYX_TRANSPORT_ILLEGAL_REQUEST; | 255 | ret = PYX_TRANSPORT_ILLEGAL_REQUEST; |
256 | goto out; | ||
252 | } | 257 | } |
253 | /* | 258 | /* |
254 | * This is currently the case for target_core_mod passthrough struct se_cmd | 259 | * This is currently the case for target_core_mod passthrough struct se_cmd |
255 | * ops | 260 | * ops |
256 | */ | 261 | */ |
257 | if (!sess || !tpg) | 262 | if (!sess || !tpg) |
258 | return 0; | 263 | goto out; |
259 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 264 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) |
260 | return ret; | 265 | goto out; |
261 | 266 | ||
267 | ret = 0; | ||
262 | spin_lock(&dev->dev_reservation_lock); | 268 | spin_lock(&dev->dev_reservation_lock); |
263 | if (dev->dev_reserved_node_acl && | 269 | if (dev->dev_reserved_node_acl && |
264 | (dev->dev_reserved_node_acl != sess->se_node_acl)) { | 270 | (dev->dev_reserved_node_acl != sess->se_node_acl)) { |
@@ -271,8 +277,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
271 | " from %s \n", cmd->se_lun->unpacked_lun, | 277 | " from %s \n", cmd->se_lun->unpacked_lun, |
272 | cmd->se_deve->mapped_lun, | 278 | cmd->se_deve->mapped_lun, |
273 | sess->se_node_acl->initiatorname); | 279 | sess->se_node_acl->initiatorname); |
274 | spin_unlock(&dev->dev_reservation_lock); | 280 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; |
275 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 281 | goto out_unlock; |
276 | } | 282 | } |
277 | 283 | ||
278 | dev->dev_reserved_node_acl = sess->se_node_acl; | 284 | dev->dev_reserved_node_acl = sess->se_node_acl; |
@@ -285,9 +291,15 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
285 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 291 | " for %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
286 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, | 292 | cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun, |
287 | sess->se_node_acl->initiatorname); | 293 | sess->se_node_acl->initiatorname); |
288 | spin_unlock(&dev->dev_reservation_lock); | ||
289 | 294 | ||
290 | return 0; | 295 | out_unlock: |
296 | spin_unlock(&dev->dev_reservation_lock); | ||
297 | out: | ||
298 | if (!ret) { | ||
299 | task->task_scsi_status = GOOD; | ||
300 | transport_complete_task(task, 1); | ||
301 | } | ||
302 | return ret; | ||
291 | } | 303 | } |
292 | 304 | ||
293 | 305 | ||
@@ -3744,6 +3756,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3744 | u64 res_key, sa_res_key; | 3756 | u64 res_key, sa_res_key; |
3745 | int sa, scope, type, aptpl; | 3757 | int sa, scope, type, aptpl; |
3746 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; | 3758 | int spec_i_pt = 0, all_tg_pt = 0, unreg = 0; |
3759 | int ret; | ||
3747 | 3760 | ||
3748 | /* | 3761 | /* |
3749 | * Following spc2r20 5.5.1 Reservations overview: | 3762 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -3758,7 +3771,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3758 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3771 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
3759 | " SPC-2 reservation is held, returning" | 3772 | " SPC-2 reservation is held, returning" |
3760 | " RESERVATION_CONFLICT\n"); | 3773 | " RESERVATION_CONFLICT\n"); |
3761 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3774 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; |
3775 | goto out; | ||
3762 | } | 3776 | } |
3763 | 3777 | ||
3764 | /* | 3778 | /* |
@@ -3771,7 +3785,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3771 | if (cmd->data_length < 24) { | 3785 | if (cmd->data_length < 24) { |
3772 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3786 | pr_warn("SPC-PR: Received PR OUT parameter list" |
3773 | " length too small: %u\n", cmd->data_length); | 3787 | " length too small: %u\n", cmd->data_length); |
3774 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3788 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
3789 | goto out; | ||
3775 | } | 3790 | } |
3776 | /* | 3791 | /* |
3777 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) | 3792 | * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB) |
@@ -3804,8 +3819,11 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3804 | /* | 3819 | /* |
3805 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3820 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
3806 | */ | 3821 | */ |
3807 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) | 3822 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { |
3808 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3823 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
3824 | goto out; | ||
3825 | } | ||
3826 | |||
3809 | /* | 3827 | /* |
3810 | * From spc4r17 section 6.14: | 3828 | * From spc4r17 section 6.14: |
3811 | * | 3829 | * |
@@ -3819,7 +3837,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3819 | (cmd->data_length != 24)) { | 3837 | (cmd->data_length != 24)) { |
3820 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3838 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
3821 | " list length: %u\n", cmd->data_length); | 3839 | " list length: %u\n", cmd->data_length); |
3822 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3840 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; |
3841 | goto out; | ||
3823 | } | 3842 | } |
3824 | /* | 3843 | /* |
3825 | * (core_scsi3_emulate_pro_* function parameters | 3844 | * (core_scsi3_emulate_pro_* function parameters |
@@ -3828,35 +3847,47 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3828 | */ | 3847 | */ |
3829 | switch (sa) { | 3848 | switch (sa) { |
3830 | case PRO_REGISTER: | 3849 | case PRO_REGISTER: |
3831 | return core_scsi3_emulate_pro_register(cmd, | 3850 | ret = core_scsi3_emulate_pro_register(cmd, |
3832 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0); | 3851 | res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0); |
3852 | break; | ||
3833 | case PRO_RESERVE: | 3853 | case PRO_RESERVE: |
3834 | return core_scsi3_emulate_pro_reserve(cmd, | 3854 | ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key); |
3835 | type, scope, res_key); | 3855 | break; |
3836 | case PRO_RELEASE: | 3856 | case PRO_RELEASE: |
3837 | return core_scsi3_emulate_pro_release(cmd, | 3857 | ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key); |
3838 | type, scope, res_key); | 3858 | break; |
3839 | case PRO_CLEAR: | 3859 | case PRO_CLEAR: |
3840 | return core_scsi3_emulate_pro_clear(cmd, res_key); | 3860 | ret = core_scsi3_emulate_pro_clear(cmd, res_key); |
3861 | break; | ||
3841 | case PRO_PREEMPT: | 3862 | case PRO_PREEMPT: |
3842 | return core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3863 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
3843 | res_key, sa_res_key, 0); | 3864 | res_key, sa_res_key, 0); |
3865 | break; | ||
3844 | case PRO_PREEMPT_AND_ABORT: | 3866 | case PRO_PREEMPT_AND_ABORT: |
3845 | return core_scsi3_emulate_pro_preempt(cmd, type, scope, | 3867 | ret = core_scsi3_emulate_pro_preempt(cmd, type, scope, |
3846 | res_key, sa_res_key, 1); | 3868 | res_key, sa_res_key, 1); |
3869 | break; | ||
3847 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: | 3870 | case PRO_REGISTER_AND_IGNORE_EXISTING_KEY: |
3848 | return core_scsi3_emulate_pro_register(cmd, | 3871 | ret = core_scsi3_emulate_pro_register(cmd, |
3849 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); | 3872 | 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1); |
3873 | break; | ||
3850 | case PRO_REGISTER_AND_MOVE: | 3874 | case PRO_REGISTER_AND_MOVE: |
3851 | return core_scsi3_emulate_pro_register_and_move(cmd, res_key, | 3875 | ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key, |
3852 | sa_res_key, aptpl, unreg); | 3876 | sa_res_key, aptpl, unreg); |
3877 | break; | ||
3853 | default: | 3878 | default: |
3854 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3879 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
3855 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3880 | " action: 0x%02x\n", cdb[1] & 0x1f); |
3856 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3881 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; |
3882 | break; | ||
3857 | } | 3883 | } |
3858 | 3884 | ||
3859 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3885 | out: |
3886 | if (!ret) { | ||
3887 | task->task_scsi_status = GOOD; | ||
3888 | transport_complete_task(task, 1); | ||
3889 | } | ||
3890 | return ret; | ||
3860 | } | 3891 | } |
3861 | 3892 | ||
3862 | /* | 3893 | /* |
@@ -4209,6 +4240,7 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4209 | int target_scsi3_emulate_pr_in(struct se_task *task) | 4240 | int target_scsi3_emulate_pr_in(struct se_task *task) |
4210 | { | 4241 | { |
4211 | struct se_cmd *cmd = task->task_se_cmd; | 4242 | struct se_cmd *cmd = task->task_se_cmd; |
4243 | int ret; | ||
4212 | 4244 | ||
4213 | /* | 4245 | /* |
4214 | * Following spc2r20 5.5.1 Reservations overview: | 4246 | * Following spc2r20 5.5.1 Reservations overview: |
@@ -4228,18 +4260,29 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
4228 | 4260 | ||
4229 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4261 | switch (cmd->t_task_cdb[1] & 0x1f) { |
4230 | case PRI_READ_KEYS: | 4262 | case PRI_READ_KEYS: |
4231 | return core_scsi3_pri_read_keys(cmd); | 4263 | ret = core_scsi3_pri_read_keys(cmd); |
4264 | break; | ||
4232 | case PRI_READ_RESERVATION: | 4265 | case PRI_READ_RESERVATION: |
4233 | return core_scsi3_pri_read_reservation(cmd); | 4266 | ret = core_scsi3_pri_read_reservation(cmd); |
4267 | break; | ||
4234 | case PRI_REPORT_CAPABILITIES: | 4268 | case PRI_REPORT_CAPABILITIES: |
4235 | return core_scsi3_pri_report_capabilities(cmd); | 4269 | ret = core_scsi3_pri_report_capabilities(cmd); |
4270 | break; | ||
4236 | case PRI_READ_FULL_STATUS: | 4271 | case PRI_READ_FULL_STATUS: |
4237 | return core_scsi3_pri_read_full_status(cmd); | 4272 | ret = core_scsi3_pri_read_full_status(cmd); |
4273 | break; | ||
4238 | default: | 4274 | default: |
4239 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4275 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
4240 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4276 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
4241 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4277 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; |
4278 | break; | ||
4279 | } | ||
4280 | |||
4281 | if (!ret) { | ||
4282 | task->task_scsi_status = GOOD; | ||
4283 | transport_complete_task(task, 1); | ||
4242 | } | 4284 | } |
4285 | return ret; | ||
4243 | } | 4286 | } |
4244 | 4287 | ||
4245 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) | 4288 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3ad8db2d3ad3..74015793c03a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -2162,28 +2162,6 @@ check_depth: | |||
2162 | */ | 2162 | */ |
2163 | if (cmd->execute_task) { | 2163 | if (cmd->execute_task) { |
2164 | error = cmd->execute_task(task); | 2164 | error = cmd->execute_task(task); |
2165 | if (error != 0) { | ||
2166 | cmd->transport_error_status = error; | ||
2167 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
2168 | task->task_flags &= ~TF_ACTIVE; | ||
2169 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
2170 | atomic_set(&cmd->t_transport_sent, 0); | ||
2171 | transport_stop_tasks_for_cmd(cmd); | ||
2172 | atomic_inc(&dev->depth_left); | ||
2173 | transport_generic_request_failure(cmd, 0, 1); | ||
2174 | goto check_depth; | ||
2175 | } | ||
2176 | /* | ||
2177 | * Handle the successful completion for execute_task() | ||
2178 | * for synchronous operation, following SCF_EMULATE_CDB_ASYNC | ||
2179 | * Otherwise the caller is expected to complete the task with | ||
2180 | * proper status. | ||
2181 | */ | ||
2182 | if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) { | ||
2183 | cmd->scsi_status = SAM_STAT_GOOD; | ||
2184 | task->task_scsi_status = GOOD; | ||
2185 | transport_complete_task(task, 1); | ||
2186 | } | ||
2187 | } else { | 2165 | } else { |
2188 | /* | 2166 | /* |
2189 | * Currently for all virtual TCM plugins including IBLOCK, FILEIO and | 2167 | * Currently for all virtual TCM plugins including IBLOCK, FILEIO and |
@@ -2200,17 +2178,17 @@ check_depth: | |||
2200 | error = transport_emulate_control_cdb(task); | 2178 | error = transport_emulate_control_cdb(task); |
2201 | else | 2179 | else |
2202 | error = dev->transport->do_task(task); | 2180 | error = dev->transport->do_task(task); |
2181 | } | ||
2203 | 2182 | ||
2204 | if (error != 0) { | 2183 | if (error != 0) { |
2205 | cmd->transport_error_status = error; | 2184 | cmd->transport_error_status = error; |
2206 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2185 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2207 | task->task_flags &= ~TF_ACTIVE; | 2186 | task->task_flags &= ~TF_ACTIVE; |
2208 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2187 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2209 | atomic_set(&cmd->t_transport_sent, 0); | 2188 | atomic_set(&cmd->t_transport_sent, 0); |
2210 | transport_stop_tasks_for_cmd(cmd); | 2189 | transport_stop_tasks_for_cmd(cmd); |
2211 | atomic_inc(&dev->depth_left); | 2190 | atomic_inc(&dev->depth_left); |
2212 | transport_generic_request_failure(cmd, 0, 1); | 2191 | transport_generic_request_failure(cmd, 0, 1); |
2213 | } | ||
2214 | } | 2192 | } |
2215 | 2193 | ||
2216 | goto check_depth; | 2194 | goto check_depth; |
@@ -3002,11 +2980,6 @@ static int transport_generic_cmd_sequencer( | |||
3002 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | 2980 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
3003 | break; | 2981 | break; |
3004 | /* | 2982 | /* |
3005 | * Set SCF_EMULATE_CDB_ASYNC to ensure asynchronous operation | ||
3006 | * for SYNCHRONIZE_CACHE* Immed=1 case in __transport_execute_tasks() | ||
3007 | */ | ||
3008 | cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC; | ||
3009 | /* | ||
3010 | * Check to ensure that LBA + Range does not exceed past end of | 2983 | * Check to ensure that LBA + Range does not exceed past end of |
3011 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls | 2984 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls |
3012 | */ | 2985 | */ |