diff options
-rw-r--r-- | drivers/target/target_core_user.c | 94 |
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 | ||
1047 | enum { | 1048 | enum { |
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 | ||
1052 | static match_table_t tokens = { | 1053 | static 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 | ||
1189 | static const struct target_backend_ops tcmu_ops = { | 1170 | static 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 | |||
1180 | static 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 | } | ||
1207 | CONFIGFS_ATTR(tcmu_, cmd_time_out); | ||
1208 | |||
1209 | static struct configfs_attribute **tcmu_attrs; | ||
1210 | |||
1211 | static 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 | ||
1206 | static int __init tcmu_module_init(void) | 1228 | static 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 | ||
1275 | out_attrs: | ||
1276 | kfree(tcmu_attrs); | ||
1236 | out_unreg_genl: | 1277 | out_unreg_genl: |
1237 | genl_unregister_family(&tcmu_genl_family); | 1278 | genl_unregister_family(&tcmu_genl_family); |
1238 | out_unreg_device: | 1279 | out_unreg_device: |
@@ -1246,6 +1287,7 @@ out_free_cache: | |||
1246 | static void __exit tcmu_module_exit(void) | 1287 | static 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); |