Commit 5bda90c8f20f0af93375721533f4081a40fa6f41

Authored by Christoph Hellwig
Committed by Nicholas Bellinger
1 parent d29a5b6acc

target: use ->exectute_task for all CDB emulation

Instead of calling into transport_emulate_control_cdb from
__transport_execute_tasks for some CDBs always set up ->exectute_tasks
in the command sequence and use it uniformly.

(nab: Add default passthrough break for SERVICE_ACTION_IN)

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

Showing 3 changed files with 97 additions and 140 deletions Side-by-side Diff

drivers/target/target_core_cdb.c
... ... @@ -32,6 +32,7 @@
32 32 #include <target/target_core_transport.h>
33 33 #include <target/target_core_fabric_ops.h>
34 34 #include "target_core_ua.h"
  35 +#include "target_core_cdb.h"
35 36  
36 37 static void
37 38 target_fill_alua_data(struct se_port *port, unsigned char *buf)
... ... @@ -679,8 +680,7 @@
679 680 return 0;
680 681 }
681 682  
682   -static int
683   -target_emulate_inquiry(struct se_task *task)
  683 +int target_emulate_inquiry(struct se_task *task)
684 684 {
685 685 struct se_cmd *cmd = task->task_se_cmd;
686 686 struct se_device *dev = cmd->se_dev;
... ... @@ -731,8 +731,7 @@
731 731 return ret;
732 732 }
733 733  
734   -static int
735   -target_emulate_readcapacity(struct se_task *task)
  734 +int target_emulate_readcapacity(struct se_task *task)
736 735 {
737 736 struct se_cmd *cmd = task->task_se_cmd;
738 737 struct se_device *dev = cmd->se_dev;
... ... @@ -768,8 +767,7 @@
768 767 return 0;
769 768 }
770 769  
771   -static int
772   -target_emulate_readcapacity_16(struct se_task *task)
  770 +int target_emulate_readcapacity_16(struct se_task *task)
773 771 {
774 772 struct se_cmd *cmd = task->task_se_cmd;
775 773 struct se_device *dev = cmd->se_dev;
... ... @@ -939,8 +937,7 @@
939 937 }
940 938 }
941 939  
942   -static int
943   -target_emulate_modesense(struct se_task *task)
  940 +int target_emulate_modesense(struct se_task *task)
944 941 {
945 942 struct se_cmd *cmd = task->task_se_cmd;
946 943 struct se_device *dev = cmd->se_dev;
... ... @@ -1019,8 +1016,7 @@
1019 1016 return 0;
1020 1017 }
1021 1018  
1022   -static int
1023   -target_emulate_request_sense(struct se_task *task)
  1019 +int target_emulate_request_sense(struct se_task *task)
