diff options
author | Stefan Haberland <sth@linux.ibm.com> | 2020-12-17 16:59:06 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-12-30 11:54:09 +0100 |
commit | 18494d12ef9b75fbec3a63e6376f452e7d0174c6 (patch) | |
tree | 96d0d7246063426c4ceaa4b181c582f897394cc4 /drivers/s390 | |
parent | 96aca84128f2f4e3b687ad523ce96d10df51c39f (diff) | |
download | linux-stable-18494d12ef9b75fbec3a63e6376f452e7d0174c6.tar.gz linux-stable-18494d12ef9b75fbec3a63e6376f452e7d0174c6.tar.bz2 linux-stable-18494d12ef9b75fbec3a63e6376f452e7d0174c6.zip |
s390/dasd: fix list corruption of pavgroup group list
commit 0ede91f83aa335da1c3ec68eb0f9e228f269f6d8 upstream.
dasd_alias_add_device() moves devices to the active_devices list in case
of a scheduled LCU update regardless if they have previously been in a
pavgroup or not.
Example: device A and B are in the same pavgroup.
Device A has already been in a pavgroup and the private->pavgroup pointer
is set and points to a valid pavgroup. While going through dasd_add_device
it is moved from the pavgroup to the active_devices list.
In parallel device B might be removed from the same pavgroup in
remove_device_from_lcu() which in turn checks if the group is empty
and deletes it accordingly because device A has already been removed from
there.
When now device A enters remove_device_from_lcu() it is tried to remove it
from the pavgroup again because the pavgroup pointer is still set and again
the empty group will be cleaned up which leads to a list corruption.
Fix by setting private->pavgroup to NULL in dasd_add_device.
If the device has been the last device on the pavgroup an empty pavgroup
remains but this will be cleaned up by the scheduled lcu_update which
iterates over all existing pavgroups.
Fixes: 8e09f21574ea ("[S390] dasd: add hyper PAV support to DASD device driver, part 1")
Cc: stable@vger.kernel.org
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd_alias.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index f841518de6c5..60344e13e87b 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -642,6 +642,7 @@ int dasd_alias_add_device(struct dasd_device *device) } if (lcu->flags & UPDATE_PENDING) { list_move(&device->alias_list, &lcu->active_devices); + private->pavgroup = NULL; _schedule_lcu_update(lcu, device); } spin_unlock_irqrestore(&lcu->lock, flags); |