aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2015-05-19 17:44:39 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-05-30 22:57:48 -0400
commit9c1cd1b68cd15c81d12a0cf2402129475882b620 (patch)
tree83f3008fd0b47e62b6792926f2bc8eec1b9082d2
parentcf87edc6022d1fe7efa6b8ce1a99f2ef6a1b27f9 (diff)
target/user: Only support full command pass-through
After much discussion, give up on only passing a subset of SCSI commands to userspace and pass them all. Based on what pscsi is doing, make sure to set SCF_SCSI_DATA_CDB for I/O ops, and define attributes identical to pscsi. Make hw_block_size configurable via dev param. Remove mention of command filtering from tcmu-design.txt. Signed-off-by: Andy Grover <agrover@redhat.com> Reviewed-by: Ilias Tsitsimpis <iliastsi@arrikto.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--Documentation/target/tcmu-design.txt21
-rw-r--r--drivers/target/target_core_user.c124
2 files changed, 75 insertions, 70 deletions
diff --git a/Documentation/target/tcmu-design.txt b/Documentation/target/tcmu-design.txt
index b495108c433c..263b907517ac 100644
--- a/Documentation/target/tcmu-design.txt
+++ b/Documentation/target/tcmu-design.txt
@@ -15,8 +15,7 @@ Contents:
15 a) Discovering and configuring TCMU uio devices 15 a) Discovering and configuring TCMU uio devices
16 b) Waiting for events on the device(s) 16 b) Waiting for events on the device(s)
17 c) Managing the command ring 17 c) Managing the command ring
183) Command filtering 183) A final note
194) A final note
20 19
21 20
22TCM Userspace Design 21TCM Userspace Design
@@ -364,24 +363,6 @@ int handle_device_events(int fd, void *map)
364} 363}
365 364
366 365
367Command filtering
368-----------------
369
370Initial TCMU support is for a filtered commandset. Only IO-related
371commands are presented to userspace, and the rest are handled by LIO's
372in-kernel command emulation. The commands presented are all versions
373of:
374
375READ
376WRITE
377WRITE_VERIFY
378XDWRITEREAD
379WRITE_SAME
380COMPARE_AND_WRITE
381SYNCHRONIZE_CACHE
382UNMAP
383
384
385A final note 366A final note
386------------ 367------------
387 368
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 0e0feeaec39c..90e084ea7b92 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -938,12 +938,13 @@ static void tcmu_free_device(struct se_device *dev)
938} 938}
939 939
940enum { 940enum {
941 Opt_dev_config, Opt_dev_size, Opt_err, 941 Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_err,
942}; 942};
943 943
944static match_table_t tokens = { 944static match_table_t tokens = {
945 {Opt_dev_config, "dev_config=%s"}, 945 {Opt_dev_config, "dev_config=%s"},
946 {Opt_dev_size, "dev_size=%u"}, 946 {Opt_dev_size, "dev_size=%u"},
947 {Opt_hw_block_size, "hw_block_size=%u"},
947 {Opt_err, NULL} 948 {Opt_err, NULL}
948}; 949};
949 950
@@ -954,6 +955,7 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev,
954 char *orig, *ptr, *opts, *arg_p; 955 char *orig, *ptr, *opts, *arg_p;
955 substring_t args[MAX_OPT_ARGS]; 956 substring_t args[MAX_OPT_ARGS];
956 int ret = 0, token; 957 int ret = 0, token;
958 unsigned long tmp_ul;
957 959
958 opts = kstrdup(page, GFP_KERNEL); 960 opts = kstrdup(page, GFP_KERNEL);
959 if (!opts) 961 if (!opts)
@@ -986,6 +988,24 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev,
986 if (ret < 0) 988 if (ret < 0)
987 pr_err("kstrtoul() failed for dev_size=\n"); 989 pr_err("kstrtoul() failed for dev_size=\n");
988 break; 990 break;
991 case Opt_hw_block_size:
992 arg_p = match_strdup(&args[0]);
993 if (!arg_p) {
994 ret = -ENOMEM;
995 break;
996 }
997 ret = kstrtoul(arg_p, 0, &tmp_ul);
998 kfree(arg_p);
999 if (ret < 0) {
1000 pr_err("kstrtoul() failed for hw_block_size=\n");
1001 break;
1002 }
1003 if (!tmp_ul) {
1004 pr_err("hw_block_size must be nonzero\n");
1005 break;
1006 }
1007 dev->dev_attrib.hw_block_size = tmp_ul;
1008 break;
989 default: 1009 default:
990 break; 1010 break;
991 } 1011 }
@@ -1016,12 +1036,9 @@ static sector_t tcmu_get_blocks(struct se_device *dev)
1016} 1036}
1017 1037
1018static sense_reason_t 1038static sense_reason_t
1019tcmu_execute_rw(struct se_cmd *se_cmd, struct scatterlist *sgl, u32 sgl_nents, 1039tcmu_pass_op(struct se_cmd *se_cmd)
1020 enum dma_data_direction data_direction)
1021{ 1040{
1022 int ret; 1041 int ret = tcmu_queue_cmd(se_cmd);
1023
1024 ret = tcmu_queue_cmd(se_cmd);
1025 1042
1026 if (ret != 0) 1043 if (ret != 0)
1027 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1044 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -1030,62 +1047,69 @@ tcmu_execute_rw(struct se_cmd *se_cmd, struct scatterlist *sgl, u32 sgl_nents,
1030} 1047}
1031 1048
1032static sense_reason_t 1049static sense_reason_t
1033tcmu_pass_op(struct se_cmd *se_cmd) 1050tcmu_parse_cdb(struct se_cmd *cmd)
1034{ 1051{
1035 int ret = tcmu_queue_cmd(se_cmd); 1052 unsigned char *cdb = cmd->t_task_cdb;
1036 1053
1037 if (ret != 0) 1054 /*
1038 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1055 * For REPORT LUNS we always need to emulate the response, for everything
1039 else 1056 * else, pass it up.
1057 */
1058 if (cdb[0] == REPORT_LUNS) {
1059 cmd->execute_cmd = spc_emulate_report_luns;
1040 return TCM_NO_SENSE; 1060 return TCM_NO_SENSE;
1041} 1061 }
1042 1062
1043static struct sbc_ops tcmu_sbc_ops = { 1063 /* Set DATA_CDB flag for ops that should have it */
1044 .execute_rw = tcmu_execute_rw, 1064 switch (cdb[0]) {
1045 .execute_sync_cache = tcmu_pass_op, 1065 case READ_6:
1046 .execute_write_same = tcmu_pass_op, 1066 case READ_10:
1047 .execute_write_same_unmap = tcmu_pass_op, 1067 case READ_12:
1048 .execute_unmap = tcmu_pass_op, 1068 case READ_16:
1049}; 1069 case WRITE_6:
1070 case WRITE_10:
1071 case WRITE_12:
1072 case WRITE_16:
1073 case WRITE_VERIFY:
1074 case WRITE_VERIFY_12:
1075 case 0x8e: /* WRITE_VERIFY_16 */
1076 case COMPARE_AND_WRITE:
1077 case XDWRITEREAD_10:
1078 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
1079 break;
1080 case VARIABLE_LENGTH_CMD:
1081 switch (get_unaligned_be16(&cdb[8])) {
1082 case READ_32:
1083 case WRITE_32:
1084 case 0x0c: /* WRITE_VERIFY_32 */
1085 case XDWRITEREAD_32:
1086 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
1087 break;
1088 }
1089 }
1050 1090
1051static sense_reason_t 1091 cmd->execute_cmd = tcmu_pass_op;
1052tcmu_parse_cdb(struct se_cmd *cmd) 1092
1053{ 1093 return TCM_NO_SENSE;
1054 return sbc_parse_cdb(cmd, &tcmu_sbc_ops);
1055} 1094}
1056 1095
1057DEF_TB_DEFAULT_ATTRIBS(tcmu); 1096DEF_TB_DEV_ATTRIB_RO(tcmu, hw_pi_prot_type);
1097TB_DEV_ATTR_RO(tcmu, hw_pi_prot_type);
1098
1099DEF_TB_DEV_ATTRIB_RO(tcmu, hw_block_size);
1100TB_DEV_ATTR_RO(tcmu, hw_block_size);
1101
1102DEF_TB_DEV_ATTRIB_RO(tcmu, hw_max_sectors);
1103TB_DEV_ATTR_RO(tcmu, hw_max_sectors);
1104
1105DEF_TB_DEV_ATTRIB_RO(tcmu, hw_queue_depth);
1106TB_DEV_ATTR_RO(tcmu, hw_queue_depth);
1058 1107
1059static struct configfs_attribute *tcmu_backend_dev_attrs[] = { 1108static struct configfs_attribute *tcmu_backend_dev_attrs[] = {
1060 &tcmu_dev_attrib_emulate_model_alias.attr,
1061 &tcmu_dev_attrib_emulate_dpo.attr,
1062 &tcmu_dev_attrib_emulate_fua_write.attr,
1063 &tcmu_dev_attrib_emulate_fua_read.attr,
1064 &tcmu_dev_attrib_emulate_write_cache.attr,
1065 &tcmu_dev_attrib_emulate_ua_intlck_ctrl.attr,
1066 &tcmu_dev_attrib_emulate_tas.attr,
1067 &tcmu_dev_attrib_emulate_tpu.attr,
1068 &tcmu_dev_attrib_emulate_tpws.attr,
1069 &tcmu_dev_attrib_emulate_caw.attr,
1070 &tcmu_dev_attrib_emulate_3pc.attr,
1071 &tcmu_dev_attrib_pi_prot_type.attr,
1072 &tcmu_dev_attrib_hw_pi_prot_type.attr, 1109 &tcmu_dev_attrib_hw_pi_prot_type.attr,
1073 &tcmu_dev_attrib_pi_prot_format.attr,
1074 &tcmu_dev_attrib_enforce_pr_isids.attr,
1075 &tcmu_dev_attrib_is_nonrot.attr,
1076 &tcmu_dev_attrib_emulate_rest_reord.attr,
1077 &tcmu_dev_attrib_force_pr_aptpl.attr,
1078 &tcmu_dev_attrib_hw_block_size.attr, 1110 &tcmu_dev_attrib_hw_block_size.attr,
1079 &tcmu_dev_attrib_block_size.attr,
1080 &tcmu_dev_attrib_hw_max_sectors.attr, 1111 &tcmu_dev_attrib_hw_max_sectors.attr,
1081 &tcmu_dev_attrib_optimal_sectors.attr,
1082 &tcmu_dev_attrib_hw_queue_depth.attr, 1112 &tcmu_dev_attrib_hw_queue_depth.attr,
1083 &tcmu_dev_attrib_queue_depth.attr,
1084 &tcmu_dev_attrib_max_unmap_lba_count.attr,
1085 &tcmu_dev_attrib_max_unmap_block_desc_count.attr,
1086 &tcmu_dev_attrib_unmap_granularity.attr,
1087 &tcmu_dev_attrib_unmap_granularity_alignment.attr,
1088 &tcmu_dev_attrib_max_write_same_len.attr,
1089 NULL, 1113 NULL,
1090}; 1114};
1091 1115
@@ -1094,7 +1118,7 @@ static struct se_subsystem_api tcmu_template = {
1094 .inquiry_prod = "USER", 1118 .inquiry_prod = "USER",
1095 .inquiry_rev = TCMU_VERSION, 1119 .inquiry_rev = TCMU_VERSION,
1096 .owner = THIS_MODULE, 1120 .owner = THIS_MODULE,
1097 .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV, 1121 .transport_type = TRANSPORT_PLUGIN_PHBA_PDEV,
1098 .attach_hba = tcmu_attach_hba, 1122 .attach_hba = tcmu_attach_hba,
1099 .detach_hba = tcmu_detach_hba, 1123 .detach_hba = tcmu_detach_hba,
1100 .alloc_device = tcmu_alloc_device, 1124 .alloc_device = tcmu_alloc_device,