1024 1020 {
1025 1021 struct se_cmd *cmd = task->task_se_cmd;
1026 1022 unsigned char *cdb = cmd->t_task_cdb;
... ... @@ -1090,8 +1086,7 @@
1090 1086 * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
1091 1087 * Note this is not used for TCM/pSCSI passthrough
1092 1088 */
1093   -static int
1094   -target_emulate_unmap(struct se_task *task)
  1089 +int target_emulate_unmap(struct se_task *task)
1095 1090 {
1096 1091 struct se_cmd *cmd = task->task_se_cmd;
1097 1092 struct se_device *dev = cmd->se_dev;
... ... @@ -1150,8 +1145,7 @@
1150 1145 * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
1151 1146 * Note this is not used for TCM/pSCSI passthrough
1152 1147 */
1153   -static int
1154   -target_emulate_write_same(struct se_task *task)
  1148 +int target_emulate_write_same(struct se_task *task)
1155 1149 {
1156 1150 struct se_cmd *cmd = task->task_se_cmd;
1157 1151 struct se_device *dev = cmd->se_dev;
... ... @@ -1196,8 +1190,7 @@
1196 1190 return 0;
1197 1191 }
1198 1192  
1199   -static int
1200   -target_emulate_synchronize_cache(struct se_task *task)
  1193 +int target_emulate_synchronize_cache(struct se_task *task)
1201 1194 {
1202 1195 struct se_device *dev = task->task_se_cmd->se_dev;
1203 1196  
1204 1197  
... ... @@ -1211,95 +1204,11 @@
1211 1204 return 0;
1212 1205 }
1213 1206  
1214   -static int
1215   -target_emulate_noop(struct se_task *task)
  1207 +int target_emulate_noop(struct se_task *task)
1216 1208 {
1217 1209 task->task_scsi_status = GOOD;
1218 1210 transport_complete_task(task, 1);
1219 1211 return 0;
1220   -}
1221   -
1222   -int
1223   -transport_emulate_control_cdb(struct se_task *task)
1224   -{
1225   - struct se_cmd *cmd = task->task_se_cmd;
1226   - struct se_device *dev = cmd->se_dev;
1227   - unsigned short service_action;
1228   - int ret = 0;
1229   -
1230   - switch (cmd->t_task_cdb[0]) {
1231   - case INQUIRY:
1232   - ret = target_emulate_inquiry(task);
1233   - break;
1234   - case READ_CAPACITY:
1235   - ret = target_emulate_readcapacity(task);
1236   - break;
1237   - case MODE_SENSE:
1238   - ret = target_emulate_modesense(task);
1239   - break;
1240   - case MODE_SENSE_10:
1241   - ret = target_emulate_modesense(task);
1242   - break;
1243   - case SERVICE_ACTION_IN:
1244   - switch (cmd->t_task_cdb[1] & 0x1f) {
1245   - case SAI_READ_CAPACITY_16:
1246   - ret = target_emulate_readcapacity_16(task);
1247   - break;
1248   - default:
1249   - pr_err("Unsupported SA: 0x%02x\n",
1250   - cmd->t_task_cdb[1] & 0x1f);
1251   - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1252   - }
1253   - break;
1254   - case REQUEST_SENSE:
1255   - ret = target_emulate_request_sense(task);
1256   - break;
1257   - case UNMAP:
1258   - ret = target_emulate_unmap(task);
1259   - break;
1260   - case WRITE_SAME:
1261   - ret = target_emulate_write_same(task);
1262   - break;
1263   - case WRITE_SAME_16:
1264   - ret = target_emulate_write_same(task);
1265   - break;
1266   - case VARIABLE_LENGTH_CMD:
1267   - service_action =
1268   - get_unaligned_be16(&cmd->t_task_cdb[8]);
1269   - switch (service_action) {
1270   - case WRITE_SAME_32:
1271   - ret = target_emulate_write_same(task);
1272   - break;
1273   - default:
1274   - pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"
1275   - " 0x%02x\n", service_action);
1276   - break;
1277   - }
1278   - break;
1279   - case SYNCHRONIZE_CACHE:
1280   - case 0x91: /* SYNCHRONIZE_CACHE_16: */
1281   - ret = target_emulate_synchronize_cache(task);
1282   - break;
1283   - case ALLOW_MEDIUM_REMOVAL:
1284   - case ERASE:
1285   - case REZERO_UNIT:
1286   - case SEEK_10:
1287   - case SPACE:
1288   - case START_STOP:
1289   - case TEST_UNIT_READY:
1290   - case VERIFY:
1291   - case WRITE_FILEMARKS:
1292   - ret = target_emulate_noop(task);
1293   - break;
1294   - default:
1295   - pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n",
1296   - cmd->t_task_cdb[0], dev->transport->name);
1297   - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
1298   - }
1299   -
1300   - if (ret < 0)
1301   - return ret;
1302   - return PYX_TRANSPORT_SENT_TO_TRANSPORT;
1303 1212 }
1304 1213  
1305 1214 /*
drivers/target/target_core_cdb.h
  1 +#ifndef TARGET_CORE_CDB_H
  2 +#define TARGET_CORE_CDB_H
  3 +
  4 +int target_emulate_inquiry(struct se_task *task);
  5 +int target_emulate_readcapacity(struct se_task *task);
  6 +int target_emulate_readcapacity_16(struct se_task *task);
  7 +int target_emulate_modesense(struct se_task *task);
  8 +int target_emulate_request_sense(struct se_task *task);
  9 +int target_emulate_unmap(struct se_task *task);
  10 +int target_emulate_write_same(struct se_task *task);
  11 +int target_emulate_synchronize_cache(struct se_task *task);
  12 +int target_emulate_noop(struct se_task *task);
  13 +
  14 +#endif /* TARGET_CORE_CDB_H */
