mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
tcmu: Convert cmd_time_out into backend device attribute
Instead of putting cmd_time_out under ../target/core/user_0/foo/control, which has historically been used by parameters needed for initial backend device configuration, go ahead and move cmd_time_out into a backend device attribute. In order to do this, tcmu_module_init() has been updated to create a local struct configfs_attribute **tcmu_attrs, that is based upon the existing passthrough_attrib_attrs along with the new cmd_time_out attribute. Once **tcm_attrs has been setup, go ahead and point it at tcmu_ops->tb_dev_attrib_attrs so it's picked up by target-core. Also following MNC's previous change, ->cmd_time_out is stored in milliseconds but exposed via configfs in seconds. Also, note this patch restricts the modification of ->cmd_time_out to before + after the TCMU device has been configured, but not while it has active fabric exports. Cc: Mike Christie <mchristi@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
af980e46a2
commit
7d7a743543
@ -28,6 +28,7 @@
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/configfs.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <scsi/scsi_common.h>
|
||||
#include <scsi/scsi_proto.h>
|
||||
@ -1046,7 +1047,7 @@ static void tcmu_free_device(struct se_device *dev)
|
||||
|
||||
enum {
|
||||
Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors,
|
||||
Opt_cmd_time_out, Opt_err,
|
||||
Opt_err,
|
||||
};
|
||||
|
||||
static match_table_t tokens = {
|
||||
@ -1054,7 +1055,6 @@ static match_table_t tokens = {
|
||||
{Opt_dev_size, "dev_size=%u"},
|
||||
{Opt_hw_block_size, "hw_block_size=%u"},
|
||||
{Opt_hw_max_sectors, "hw_max_sectors=%u"},
|
||||
{Opt_cmd_time_out, "cmd_time_out=%u"},
|
||||
{Opt_err, NULL}
|
||||
};
|
||||
|
||||
@ -1121,23 +1121,6 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev,
|
||||
if (ret < 0)
|
||||
pr_err("kstrtoul() failed for dev_size=\n");
|
||||
break;
|
||||
case Opt_cmd_time_out:
|
||||
if (tcmu_dev_configured(udev)) {
|
||||
pr_err("Can not update cmd_time_out after device has been configured.\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
arg_p = match_strdup(&args[0]);
|
||||
if (!arg_p) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
ret = kstrtouint(arg_p, 0, &udev->cmd_time_out);
|
||||
kfree(arg_p);
|
||||
if (ret < 0)
|
||||
pr_err("kstrtouint() failed for cmd_time_out=\n");
|
||||
udev->cmd_time_out *= MSEC_PER_SEC;
|
||||
break;
|
||||
case Opt_hw_block_size:
|
||||
ret = tcmu_set_dev_attrib(&args[0],
|
||||
&(dev->dev_attrib.hw_block_size));
|
||||
@ -1165,9 +1148,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b)
|
||||
|
||||
bl = sprintf(b + bl, "Config: %s ",
|
||||
udev->dev_config[0] ? udev->dev_config : "NULL");
|
||||
bl += sprintf(b + bl, "Size: %zu ", udev->dev_size);
|
||||
bl += sprintf(b + bl, "Cmd Time Out: %lu\n",
|
||||
udev->cmd_time_out / MSEC_PER_SEC);
|
||||
bl += sprintf(b + bl, "Size: %zu\n", udev->dev_size);
|
||||
|
||||
return bl;
|
||||
}
|
||||
@ -1186,7 +1167,48 @@ tcmu_parse_cdb(struct se_cmd *cmd)
|
||||
return passthrough_parse_cdb(cmd, tcmu_queue_cmd);
|
||||
}
|
||||
|
||||
static const struct target_backend_ops tcmu_ops = {
|
||||
static ssize_t tcmu_cmd_time_out_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct se_dev_attrib *da = container_of(to_config_group(item),
|
||||
struct se_dev_attrib, da_group);
|
||||
struct tcmu_dev *udev = container_of(da->da_dev,
|
||||
struct tcmu_dev, se_dev);
|
||||
|
||||
return snprintf(page, PAGE_SIZE, "%lu\n", udev->cmd_time_out / MSEC_PER_SEC);
|
||||
}
|
||||
|
||||
static ssize_t tcmu_cmd_time_out_store(struct config_item *item, const char *page,
|
||||
size_t count)
|
||||
{
|
||||
struct se_dev_attrib *da = container_of(to_config_group(item),
|
||||
struct se_dev_attrib, da_group);
|
||||
struct tcmu_dev *udev = container_of(da->da_dev,
|
||||
struct tcmu_dev, se_dev);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (da->da_dev->export_count) {
|
||||
pr_err("Unable to set tcmu cmd_time_out while exports exist\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kstrtou32(page, 0, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!val) {
|
||||
pr_err("Illegal value for cmd_time_out\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
udev->cmd_time_out = val * MSEC_PER_SEC;
|
||||
return count;
|
||||
}
|
||||
CONFIGFS_ATTR(tcmu_, cmd_time_out);
|
||||
|
||||
static struct configfs_attribute **tcmu_attrs;
|
||||
|
||||
static struct target_backend_ops tcmu_ops = {
|
||||
.name = "user",
|
||||
.owner = THIS_MODULE,
|
||||
.transport_flags = TRANSPORT_FLAG_PASSTHROUGH,
|
||||
@ -1200,12 +1222,12 @@ static const struct target_backend_ops tcmu_ops = {
|
||||
.show_configfs_dev_params = tcmu_show_configfs_dev_params,
|
||||
.get_device_type = sbc_get_device_type,
|
||||
.get_blocks = tcmu_get_blocks,
|
||||
.tb_dev_attrib_attrs = passthrough_attrib_attrs,
|
||||
.tb_dev_attrib_attrs = NULL,
|
||||
};
|
||||
|
||||
static int __init tcmu_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
int ret, i, len = 0;
|
||||
|
||||
BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0);
|
||||
|
||||
@ -1227,12 +1249,31 @@ static int __init tcmu_module_init(void)
|
||||
goto out_unreg_device;
|
||||
}
|
||||
|
||||
for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) {
|
||||
len += sizeof(struct configfs_attribute *);
|
||||
}
|
||||
len += sizeof(struct configfs_attribute *) * 2;
|
||||
|
||||
tcmu_attrs = kzalloc(len, GFP_KERNEL);
|
||||
if (!tcmu_attrs) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unreg_genl;
|
||||
}
|
||||
|
||||
for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) {
|
||||
tcmu_attrs[i] = passthrough_attrib_attrs[i];
|
||||
}
|
||||
tcmu_attrs[i] = &tcmu_attr_cmd_time_out;
|
||||
tcmu_ops.tb_dev_attrib_attrs = tcmu_attrs;
|
||||
|
||||
ret = transport_backend_register(&tcmu_ops);
|
||||
if (ret)
|
||||
goto out_unreg_genl;
|
||||
goto out_attrs;
|
||||
|
||||
return 0;
|
||||
|
||||
out_attrs:
|
||||
kfree(tcmu_attrs);
|
||||
out_unreg_genl:
|
||||
genl_unregister_family(&tcmu_genl_family);
|
||||
out_unreg_device:
|
||||
@ -1246,6 +1287,7 @@ out_free_cache:
|
||||
static void __exit tcmu_module_exit(void)
|
||||
{
|
||||
target_backend_unregister(&tcmu_ops);
|
||||
kfree(tcmu_attrs);
|
||||
genl_unregister_family(&tcmu_genl_family);
|
||||
root_device_unregister(tcmu_root_device);
|
||||
kmem_cache_destroy(tcmu_cmd_cache);
|
||||
|
Loading…
Reference in New Issue
Block a user