Skip to content

Commit cae5b01

Browse files
lsgunthChristoph Hellwig
authored andcommitted
nvmet: introduce the passthru configfs interface
When CONFIG_NVME_TARGET_PASSTHRU as 'passthru' directory will be added to each subsystem. The directory is similar to a namespace and has two attributes: device_path and enable. The user must set the path to the nvme controller's char device and write '1' to enable the subsystem to use passthru. Any given subsystem is prevented from enabling both a regular namespace and the passthru device. If one is enabled, enabling the other will produce an error. Signed-off-by: Logan Gunthorpe <[email protected]> Reviewed-by: Keith Busch <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent ba76af6 commit cae5b01

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

drivers/nvme/target/configfs.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,103 @@ static const struct config_item_type nvmet_namespaces_type = {
666666
.ct_owner = THIS_MODULE,
667667
};
668668

669+
#ifdef CONFIG_NVME_TARGET_PASSTHRU
670+
671+
static ssize_t nvmet_passthru_device_path_show(struct config_item *item,
672+
char *page)
673+
{
674+
struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
675+
676+
return snprintf(page, PAGE_SIZE, "%s\n", subsys->passthru_ctrl_path);
677+
}
678+
679+
static ssize_t nvmet_passthru_device_path_store(struct config_item *item,
680+
const char *page, size_t count)
681+
{
682+
struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
683+
size_t len;
684+
int ret;
685+
686+
mutex_lock(&subsys->lock);
687+
688+
ret = -EBUSY;
689+
if (subsys->passthru_ctrl)
690+
goto out_unlock;
691+
692+
ret = -EINVAL;
693+
len = strcspn(page, "\n");
694+
if (!len)
695+
goto out_unlock;
696+
697+
kfree(subsys->passthru_ctrl_path);
698+
ret = -ENOMEM;
699+
subsys->passthru_ctrl_path = kstrndup(page, len, GFP_KERNEL);
700+
if (!subsys->passthru_ctrl_path)
701+
goto out_unlock;
702+
703+
mutex_unlock(&subsys->lock);
704+
705+
return count;
706+
out_unlock:
707+
mutex_unlock(&subsys->lock);
708+
return ret;
709+
}
710+
CONFIGFS_ATTR(nvmet_passthru_, device_path);
711+
712+
static ssize_t nvmet_passthru_enable_show(struct config_item *item,
713+
char *page)
714+
{
715+
struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
716+
717+
return sprintf(page, "%d\n", subsys->passthru_ctrl ? 1 : 0);
718+
}
719+
720+
static ssize_t nvmet_passthru_enable_store(struct config_item *item,
721+
const char *page, size_t count)
722+
{
723+
struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
724+
bool enable;
725+
int ret = 0;
726+
727+
if (strtobool(page, &enable))
728+
return -EINVAL;
729+
730+
if (enable)
731+
ret = nvmet_passthru_ctrl_enable(subsys);
732+
else
733+
nvmet_passthru_ctrl_disable(subsys);
734+
735+
return ret ? ret : count;
736+
}
737+
CONFIGFS_ATTR(nvmet_passthru_, enable);
738+
739+
static struct configfs_attribute *nvmet_passthru_attrs[] = {
740+
&nvmet_passthru_attr_device_path,
741+
&nvmet_passthru_attr_enable,
742+
NULL,
743+
};
744+
745+
static const struct config_item_type nvmet_passthru_type = {
746+
.ct_attrs = nvmet_passthru_attrs,
747+
.ct_owner = THIS_MODULE,
748+
};
749+
750+
static void nvmet_add_passthru_group(struct nvmet_subsys *subsys)
751+
{
752+
config_group_init_type_name(&subsys->passthru_group,
753+
"passthru", &nvmet_passthru_type);
754+
configfs_add_default_group(&subsys->passthru_group,
755+
&subsys->group);
756+
}
757+
758+
#else /* CONFIG_NVME_TARGET_PASSTHRU */
759+
760+
static void nvmet_add_passthru_group(struct nvmet_subsys *subsys)
761+
{
762+
}
763+
764+
#endif /* CONFIG_NVME_TARGET_PASSTHRU */
765+
669766
static int nvmet_port_subsys_allow_link(struct config_item *parent,
670767
struct config_item *target)
671768
{
@@ -1125,6 +1222,8 @@ static struct config_group *nvmet_subsys_make(struct config_group *group,
11251222
configfs_add_default_group(&subsys->allowed_hosts_group,
11261223
&subsys->group);
11271224

1225+
nvmet_add_passthru_group(subsys);
1226+
11281227
return &subsys->group;
11291228
}
11301229

drivers/nvme/target/nvmet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ struct nvmet_subsys {
248248
#ifdef CONFIG_NVME_TARGET_PASSTHRU
249249
struct nvme_ctrl *passthru_ctrl;
250250
char *passthru_ctrl_path;
251+
struct config_group passthru_group;
251252
#endif /* CONFIG_NVME_TARGET_PASSTHRU */
252253
};
253254

0 commit comments

Comments
 (0)