drivers/target/target_core_transport.c
... ... @@ -52,6 +52,7 @@
52 52 #include <target/target_core_configfs.h>
53 53  
54 54 #include "target_core_alua.h"
  55 +#include "target_core_cdb.h"
55 56 #include "target_core_hba.h"
56 57 #include "target_core_pr.h"
57 58 #include "target_core_ua.h"
58 59  
... ... @@ -2155,31 +2156,11 @@
2155 2156 atomic_set(&cmd->t_transport_sent, 1);
2156 2157  
2157 2158 spin_unlock_irqrestore(&cmd->t_state_lock, flags);
2158   - /*
2159   - * The struct se_cmd->execute_task() function pointer is used
2160   - * to grab REPORT_LUNS and other CDBs we want to handle before they hit the
2161   - * struct se_subsystem_api->do_task() caller below.
2162   - */
2163   - if (cmd->execute_task) {
2164   - error = cmd->execute_task(task);
2165   - } else {
2166   - /*
2167   - * Currently for all virtual TCM plugins including IBLOCK, FILEIO and
2168   - * RAMDISK we use the internal transport_emulate_control_cdb() logic
2169   - * with struct se_subsystem_api callers for the primary SPC-3 TYPE_DISK
2170   - * LUN emulation code.
2171   - *
2172   - * For TCM/pSCSI and all other SCF_SCSI_DATA_SG_IO_CDB I/O tasks we
2173   - * call ->do_task() directly and let the underlying TCM subsystem plugin
2174   - * code handle the CDB emulation.
2175   - */
2176   - if ((dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) &&
2177   - (!(task->task_se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
2178   - error = transport_emulate_control_cdb(task);
2179   - else
2180   - error = dev->transport->do_task(task);
2181   - }
2182 2159  
  2160 + if (cmd->execute_task)
  2161 + error = cmd->execute_task(task);
  2162 + else
  2163 + error = dev->transport->do_task(task);
2183 2164 if (error != 0) {
2184 2165 cmd->transport_error_status = error;
2185 2166 spin_lock_irqsave(&cmd->t_state_lock, flags);
... ... @@ -2622,6 +2603,13 @@
2622 2603 */
2623 2604 }
2624 2605  
  2606 + /*
  2607 + * If we operate in passthrough mode we skip most CDB emulation and
  2608 + * instead hand the commands down to the physical SCSI device.
  2609 + */
  2610 + passthrough =
  2611 + (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV);
  2612 +
2625 2613 switch (cdb[0]) {
2626 2614 case READ_6:
2627 2615 sectors = transport_get_sectors_6(cdb, cmd, &sector_ret);
2628 2616  
... ... @@ -2701,9 +2689,12 @@
2701 2689 cmd->t_task_lba = transport_lba_32(cdb);
2702 2690 cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
2703 2691  
2704   - if (dev->transport->transport_type ==
2705   - TRANSPORT_PLUGIN_PHBA_PDEV)
  2692 + /*
  2693 + * Do now allow BIDI commands for passthrough mode.
  2694 + */
  2695 + if (passthrough)
2706 2696 goto out_unsupported_cdb;
  2697 +
2707 2698 /*
2708 2699 * Setup BIDI XOR callback to be run after I/O completion.
2709 2700 */
... ... @@ -2712,13 +2703,6 @@
2712 2703 break;
2713 2704 case VARIABLE_LENGTH_CMD:
2714 2705 service_action = get_unaligned_be16(&cdb[8]);
2715   - /*
2716   - * Determine if this is TCM/PSCSI device and we should disable
2717   - * internal emulation for this CDB.
2718   - */
2719   - passthrough = (dev->transport->transport_type ==
2720   - TRANSPORT_PLUGIN_PHBA_PDEV);
2721   -
2722 2706 switch (service_action) {
2723 2707 case XDWRITEREAD_32:
2724 2708 sectors = transport_get_sectors_32(cdb, cmd, &sector_ret);
2725 2709  
... ... @@ -2732,8 +2716,12 @@
2732 2716 cmd->t_task_lba = transport_lba_64_ext(cdb);
2733 2717 cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
2734 2718  
  2719 + /*
  2720 + * Do now allow BIDI commands for passthrough mode.
  2721 + */
2735 2722 if (passthrough)
2736 2723 goto out_unsupported_cdb;
  2724 +
2737 2725 /*
2738 2726 * Setup BIDI XOR callback to be run during after I/O
2739 2727 * completion.
... ... @@ -2759,7 +2747,8 @@
2759 2747  
2760 2748 if (target_check_write_same_discard(&cdb[10], dev) < 0)
2761 2749 goto out_invalid_cdb_field;
2762   -
  2750 + if (!passthrough)
  2751 + cmd->execute_task = target_emulate_write_same;
2763 2752 break;
2764 2753 default:
2765 2754 pr_err("VARIABLE_LENGTH_CMD service action"
2766 2755  
... ... @@ -2797,8 +2786,15 @@
2797 2786 case MODE_SENSE:
2798 2787 size = cdb[4];
2799 2788 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  2789 + if (!passthrough)
  2790 + cmd->execute_task = target_emulate_modesense;
2800 2791 break;
2801 2792 case MODE_SENSE_10:
  2793 + size = (cdb[7] << 8) + cdb[8];
  2794 + cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  2795 + if (!passthrough)
  2796 + cmd->execute_task = target_emulate_modesense;
  2797 + break;
2802 2798 case GPCMD_READ_BUFFER_CAPACITY:
2803 2799 case GPCMD_SEND_OPC:
2804 2800 case LOG_SELECT:
... ... @@ -2867,6 +2863,8 @@
2867 2863 if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
2868 2864 cmd->sam_task_attr = MSG_HEAD_TAG;
2869 2865 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  2866 + if (!passthrough)
  2867 + cmd->execute_task = target_emulate_inquiry;
2870 2868 break;
2871 2869 case READ_BUFFER:
2872 2870 size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
... ... @@ -2875,6 +2873,8 @@
2875 2873 case READ_CAPACITY:
2876 2874 size = READ_CAP_LEN;
2877 2875 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  2876 + if (!passthrough)
  2877 + cmd->execute_task = target_emulate_readcapacity;
2878 2878 break;
2879 2879 case READ_MEDIA_SERIAL_NUMBER:
2880 2880 case SECURITY_PROTOCOL_IN:
... ... @@ -2883,6 +2883,21 @@
2883 2883 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
2884 2884 break;
2885 2885 case SERVICE_ACTION_IN:
  2886 + switch (cmd->t_task_cdb[1] & 0x1f) {
  2887 + case SAI_READ_CAPACITY_16:
  2888 + if (!passthrough)
  2889 + cmd->execute_task =
  2890 + target_emulate_readcapacity_16;
  2891 + break;
  2892 + default:
  2893 + if (passthrough)
  2894 + break;
  2895 +
  2896 + pr_err("Unsupported SA: 0x%02x\n",
  2897 + cmd->t_task_cdb[1] & 0x1f);
  2898 + goto out_unsupported_cdb;
  2899 + }
  2900 + /*FALLTHROUGH*/
2886 2901 case ACCESS_CONTROL_IN:
2887 2902 case ACCESS_CONTROL_OUT:
2888 2903 case EXTENDED_COPY:
... ... @@ -2913,6 +2928,8 @@
2913 2928 case REQUEST_SENSE:
2914 2929 size = cdb[4];
2915 2930 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  2931 + if (!passthrough)
  2932 + cmd->execute_task = target_emulate_request_sense;
2916 2933 break;
2917 2934 case READ_ELEMENT_STATUS:
2918 2935 size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9];
2919 2936  
... ... @@ -2977,8 +2994,9 @@
2977 2994 size = transport_get_size(sectors, cdb, cmd);
2978 2995 cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
2979 2996  
2980   - if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
  2997 + if (passthrough)
2981 2998 break;
  2999 +
2982 3000 /*
2983 3001 * Check to ensure that LBA + Range does not exceed past end of
2984 3002 * device for IBLOCK and FILEIO ->do_sync_cache() backend calls
2985 3003  
... ... @@ -2987,10 +3005,13 @@
2987 3005 if (transport_cmd_get_valid_sectors(cmd) < 0)
2988 3006 goto out_invalid_cdb_field;
2989 3007 }
  3008 + cmd->execute_task = target_emulate_synchronize_cache;
2990 3009 break;
2991 3010 case UNMAP:
2992 3011 size = get_unaligned_be16(&cdb[7]);
2993 3012 cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
  3013 + if (!passthrough)
  3014 + cmd->execute_task = target_emulate_unmap;
2994 3015 break;
2995 3016 case WRITE_SAME_16:
2996 3017 sectors = transport_get_sectors_16(cdb, cmd, &sector_ret);
... ... @@ -3009,6 +3030,8 @@
3009 3030  
3010 3031 if (target_check_write_same_discard(&cdb[1], dev) < 0)
3011 3032 goto out_invalid_cdb_field;
  3033 + if (!passthrough)
  3034 + cmd->execute_task = target_emulate_write_same;
3012 3035 break;
3013 3036 case WRITE_SAME:
3014 3037 sectors = transport_get_sectors_10(cdb, cmd, &sector_ret);
3015 3038  
3016 3039  
3017 3040  
3018 3041  
... ... @@ -3030,20 +3053,26 @@
3030 3053 */
3031 3054 if (target_check_write_same_discard(&cdb[1], dev) < 0)
3032 3055 goto out_invalid_cdb_field;
  3056 + if (!passthrough)
  3057 + cmd->execute_task = target_emulate_write_same;
3033 3058 break;
3034 3059 case ALLOW_MEDIUM_REMOVAL:
3035   - case GPCMD_CLOSE_TRACK:
3036 3060 case ERASE:
3037   - case INITIALIZE_ELEMENT_STATUS:
3038   - case GPCMD_LOAD_UNLOAD:
3039 3061 case REZERO_UNIT:
3040 3062 case SEEK_10:
3041   - case GPCMD_SET_SPEED:
3042 3063 case SPACE:
3043 3064 case START_STOP:
3044 3065 case TEST_UNIT_READY:
3045 3066 case VERIFY:
3046 3067 case WRITE_FILEMARKS:
  3068 + cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
  3069 + if (!passthrough)
  3070 + cmd->execute_task = target_emulate_noop;
  3071 + break;
  3072 + case GPCMD_CLOSE_TRACK:
  3073 + case INITIALIZE_ELEMENT_STATUS:
  3074 + case GPCMD_LOAD_UNLOAD:
  3075 + case GPCMD_SET_SPEED:
3047 3076 case MOVE_MEDIUM:
3048 3077 cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
3049 3078 break;
... ... @@ -3099,6 +3128,11 @@
3099 3128 }
3100 3129 cmd->data_length = size;
3101 3130 }
  3131 +
  3132 + /* reject any command that we don't have a handler for */
  3133 + if (!(passthrough || cmd->execute_task ||
  3134 + (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
  3135 + goto out_unsupported_cdb;
3102 3136  
3103 3137 /* Let's limit control cdbs to a page, for simplicity's sake. */
3104 3138 if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) &&