summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2015-10-14 11:01:05 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-10-15 09:28:15 +0200
commit6933c35a307cad0b8b847042346dde68866d3d2a (patch)
tree04cf85271047a5689b54976954cdb955bc39f93c
parents390/spinlock: remove unneeded serializations at unlock (diff)
downloadlinux-6933c35a307cad0b8b847042346dde68866d3d2a.tar.xz
linux-6933c35a307cad0b8b847042346dde68866d3d2a.zip
s390/dasd: fix list_del corruption after lcu changes
A summary unit check occurs when the lcu updates the PAV configuration e.g. base PAV assignment or PAV mode at all. This requires the reset of the drivers internal pavgroups. Therefore the alias devices are flushed and moved via a temporary list to the active_devices list where they are not associated with a pavgroup. In conjunction with updates to the base device the pavgroup may be removed since both base_list and alias_list are empty. Unfortunately during alias flush and move to the active_device list from alias_list the pavgroup pointer is not deleted in the device private structure. This leads to a list del_corruption if another lcu_update tries to move the device in the non existent pavgroup. Fix by removing the pavgroup pointer after the alias device was moved to the active_devices list. Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/block/dasd_alias.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index fe07f3139bf6..184b1dbeb554 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -824,8 +824,11 @@ static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
* were waiting for the flush
*/
if (device == list_first_entry(&active,
- struct dasd_device, alias_list))
+ struct dasd_device, alias_list)) {
list_move(&device->alias_list, &lcu->active_devices);
+ private = (struct dasd_eckd_private *) device->private;
+ private->pavgroup = NULL;
+ }
}
spin_unlock_irqrestore(&lcu->lock, flags);
}