Commit 11e52a69 authored by James Bottomley's avatar James Bottomley

enclosure: fix WARN_ON removing an adapter in multi-path devices

We have peculiar problems with multi-path and enclosures: physically, we know
each bay can only be occupied by a single disk device.  However in multi-path,
it appears we have many (because each path to the device appears in Linux as a
different kernel device).  We try to fix this by only having the last seen
device show up in the bay.

Sysfs gets very annoyed if we try to manipulate links when the kobject sysfs
directory (kobj.sd) doesn't exist and drops a huge WARN_ON which most users
panic and report an oops for.  This happens on a few path removal situations
and IBM reports seeing it when one of their multi-path adapters is removed.

Add a check to enclosure device removal for the existence the sysfs directory
containing both the forward and back links so that the remnants (if any) get
removed in either direction but no scary warnings are dumped.
Reported-by: default avatarWen Xiong <wenxiong@linux.vnet.ibm.com>
Tested-by: default avatarWen Xiong <wenxiong@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 6302ce4d
...@@ -202,16 +202,17 @@ static void enclosure_remove_links(struct enclosure_component *cdev) ...@@ -202,16 +202,17 @@ static void enclosure_remove_links(struct enclosure_component *cdev)
{ {
char name[ENCLOSURE_NAME_SIZE]; char name[ENCLOSURE_NAME_SIZE];
enclosure_link_name(cdev, name);
/* /*
* In odd circumstances, like multipath devices, something else may * In odd circumstances, like multipath devices, something else may
* already have removed the links, so check for this condition first. * already have removed the links, so check for this condition first.
*/ */
if (!cdev->dev->kobj.sd) if (cdev->dev->kobj.sd)
return; sysfs_remove_link(&cdev->dev->kobj, name);
enclosure_link_name(cdev, name); if (cdev->cdev.kobj.sd)
sysfs_remove_link(&cdev->dev->kobj, name); sysfs_remove_link(&cdev->cdev.kobj, "device");
sysfs_remove_link(&cdev->cdev.kobj, "device");
} }
static int enclosure_add_links(struct enclosure_component *cdev) static int enclosure_add_links(struct enclosure_component *cdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment