diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2015-07-10 11:47:09 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2015-07-13 12:02:14 +0300 |
commit | f81a49d13b3014c2b7c424628779a8af93f25c04 (patch) | |
tree | 5acd89ff363fcf1f1da4b082a798aed0709f5efe /drivers/s390/block/dasd_alias.c | |
parent | f9c87a6f46d508eae0d9ae640be98d50f237f827 (diff) | |
download | linux-f81a49d13b3014c2b7c424628779a8af93f25c04.tar.xz |
s390/dasd: fix kernel panic when alias is set offline
The dasd device driver selects which (alias or base) device is used
for a given requests when the request is build. If the chosen alias
device is set offline before the request gets queued to the device
queue the starting function may use device structures that are
already freed. This might lead to a hanging offline process or a
kernel panic.
Add a check to the starting function that returns the request to the
upper layer if the device is already in offline processing.
In addition to that prevent that an alias device that's already in
offline processing gets chosen as start device.
Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <peter.oberparleiter@linux.vnet.ibm.com>
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_alias.c')
-rw-r--r-- | drivers/s390/block/dasd_alias.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index a2597e683e79..ee3a6faae22a 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -699,7 +699,8 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) struct dasd_device, alias_list); spin_unlock_irqrestore(&lcu->lock, flags); alias_priv = (struct dasd_eckd_private *) alias_device->private; - if ((alias_priv->count < private->count) && !alias_device->stopped) + if ((alias_priv->count < private->count) && !alias_device->stopped && + !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags)) return alias_device; else return NULL; |