Commit d29a5b6acc4b63d4e05ff554509df6fbeaf527cd

Authored by Christoph Hellwig
Committed by Nicholas Bellinger
1 parent 6ed5a55790

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>

Showing 6 changed files with 142 additions and 100 deletions Side-by-side Diff

drivers/target/target_core_alua.c
... ... @@ -165,6 +165,8 @@
165 165  
166 166 transport_kunmap_first_data_page(cmd);
167 167  
  168 + task->task_scsi_status = GOOD;
  169 + transport_complete_task(task, 1);
168 170 return 0;
169 171 }
170 172  
... ... @@ -343,7 +345,8 @@
343 345  
344 346 out:
345 347 transport_kunmap_first_data_page(cmd);
346   -
  348 + task->task_scsi_status = GOOD;
  349 + transport_complete_task(task, 1);
347 350 return 0;
348 351 }
349 352  
drivers/target/target_core_cdb.c
... ... @@ -688,8 +688,10 @@
688 688 unsigned char *cdb = cmd->t_task_cdb;
689 689 int p, ret;
690 690  
691   - if (!(cdb[1] & 0x1))
692   - return target_emulate_inquiry_std(cmd);
  691 + if (!(cdb[1] & 0x1)) {
  692 + ret = target_emulate_inquiry_std(cmd);
  693 + goto out;
  694 + }
693 695  
694 696 /*
695 697 * Make sure we at least have 4 bytes of INQUIRY response
696 698  
697 699  
698 700  
699 701  
... ... @@ -708,17 +710,25 @@
708 710  
709 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 714 if (cdb[2] == evpd_handlers[p].page) {
713 715 buf[1] = cdb[2];
714 716 ret = evpd_handlers[p].emulate(cmd, buf);
715   - transport_kunmap_first_data_page(cmd);
716   - return ret;
  717 + goto out_unmap;
717 718 }
  719 + }
718 720  
719   - transport_kunmap_first_data_page(cmd);
720 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 734 static int
... ... @@ -753,6 +763,8 @@
753 763  
754 764 transport_kunmap_first_data_page(cmd);
755 765  
  766 + task->task_scsi_status = GOOD;
  767 + transport_complete_task(task, 1);
756 768 return 0;
757 769 }
758 770  
... ... @@ -787,6 +799,8 @@
787 799  
788 800 transport_kunmap_first_data_page(cmd);
789 801  
  802 + task->task_scsi_status = GOOD;
  803 + transport_complete_task(task, 1);
790 804 return 0;
791 805 }
792 806  
... ... @@ -1000,6 +1014,8 @@
1000 1014 memcpy(rbuf, buf, offset);
1001 1015 transport_kunmap_first_data_page(cmd);
1002 1016  
  1017 + task->task_scsi_status = GOOD;
  1018 + transport_complete_task(task, 1);
1003 1019 return 0;
1004 1020 }
1005 1021  
... ... @@ -1065,7 +1081,8 @@
1065 1081  
1066 1082 end:
1067 1083 transport_kunmap_first_data_page(cmd);
1068   -
  1084 + task->task_scsi_status = GOOD;
  1085 + transport_complete_task(task, 1);
1069 1086 return 0;
1070 1087 }
1071 1088  
... ... @@ -1122,7 +1139,10 @@
1122 1139  
1123 1140 err:
1124 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 1146 return ret;
1127 1147 }
1128 1148  
... ... @@ -1171,6 +1191,8 @@
1171 1191 return ret;
1172 1192 }
1173 1193  
  1194 + task->task_scsi_status = GOOD;
  1195 + transport_complete_task(task, 1);
1174 1196 return 0;
1175 1197 }
1176 1198  
... ... @@ -1189,6 +1211,14 @@
1189 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 1222 int
1193 1223 transport_emulate_control_cdb(struct se_task *task)
1194 1224 {
... ... @@ -1259,6 +1289,7 @@
1259 1289 case TEST_UNIT_READY:
1260 1290 case VERIFY:
1261 1291 case WRITE_FILEMARKS:
  1292 + ret = target_emulate_noop(task);
1262 1293 break;
1263 1294 default:
1264 1295 pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n",
... ... @@ -1268,15 +1299,6 @@
1268 1299  
1269 1300 if (ret < 0)
1270 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 1302 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
1281 1303 }
1282 1304  
drivers/target/target_core_device.c
... ... @@ -705,6 +705,8 @@
705 705 buf[2] = ((lun_count >> 8) & 0xff);
706 706 buf[3] = (lun_count & 0xff);
707 707  
  708 + se_task->task_scsi_status = GOOD;
  709 + transport_complete_task(se_task, 1);
708 710 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
709 711 }
710 712  
drivers/target/target_core_pr.c
... ... @@ -204,23 +204,21 @@
204 204 struct se_device *dev = cmd->se_dev;
205 205 struct se_session *sess = cmd->se_sess;
206 206 struct se_portal_group *tpg = sess->se_tpg;
207   - int ret;
  207 + int ret = 0;
208 208  
209 209 if (!sess || !tpg)
210   - return 0;
  210 + goto out;
211 211 if (target_check_scsi2_reservation_conflict(cmd, &ret))
212   - return ret;
  212 + goto out;
213 213  
  214 + ret = 0;
214 215 spin_lock(&dev->dev_reservation_lock);
215   - if (!dev->dev_reserved_node_acl || !sess) {
216   - spin_unlock(&dev->dev_reservation_lock);
217   - return 0;
218   - }
  216 + if (!dev->dev_reserved_node_acl || !sess)
  217 + goto out_unlock;
219 218  
220   - if (dev->dev_reserved_node_acl != sess->se_node_acl) {
221   - spin_unlock(&dev->dev_reservation_lock);
222   - return 0;
223   - }
  219 + if (dev->dev_reserved_node_acl != sess->se_node_acl)
  220 + goto out_unlock;
  221 +
224 222 dev->dev_reserved_node_acl = NULL;
225 223 dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
226 224 if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
227 225  
... ... @@ -231,9 +229,15 @@
231 229 " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
232 230 cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
233 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 243 int target_scsi2_reservation_reserve(struct se_task *task)
240 244  
241 245  
242 246  
243 247  
... ... @@ -242,23 +246,25 @@
242 246 struct se_device *dev = cmd->se_dev;
243 247 struct se_session *sess = cmd->se_sess;
244 248 struct se_portal_group *tpg = sess->se_tpg;
245   - int ret;
  249 + int ret = 0;
246 250  
247 251 if ((cmd->t_task_cdb[1] & 0x01) &&
248 252 (cmd->t_task_cdb[1] & 0x02)) {
249 253 pr_err("LongIO and Obselete Bits set, returning"
250 254 " ILLEGAL_REQUEST\n");
251   - return PYX_TRANSPORT_ILLEGAL_REQUEST;
  255 + ret = PYX_TRANSPORT_ILLEGAL_REQUEST;
  256 + goto out;
252 257 }
253 258 /*
254 259 * This is currently the case for target_core_mod passthrough struct se_cmd
255 260 * ops
256 261 */
257 262 if (!sess || !tpg)
258   - return 0;
  263 + goto out;
