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.

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>

authored by

Christoph Hellwig and committed by
Nicholas Bellinger
5bda90c8 d29a5b6a

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