[PATCH] nvme: avoid connecting to the same subsystem from the same path gain.

Guilherme G. Piccoli gpiccoli at linux.vnet.ibm.com
Wed Apr 26 08:33:03 PDT 2017


On 04/24/2017 10:26 AM, Guan Junxiong wrote:
> From: Junxiong Guan <guanjunxiong at huawei.com>
> 
> Current code has the defect that we will get more /dev/nvme#n#
> generated in the /dev node if we execute the same connect command
> with nvme-cli tools more than once. To fix it, this patch iterate
> the allocated controller list to check if the same subsystem with
> the same path of topology exists before create new controller. If
> exists, just log and return. The path identifier is combined with
> tranport type, transport address, target subsystem nqn and hostnqn.

Agree with you, and I'm curious too on why this is considered a feature
instead of a problematic behavior.

Minor suggestions to the patch:

1) On title: s/gain/again/g

2) s/with nvme-cli tools/with nvme-cli tool/g

3) s/tranport/transport/g

Thanks for the good fix!
Cheers,


Guilherme

> ---
>  drivers/nvme/host/core.c   | 33 +++++++++++++++++++++++++++++++++
>  drivers/nvme/host/nvme.h   |  1 +
>  drivers/nvme/host/rdma.c   |  8 ++++++++
>  drivers/nvme/target/loop.c |  6 ++++++
>  4 files changed, 48 insertions(+)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 6dcd7a123b50..1d3a077cba78 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -2318,6 +2318,39 @@ void nvme_put_ctrl(struct nvme_ctrl *ctrl)
>  }
>  EXPORT_SYMBOL_GPL(nvme_put_ctrl);
> 
> +bool nvme_is_ctrl_existed(const struct nvmf_ctrl_options *opts)
> +{
> +	struct nvme_ctrl *ctrl;
> +	bool find = false;
> +
> +	spin_lock(&dev_list_lock);
> +	list_for_each_entry(ctrl, &nvme_ctrl_list, node) {
> +		if(strcmp(ctrl->opts->transport, opts->transport))
> +			continue;
> +		if((opts->mask&NVMF_OPT_TRADDR) \
> +				&& (ctrl->opts->traddr != NULL)) {
> +			if(strcmp(ctrl->opts->traddr, opts->traddr))
> +				continue;
> +		}
> +		if((opts->mask & NVMF_OPT_TRSVCID) \
> +				&& (ctrl->opts->trsvcid != NULL)) {
> +			if(strcmp(ctrl->opts->trsvcid, opts->trsvcid))
> +				continue;
> +		}
> +		if(strcmp(ctrl->opts->subsysnqn, opts->subsysnqn))
> +			continue;
> +		if(strcmp(ctrl->opts->host->nqn, opts->host->nqn))
> +			continue;
> +		find = true;
> +		break;
> +	}
> +	spin_unlock(&dev_list_lock);
> +
> +	return find;
> +}
> +EXPORT_SYMBOL_GPL(nvme_is_ctrl_existed);
> +
> +
>  /*
>   * Initialize a NVMe controller structures.  This needs to be called during
>   * earliest initialization so that we have the initialized structured around
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index 72dc98f6a6c6..07635522b691 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -261,6 +261,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
>  int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
>  int nvme_enable_ctrl(struct nvme_ctrl *ctrl, u64 cap);
>  int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
> +bool nvme_is_ctrl_existed(const struct nvmf_ctrl_options *opts);
>  int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
>  		const struct nvme_ctrl_ops *ops, unsigned long quirks);
>  void nvme_uninit_ctrl(struct nvme_ctrl *ctrl);
> diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
> index 53b611f9ba5d..6696ed0fdd87 100644
> --- a/drivers/nvme/host/rdma.c
> +++ b/drivers/nvme/host/rdma.c
> @@ -1858,6 +1858,14 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
>  	bool changed;
>  	char *port;
> 
> +	if(!(opts->mask & NVMF_OPT_TRSVCID))
> +		opts->trsvcid = __stringify(NVME_RDMA_IP_PORT);
> +	if(nvme_is_ctrl_existed(opts)) {
> +		pr_err("connect to the same subsystem from the same path\n");
> +		ret = -EBUSY;
> +		return ERR_PTR(ret);
> +	}
> +
>  	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
>  	if (!ctrl)
>  		return ERR_PTR(-ENOMEM);
> diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c
> index 8260ee1f8e48..1e0fa2397aa7 100644
> --- a/drivers/nvme/target/loop.c
> +++ b/drivers/nvme/target/loop.c
> @@ -621,6 +621,12 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
>  	bool changed;
>  	int ret;
> 
> +	if(nvme_is_ctrl_existed(opts)) {
> +		pr_err("connect to the same subsystem from the same path\n");
> +		ret = -EBUSY;
> +		return ERR_PTR(ret);
> +	}
> +
>  	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
>  	if (!ctrl)
>  		return ERR_PTR(-ENOMEM);
> 




More information about the Linux-nvme mailing list