diff mbox

[RFC] enclosure: fix sysfs symlinks creation when using multipath

Message ID 1486476528-27580-2-git-send-email-mlombard@redhat.com (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Maurizio Lombardi Feb. 7, 2017, 2:08 p.m. UTC
With multipath, it may happen that the same device is passed
to enclosure_add_device() multiple times and that the enclosure_add_links()
function fails to create the symlinks because the device's sysfs
directory entry is still NULL.
In this case, the links will never be created because all the subsequent
calls to enclosure_add_device() will immediately fail with EEXIST.

This patch modifies the code so the driver will detect this condition
and will retry to create the symlinks when enclosure_add_device() is called.

Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
---
 drivers/misc/enclosure.c  | 16 ++++++++++++++--
 include/linux/enclosure.h |  1 +
 2 files changed, 15 insertions(+), 2 deletions(-)

Comments

Maurizio Lombardi Feb. 16, 2017, 1:13 p.m. UTC | #1
Hi James,

have you noticed this patch?


Dne 7.2.2017 v 15:08 Maurizio Lombardi napsal(a):
> With multipath, it may happen that the same device is passed
> to enclosure_add_device() multiple times and that the enclosure_add_links()
> function fails to create the symlinks because the device's sysfs
> directory entry is still NULL.
> In this case, the links will never be created because all the subsequent
> calls to enclosure_add_device() will immediately fail with EEXIST.
> 
> This patch modifies the code so the driver will detect this condition
> and will retry to create the symlinks when enclosure_add_device() is called.
> 
> Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
> ---
>  drivers/misc/enclosure.c  | 16 ++++++++++++++--
>  include/linux/enclosure.h |  1 +
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
> index 65fed71..a856c98 100644
> --- a/drivers/misc/enclosure.c
> +++ b/drivers/misc/enclosure.c
> @@ -375,21 +375,33 @@ int enclosure_add_device(struct enclosure_device *edev, int component,
>  			 struct device *dev)
>  {
>  	struct enclosure_component *cdev;
> +	int error;
>  
>  	if (!edev || component >= edev->components)
>  		return -EINVAL;
>  
>  	cdev = &edev->component[component];
>  
> -	if (cdev->dev == dev)
> +	if (cdev->dev == dev) {
> +		if (!cdev->links_created) {
> +			error = enclosure_add_links(cdev);
> +			if (!error)
> +				cdev->links_created = 1;
> +		}
>  		return -EEXIST;
> +	}
>  
>  	if (cdev->dev)
>  		enclosure_remove_links(cdev);
>  
>  	put_device(cdev->dev);
>  	cdev->dev = get_device(dev);
> -	return enclosure_add_links(cdev);
> +	error = enclosure_add_links(cdev);
> +	if (!error)
> +		cdev->links_created = 1;
> +	else
> +		cdev->links_created = 0;
> +	return error;
>  }
>  EXPORT_SYMBOL_GPL(enclosure_add_device);
>  
> diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
> index a4cf57c..c3bdc4c 100644
> --- a/include/linux/enclosure.h
> +++ b/include/linux/enclosure.h
> @@ -97,6 +97,7 @@ struct enclosure_component {
>  	struct device cdev;
>  	struct device *dev;
>  	enum enclosure_component_type type;
> +	int links_created;
>  	int number;
>  	int fault;
>  	int active;
>
Douglas Miller June 16, 2017, 12:40 p.m. UTC | #2
On 02/07/2017 08:08 AM, Maurizio Lombardi wrote:
> With multipath, it may happen that the same device is passed
> to enclosure_add_device() multiple times and that the enclosure_add_links()
> function fails to create the symlinks because the device's sysfs
> directory entry is still NULL.
> In this case, the links will never be created because all the subsequent
> calls to enclosure_add_device() will immediately fail with EEXIST.
>
> This patch modifies the code so the driver will detect this condition
> and will retry to create the symlinks when enclosure_add_device() is called.
>
> Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
> ---
>   drivers/misc/enclosure.c  | 16 ++++++++++++++--
>   include/linux/enclosure.h |  1 +
>   2 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
> index 65fed71..a856c98 100644
> --- a/drivers/misc/enclosure.c
> +++ b/drivers/misc/enclosure.c
> @@ -375,21 +375,33 @@ int enclosure_add_device(struct enclosure_device *edev, int component,
>   			 struct device *dev)
>   {
>   	struct enclosure_component *cdev;
> +	int error;
>   
>   	if (!edev || component >= edev->components)
>   		return -EINVAL;
>   
>   	cdev = &edev->component[component];
>   
> -	if (cdev->dev == dev)
> +	if (cdev->dev == dev) {
> +		if (!cdev->links_created) {
> +			error = enclosure_add_links(cdev);
> +			if (!error)
> +				cdev->links_created = 1;
> +		}
>   		return -EEXIST;
> +	}
>   
>   	if (cdev->dev)
>   		enclosure_remove_links(cdev);
>   
>   	put_device(cdev->dev);
>   	cdev->dev = get_device(dev);
> -	return enclosure_add_links(cdev);
> +	error = enclosure_add_links(cdev);
> +	if (!error)
> +		cdev->links_created = 1;
> +	else
> +		cdev->links_created = 0;
> +	return error;
>   }
>   EXPORT_SYMBOL_GPL(enclosure_add_device);
>   
> diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
> index a4cf57c..c3bdc4c 100644
> --- a/include/linux/enclosure.h
> +++ b/include/linux/enclosure.h
> @@ -97,6 +97,7 @@ struct enclosure_component {
>   	struct device cdev;
>   	struct device *dev;
>   	enum enclosure_component_type type;
> +	int links_created;
>   	int number;
>   	int fault;
>   	int active;

Tested-by: Douglas Miller <dougmill@linux.vnet.ibm.com>

I'd like to add that we are seeing this problem with singlepath 
installations and need to get this fixed upstream as soon as possible. 
RHEL new product contains this fix and is working for us, but we need to 
be able to offer other distros as well. I am currently running this 
patch on a custom-built Ubuntu 16.04.2 kernel and it is fixing the 
problem there.

What needs to be done to get this patch accepted?

Thanks,
Doug
diff mbox

Patch

diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 65fed71..a856c98 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -375,21 +375,33 @@  int enclosure_add_device(struct enclosure_device *edev, int component,
 			 struct device *dev)
 {
 	struct enclosure_component *cdev;
+	int error;
 
 	if (!edev || component >= edev->components)
 		return -EINVAL;
 
 	cdev = &edev->component[component];
 
-	if (cdev->dev == dev)
+	if (cdev->dev == dev) {
+		if (!cdev->links_created) {
+			error = enclosure_add_links(cdev);
+			if (!error)
+				cdev->links_created = 1;
+		}
 		return -EEXIST;
+	}
 
 	if (cdev->dev)
 		enclosure_remove_links(cdev);
 
 	put_device(cdev->dev);
 	cdev->dev = get_device(dev);
-	return enclosure_add_links(cdev);
+	error = enclosure_add_links(cdev);
+	if (!error)
+		cdev->links_created = 1;
+	else
+		cdev->links_created = 0;
+	return error;
 }
 EXPORT_SYMBOL_GPL(enclosure_add_device);
 
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index a4cf57c..c3bdc4c 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -97,6 +97,7 @@  struct enclosure_component {
 	struct device cdev;
 	struct device *dev;
 	enum enclosure_component_type type;
+	int links_created;
 	int number;
 	int fault;
 	int active;