259 264 if (target_check_scsi2_reservation_conflict(cmd, &ret))
260   - return ret;
  265 + goto out;
261 266  
  267 + ret = 0;
262 268 spin_lock(&dev->dev_reservation_lock);
263 269 if (dev->dev_reserved_node_acl &&
264 270 (dev->dev_reserved_node_acl != sess->se_node_acl)) {
... ... @@ -271,8 +277,8 @@
271 277 " from %s \n", cmd->se_lun->unpacked_lun,
272 278 cmd->se_deve->mapped_lun,
273 279 sess->se_node_acl->initiatorname);
274   - spin_unlock(&dev->dev_reservation_lock);
275   - return PYX_TRANSPORT_RESERVATION_CONFLICT;
  280 + ret = PYX_TRANSPORT_RESERVATION_CONFLICT;
  281 + goto out_unlock;
276 282 }
277 283  
278 284 dev->dev_reserved_node_acl = sess->se_node_acl;
279 285  
... ... @@ -285,9 +291,15 @@
285 291 " for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
286 292 cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
287 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 @@
3744 3756 u64 res_key, sa_res_key;
3745 3757 int sa, scope, type, aptpl;
3746 3758 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
  3759 + int ret;
3747 3760  
3748 3761 /*
3749 3762 * Following spc2r20 5.5.1 Reservations overview:
... ... @@ -3758,7 +3771,8 @@
3758 3771 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
3759 3772 " SPC-2 reservation is held, returning"
3760 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 @@
3771 3785 if (cmd->data_length < 24) {
3772 3786 pr_warn("SPC-PR: Received PR OUT parameter list"
3773 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 3792 * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB)
... ... @@ -3804,8 +3819,11 @@
3804 3819 /*
3805 3820 * SPEC_I_PT=1 is only valid for Service action: REGISTER
3806 3821 */
3807   - if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER))
3808   - return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
  3822 + if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) {
  3823 + ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
  3824 + goto out;
  3825 + }
  3826 +
3809 3827 /*
3810 3828 * From spc4r17 section 6.14:
3811 3829 *
... ... @@ -3819,7 +3837,8 @@
3819 3837 (cmd->data_length != 24)) {
3820 3838 pr_warn("SPC-PR: Received PR OUT illegal parameter"
3821 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 3844 * (core_scsi3_emulate_pro_* function parameters
3826 3845  
3827 3846  
3828 3847  
3829 3848  
3830 3849  
3831 3850  
3832 3851  
3833 3852  
3834 3853  
3835 3854  
3836 3855  
3837 3856  
3838 3857  
3839 3858  
... ... @@ -3828,35 +3847,47 @@
3828 3847 */
3829 3848 switch (sa) {
3830 3849 case PRO_REGISTER:
3831   - return core_scsi3_emulate_pro_register(cmd,
  3850 + ret = core_scsi3_emulate_pro_register(cmd,
3832 3851 res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0);
  3852 + break;
3833 3853 case PRO_RESERVE:
3834   - return core_scsi3_emulate_pro_reserve(cmd,
3835   - type, scope, res_key);
  3854 + ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key);
  3855 + break;
3836 3856 case PRO_RELEASE:
3837   - return core_scsi3_emulate_pro_release(cmd,
3838   - type, scope, res_key);
  3857 + ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key);
  3858 + break;
