aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/target/target_core_user.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 10cc15f0b1fa..c6874c38a10b 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -28,6 +28,7 @@
28#include <linux/stringify.h> 28#include <linux/stringify.h>
29#include <linux/bitops.h> 29#include <linux/bitops.h>
30#include <linux/highmem.h> 30#include <linux/highmem.h>
31#include <linux/configfs.h>
31#include <net/genetlink.h> 32#include <net/genetlink.h>
32#include <scsi/scsi_common.h> 33#include <scsi/scsi_common.h>
33#include <scsi/scsi_proto.h> 34#include <scsi/scsi_proto.h>
@@ -1046,7 +1047,7 @@ static void tcmu_free_device(struct se_device *dev)
1046 1047
1047enum { 1048enum {
1048 Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, 1049 Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors,
1049 Opt_cmd_time_out, Opt_err, 1050 Opt_err,
1050}; 1051};
1051 1052
1052static match_table_t tokens = { 1053static match_table_t tokens = {
@@ -1054,7 +1055,6 @@ static match_table_t tokens = {
1054 {Opt_dev_size, "dev_size=%u"}, 1055 {Opt_dev_size, "dev_size=%u"},
1055 {Opt_hw_block_size, "hw_block_size=%u"}, 1056 {Opt_hw_block_size, "hw_block_size=%u"},
1056 {Opt_hw_max_sectors, "hw_max_sectors=%u"}, 1057 {Opt_hw_max_sectors, "hw_max_sectors=%u"},
1057 {Opt_cmd_time_out, "cmd_time_out=%u"},
1058 {Opt_err, NULL} 1058 {Opt_err, NULL}
1059}; 1059};
1060 1060
@@ -1121,23 +1121,6 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev,
1121 if (ret < 0) 1121 if (ret < 0)
1122 pr_err("kstrtoul() failed for dev_size=\n"); 1122 pr_err("kstrtoul() failed for dev_size=\n");
1123 break; 1123 break;
1124 case Opt_cmd_time_out:
1125 if (tcmu_dev_configured(udev)) {
1126 pr_err("Can not update cmd_time_out after device has been configured.\n");
1127 ret = -EINVAL;
1128 break;
1129 }
1130 arg_p = match_strdup(&args[0]);
1131 if (!arg_p) {
1132 ret = -ENOMEM;
1133 break;
1134 }
1135 ret = kstrtouint(arg_p, 0, &udev->cmd_time_out);
1136 kfree(arg_p);
1137 if (ret < 0)
1138 pr_err("kstrtouint() failed for cmd_time_out=\n");
1139 udev->cmd_time_out *= MSEC_PER_SEC;
1140 break;
1141 case Opt_hw_block_size: 1124 case Opt_hw_block_size:
1142 ret = tcmu_set_dev_attrib(&args[0], 1125 ret = tcmu_set_dev_attrib(&args[0],
1143 &(dev->dev_attrib.hw_block_size)); 1126 &(dev->dev_attrib.hw_block_size));
@@ -1165,9 +1148,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b)
1165 1148
1166 bl = sprintf(b + bl, "Config: %s ", 1149 bl = sprintf(b + bl, "Config: %s ",
1167 udev->dev_config[0] ? udev->dev_config : "NULL"); 1150 udev->dev_config[0] ? udev->dev_config : "NULL");
1168 bl += sprintf(b + bl, "Size: %zu ", udev->dev_size); 1151 bl += sprintf(b + bl, "Size: %zu\n", udev->dev_size);
1169 bl += sprintf(b + bl, "Cmd Time Out: %lu\n",
1170 udev->cmd_time_out / MSEC_PER_SEC);
1171 1152
1172 return bl; 1153 return bl;
1173} 1154}
@@ -1186,7 +1167,48 @@ tcmu_parse_cdb(struct se_cmd *cmd)
1186 return passthrough_parse_cdb(cmd, tcmu_queue_cmd); 1167 return passthrough_parse_cdb(cmd, tcmu_queue_cmd);
1187} 1168}
1188 1169
1189static const struct target_backend_ops tcmu_ops = { 1170static ssize_t tcmu_cmd_time_out_show(struct config_item *item, char *page)
1171{
1172 struct se_dev_attrib *da = container_of(to_config_group(item),
1173 struct se_dev_attrib, da_group);
1174 struct tcmu_dev *udev = container_of(da->da_dev,
1175 struct tcmu_dev, se_dev);
1176
1177 return snprintf(page, PAGE_SIZE, "%lu\n", udev->cmd_time_out / MSEC_PER_SEC);
1178}
1179
1180static ssize_t tcmu_cmd_time_out_store(struct config_item *item, const char *page,
1181 size_t count)
1182{
1183 struct se_dev_attrib *da = container_of(to_config_group(item),
1184 struct se_dev_attrib, da_group);
1185 struct tcmu_dev *udev = container_of(da->da_dev,
1186 struct tcmu_dev, se_dev);
1187 u32 val;
1188 int ret;
1189
1190 if (da->da_dev->export_count) {
1191 pr_err("Unable to set tcmu cmd_time_out while exports exist\n");
1192 return -EINVAL;
1193 }
1194
1195 ret = kstrtou32(page, 0, &val);
1196 if (ret < 0)
1197 return ret;
1198
1199 if (!val) {
1200 pr_err("Illegal value for cmd_time_out\n");
1201 return -EINVAL;
1202 }
1203
1204 udev->cmd_time_out = val * MSEC_PER_SEC;
1205 return count;
1206}
1207CONFIGFS_ATTR(tcmu_, cmd_time_out);
1208
1209static struct configfs_attribute **tcmu_attrs;
1210
1211static struct target_backend_ops tcmu_ops = {
1190 .name = "user", 1212 .name = "user",
1191 .owner = THIS_MODULE, 1213 .owner = THIS_MODULE,
1192 .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, 1214 .transport_flags = TRANSPORT_FLAG_PASSTHROUGH,
@@ -1200,12 +1222,12 @@ static const struct target_backend_ops tcmu_ops = {
1200 .show_configfs_dev_params = tcmu_show_configfs_dev_params, 1222 .show_configfs_dev_params = tcmu_show_configfs_dev_params,
1201 .get_device_type = sbc_get_device_type, 1223 .get_device_type = sbc_get_device_type,
1202 .get_blocks = tcmu_get_blocks, 1224 .get_blocks = tcmu_get_blocks,
1203 .tb_dev_attrib_attrs = passthrough_attrib_attrs, 1225 .tb_dev_attrib_attrs = NULL,
1204}; 1226};
1205 1227
1206static int __init tcmu_module_init(void) 1228static int __init tcmu_module_init(void)
1207{ 1229{
1208 int ret; 1230 int ret, i, len = 0;
1209 1231
1210 BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); 1232 BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0);
1211 1233
@@ -1227,12 +1249,31 @@ static int __init tcmu_module_init(void)
1227 goto out_unreg_device; 1249 goto out_unreg_device;
1228 } 1250 }
1229 1251
1252 for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) {
1253 len += sizeof(struct configfs_attribute *);
1254 }
1255 len += sizeof(struct configfs_attribute *) * 2;
1256
1257 tcmu_attrs = kzalloc(len, GFP_KERNEL);
1258 if (!tcmu_attrs) {
1259 ret = -ENOMEM;
1260 goto out_unreg_genl;
1261 }
1262
1263 for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) {
1264 tcmu_attrs[i] = passthrough_attrib_attrs[i];
1265 }
1266 tcmu_attrs[i] = &tcmu_attr_cmd_time_out;
1267 tcmu_ops.tb_dev_attrib_attrs = tcmu_attrs;
1268
1230 ret = transport_backend_register(&tcmu_ops); 1269 ret = transport_backend_register(&tcmu_ops);
1231 if (ret) 1270 if (ret)
1232 goto out_unreg_genl; 1271 goto out_attrs;
1233 1272
1234 return 0; 1273 return 0;
1235 1274
1275out_attrs:
1276 kfree(tcmu_attrs);
1236out_unreg_genl: 1277out_unreg_genl:
1237 genl_unregister_family(&tcmu_genl_family); 1278 genl_unregister_family(&tcmu_genl_family);
1238out_unreg_device: 1279out_unreg_device:
@@ -1246,6 +1287,7 @@ out_free_cache:
1246static void __exit tcmu_module_exit(void) 1287static void __exit tcmu_module_exit(void)
1247{ 1288{
1248 target_backend_unregister(&tcmu_ops); 1289 target_backend_unregister(&tcmu_ops);
1290 kfree(tcmu_attrs);
1249 genl_unregister_family(&tcmu_genl_family); 1291 genl_unregister_family(&tcmu_genl_family);
1250 root_device_unregister(tcmu_root_device); 1292 root_device_unregister(tcmu_root_device);
1251 kmem_cache_destroy(tcmu_cmd_cache); 1293 kmem_cache_destroy(tcmu_cmd_cache);