aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2008-08-21 13:46:39 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-08-21 13:46:41 -0400
commit91c36919a456589f4f073671474a1f899e0d3c2b (patch)
tree63cb2ee1afd9b00bf2ea4959482d58f402bb21f3 /drivers/s390/block
parent49fd38bdaa96f093fcad3176a781a4d0de8f8602 (diff)
[S390] cio: call ccw driver notify function with lock held
Calling a ccw driver's notify function without the ccw device lock held opens up a race window between discovery and handling of a change in the device operational state. As a result, the device driver may encounter unexpected device malfunction, leading to out-of-retry situations or similar. Remove race by extending the ccw device lock from state change discovery to the calling of the notify function. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 1b6c52ef7339..acb78017e7d0 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2333,13 +2333,11 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2333{ 2333{
2334 struct dasd_device *device; 2334 struct dasd_device *device;
2335 struct dasd_ccw_req *cqr; 2335 struct dasd_ccw_req *cqr;
2336 unsigned long flags;
2337 int ret; 2336 int ret;
2338 2337
2339 device = dasd_device_from_cdev(cdev); 2338 device = dasd_device_from_cdev_locked(cdev);
2340 if (IS_ERR(device)) 2339 if (IS_ERR(device))
2341 return 0; 2340 return 0;
2342 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
2343 ret = 0; 2341 ret = 0;
2344 switch (event) { 2342 switch (event) {
2345 case CIO_GONE: 2343 case CIO_GONE:
@@ -2369,7 +2367,6 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2369 ret = 1; 2367 ret = 1;
2370 break; 2368 break;
2371 } 2369 }
2372 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
2373 dasd_put_device(device); 2370 dasd_put_device(device);
2374 return ret; 2371 return ret;
2375} 2372}