aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
authorStefan Haberland <stefan.haberland@de.ibm.com>2010-02-26 16:37:47 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-02-26 16:37:32 -0500
commit589c74d5076dd1bde13a5a36d97ca79be8bd72b2 (patch)
tree252349a17326853d7e026b357921da6192958d26 /drivers/s390/block/dasd.c
parent9eb251225ab4dbea3119cfcf4c5194eed223a740 (diff)
[S390] dasd: fix refcounting.
The function dasd_device_from_cdev returns a reference to the dasd device and increases the refcount by one. If an exception occurs, the refcount was not decreased in all cases e.g. in dasd_discipline_show. Prevent the offline processing from hang by correcting two functions to decrease the refcount even if an error occured. 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.c')
-rw-r--r--drivers/s390/block/dasd.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 56df3c5ed385..302ca14a69e5 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1003,12 +1003,20 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
1003 return; 1003 return;
1004 } 1004 }
1005 1005
1006 device = (struct dasd_device *) cqr->startdev; 1006 device = dasd_device_from_cdev_locked(cdev);
1007 if (device == NULL || 1007 if (IS_ERR(device)) {
1008 device != dasd_device_from_cdev_locked(cdev) || 1008 DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
1009 strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { 1009 "unable to get device from cdev");
1010 return;
1011 }
1012
1013 if (!cqr->startdev ||
1014 device != cqr->startdev ||
1015 strncmp(cqr->startdev->discipline->ebcname,
1016 (char *) &cqr->magic, 4)) {
1010 DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s", 1017 DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
1011 "invalid device in request"); 1018 "invalid device in request");
1019 dasd_put_device(device);
1012 return; 1020 return;
1013 } 1021 }
1014 1022
@@ -2291,11 +2299,6 @@ static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
2291 if (ret) 2299 if (ret)
2292 pr_warning("%s: Setting the DASD online failed with rc=%d\n", 2300 pr_warning("%s: Setting the DASD online failed with rc=%d\n",
2293 dev_name(&cdev->dev), ret); 2301 dev_name(&cdev->dev), ret);
2294 else {
2295 struct dasd_device *device = dasd_device_from_cdev(cdev);
2296 wait_event(dasd_init_waitq, _wait_for_device(device));
2297 dasd_put_device(device);
2298 }
2299} 2302}
2300 2303
2301/* 2304/*
@@ -2430,6 +2433,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
2430 } else 2433 } else
2431 pr_debug("dasd_generic device %s found\n", 2434 pr_debug("dasd_generic device %s found\n",
2432 dev_name(&cdev->dev)); 2435 dev_name(&cdev->dev));
2436
2437 wait_event(dasd_init_waitq, _wait_for_device(device));
2438
2433 dasd_put_device(device); 2439 dasd_put_device(device);
2434 return rc; 2440 return rc;
2435} 2441}