aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
authorStefan Haberland <sth@linux.vnet.ibm.com>2016-09-20 10:42:38 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-09-26 16:45:29 +0200
commitc020d722b110a44c613ef71e657e6dd4116e09d9 (patch)
tree5fc0f6d62335cb7075f6a162380ee54c1b3ea069 /drivers/s390/block/dasd_devmap.c
parenta9f6273ff9c80dd2c226f7a2d5c16272e5092d3e (diff)
downloadlinux-c020d722b110a44c613ef71e657e6dd4116e09d9.tar.gz
s390/dasd: fix panic during offline processing
A DASD device consists of the device itself and a discipline with a corresponding private structure. These fields are set up during online processing right after the device is created and before it is processed by the state machine and made available for I/O. During offline processing the discipline pointer and the private data gets freed within the state machine and without protection of the existing reference count. This might lead to a kernel panic because a function might have taken a device reference and accesses the discipline pointer and/or private data of the device while this is already freed. Fix by freeing the discipline pointer and the private data after ensuring that there is no reference to the device left. Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r--drivers/s390/block/dasd_devmap.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 3cdbce45e4649f..15a1a70cace90f 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -617,6 +617,7 @@ dasd_delete_device(struct dasd_device *device)
/* Wait for reference counter to drop to zero. */
wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0);
+ dasd_generic_free_discipline(device);
/* Disconnect dasd_device structure from ccw_device structure. */
cdev = device->cdev;
device->cdev = NULL;