diff mbox

[v3] tcmu: Fix dev_config_store

Message ID 1499962660-41860-1-git-send-email-bryantly@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Bryant G. Ly July 13, 2017, 4:17 p.m. UTC
Currently when there is a reconfig, the uio_info->name
does not get updated to reflect the change in the dev_config
name change.

On restart tcmu-runner there will be a mismatch between
the dev_config string in uio and the tcmu structure that contains
the string. When this occurs it'll reload the one in uio
and you lose the reconfigured device path.

v2: Created a helper function for the updating of uio_info
v3: Free the old string

Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
---
 drivers/target/target_core_user.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

Comments

Mike Christie July 13, 2017, 6:12 p.m. UTC | #1
On 07/13/2017 11:17 AM, Bryant G. Ly wrote:
> Currently when there is a reconfig, the uio_info->name
> does not get updated to reflect the change in the dev_config
> name change.
> 
> On restart tcmu-runner there will be a mismatch between
> the dev_config string in uio and the tcmu structure that contains
> the string. When this occurs it'll reload the one in uio
> and you lose the reconfigured device path.
> 
> v2: Created a helper function for the updating of uio_info
> v3: Free the old string
> 
> Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
> ---
>  drivers/target/target_core_user.c | 34 ++++++++++++++++++++++++++--------
>  1 file changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
> index 2f17d80..f699ef2 100644
> --- a/drivers/target/target_core_user.c
> +++ b/drivers/target/target_core_user.c
> @@ -1419,19 +1419,14 @@ free_skb:
>  	return ret;
>  }
>  
> -static int tcmu_configure_device(struct se_device *dev)
> +static int tcmu_update_uio_info(struct tcmu_dev *udev)
>  {
> -	struct tcmu_dev *udev = TCMU_DEV(dev);
>  	struct tcmu_hba *hba = udev->hba->hba_ptr;
>  	struct uio_info *info;
> -	struct tcmu_mailbox *mb;
> -	size_t size;
> -	size_t used;
> -	int ret = 0;
> +	size_t size, used;
>  	char *str;
>  
>  	info = &udev->uio_info;
> -
>  	size = snprintf(NULL, 0, "tcm-user/%u/%s/%s", hba->host_id, udev->name,
>  			udev->dev_config);
>  	size += 1; /* for \0 */
> @@ -1440,12 +1435,29 @@ static int tcmu_configure_device(struct se_device *dev)
>  		return -ENOMEM;
>  
>  	used = snprintf(str, size, "tcm-user/%u/%s", hba->host_id, udev->name);
> -
>  	if (udev->dev_config[0])
>  		snprintf(str + used, size - used, "/%s", udev->dev_config);
>  
> +	if (info->name)
> +		kfree(info->name);

kfree does a null check for you, so we normally just call it without the
extra check.

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 2f17d80..f699ef2 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1419,19 +1419,14 @@  free_skb:
 	return ret;
 }
 
-static int tcmu_configure_device(struct se_device *dev)
+static int tcmu_update_uio_info(struct tcmu_dev *udev)
 {
-	struct tcmu_dev *udev = TCMU_DEV(dev);
 	struct tcmu_hba *hba = udev->hba->hba_ptr;
 	struct uio_info *info;
-	struct tcmu_mailbox *mb;
-	size_t size;
-	size_t used;
-	int ret = 0;
+	size_t size, used;
 	char *str;
 
 	info = &udev->uio_info;
-
 	size = snprintf(NULL, 0, "tcm-user/%u/%s/%s", hba->host_id, udev->name,
 			udev->dev_config);
 	size += 1; /* for \0 */
@@ -1440,12 +1435,29 @@  static int tcmu_configure_device(struct se_device *dev)
 		return -ENOMEM;
 
 	used = snprintf(str, size, "tcm-user/%u/%s", hba->host_id, udev->name);
-
 	if (udev->dev_config[0])
 		snprintf(str + used, size - used, "/%s", udev->dev_config);
 
+	if (info->name)
+		kfree(info->name);
 	info->name = str;
 
+	return 0;
+}
+
+static int tcmu_configure_device(struct se_device *dev)
+{
+	struct tcmu_dev *udev = TCMU_DEV(dev);
+	struct uio_info *info;
+	struct tcmu_mailbox *mb;
+	int ret = 0;
+
+	ret = tcmu_update_uio_info(udev);
+	if (ret)
+		return ret;
+
+	info = &udev->uio_info;
+
 	udev->mb_addr = vzalloc(CMDR_SIZE);
 	if (!udev->mb_addr) {
 		ret = -ENOMEM;
@@ -1787,6 +1799,12 @@  static ssize_t tcmu_dev_config_store(struct config_item *item, const char *page,
 			pr_err("Unable to reconfigure device\n");
 			return ret;
 		}
+		strlcpy(udev->dev_config, page, TCMU_CONFIG_LEN);
+
+		ret = tcmu_update_uio_info(udev);
+		if (ret)
+			return ret;
+		return count;
 	}
 	strlcpy(udev->dev_config, page, TCMU_CONFIG_LEN);