3839 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 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 3864 res_key, sa_res_key, 0);
  3865 + break;
3844 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 3868 res_key, sa_res_key, 1);
  3869 + break;
3847 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 3872 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1);
  3873 + break;
3850 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 3876 sa_res_key, aptpl, unreg);
  3877 + break;
3853 3878 default:
3854 3879 pr_err("Unknown PERSISTENT_RESERVE_OUT service"
3855 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 @@
4209 4240 int target_scsi3_emulate_pr_in(struct se_task *task)
4210 4241 {
4211 4242 struct se_cmd *cmd = task->task_se_cmd;
  4243 + int ret;
4212 4244  
4213 4245 /*
4214 4246 * Following spc2r20 5.5.1 Reservations overview:
4215 4247  
4216 4248  
4217 4249  
4218 4250  
4219 4251  
... ... @@ -4228,18 +4260,29 @@
4228 4260  
4229 4261 switch (cmd->t_task_cdb[1] & 0x1f) {
4230 4262 case PRI_READ_KEYS:
4231   - return core_scsi3_pri_read_keys(cmd);
  4263 + ret = core_scsi3_pri_read_keys(cmd);
  4264 + break;
4232 4265 case PRI_READ_RESERVATION:
4233   - return core_scsi3_pri_read_reservation(cmd);
  4266 + ret = core_scsi3_pri_read_reservation(cmd);
  4267 + break;
4234 4268 case PRI_REPORT_CAPABILITIES:
4235   - return core_scsi3_pri_report_capabilities(cmd);
  4269 + ret = core_scsi3_pri_report_capabilities(cmd);
  4270 + break;
4236 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 4274 default:
4239 4275 pr_err("Unknown PERSISTENT_RESERVE_IN service"
4240 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;
4242 4279 }
  4280 +
  4281 + if (!ret) {
  4282 + task->task_scsi_status = GOOD;
  4283 + transport_complete_task(task, 1);
  4284 + }
  4285 + return ret;
4243 4286 }
4244 4287  
4245 4288 static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)
drivers/target/target_core_transport.c
... ... @@ -2162,28 +2162,6 @@
2162 2162 */
2163 2163 if (cmd->execute_task) {
2164 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 2165 } else {
2188 2166 /*
2189 2167 * Currently for all virtual TCM plugins including IBLOCK, FILEIO and
2190 2168  
... ... @@ -2200,17 +2178,17 @@
2200 2178 error = transport_emulate_control_cdb(task);
2201 2179 else
2202 2180 error = dev->transport->do_task(task);
  2181 + }
2203 2182  
2204   - if (error != 0) {
2205   - cmd->transport_error_status = error;
2206   - spin_lock_irqsave(&cmd->t_state_lock, flags);
2207   - task->task_flags &= ~TF_ACTIVE;
2208   - spin_unlock_irqrestore(&cmd->t_state_lock, flags);
2209   - atomic_set(&cmd->t_transport_sent, 0);
2210   - transport_stop_tasks_for_cmd(cmd);
2211   - atomic_inc(&dev->depth_left);
2212   - transport_generic_request_failure(cmd, 0, 1);
2213   - }
  2183 + if (error != 0) {
  2184 + cmd->transport_error_status = error;
  2185 + spin_lock_irqsave(&cmd->t_state_lock, flags);
  2186 + task->task_flags &= ~TF_ACTIVE;
  2187 + spin_unlock_irqrestore(&cmd->t_state_lock, flags);
  2188 + atomic_set(&cmd->t_transport_sent, 0);
  2189 + transport_stop_tasks_for_cmd(cmd);
  2190 + atomic_inc(&dev->depth_left);
  2191 + transport_generic_request_failure(cmd, 0, 1);
2214 2192 }
2215 2193  
2216 2194 goto check_depth;
... ... @@ -3001,11 +2979,6 @@
3001 2979  
3002 2980 if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
3003 2981 break;
3004   - /*
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 2982 /*
3010 2983 * Check to ensure that LBA + Range does not exceed past end of
3011 2984 * device for IBLOCK and FILEIO ->do_sync_cache() backend calls
include/target/target_core_base.h
... ... @@ -114,7 +114,6 @@
114 114 SCF_DELAYED_CMD_FROM_SAM_ATTR = 0x00080000,
115 115 SCF_UNUSED = 0x00100000,
116 116 SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
117   - SCF_EMULATE_CDB_ASYNC = 0x01000000,
118 117 };
119 118  
120 119 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */