mirror of
https://github.com/torvalds/linux.git
synced 2024-12-16 16:12:52 +00:00
[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>
This commit is contained in:
parent
9eb251225a
commit
589c74d507
@ -1003,12 +1003,20 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
|
||||
return;
|
||||
}
|
||||
|
||||
device = (struct dasd_device *) cqr->startdev;
|
||||
if (device == NULL ||
|
||||
device != dasd_device_from_cdev_locked(cdev) ||
|
||||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
|
||||
device = dasd_device_from_cdev_locked(cdev);
|
||||
if (IS_ERR(device)) {
|
||||
DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
|
||||
"unable to get device from cdev");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cqr->startdev ||
|
||||
device != cqr->startdev ||
|
||||
strncmp(cqr->startdev->discipline->ebcname,
|
||||
(char *) &cqr->magic, 4)) {
|
||||
DBF_EVENT_DEVID(DBF_DEBUG, cdev, "%s",
|
||||
"invalid device in request");
|
||||
dasd_put_device(device);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2291,11 +2299,6 @@ static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
|
||||
if (ret)
|
||||
pr_warning("%s: Setting the DASD online failed with rc=%d\n",
|
||||
dev_name(&cdev->dev), ret);
|
||||
else {
|
||||
struct dasd_device *device = dasd_device_from_cdev(cdev);
|
||||
wait_event(dasd_init_waitq, _wait_for_device(device));
|
||||
dasd_put_device(device);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2430,6 +2433,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
|
||||
} else
|
||||
pr_debug("dasd_generic device %s found\n",
|
||||
dev_name(&cdev->dev));
|
||||
|
||||
wait_event(dasd_init_waitq, _wait_for_device(device));
|
||||
|
||||
dasd_put_device(device);
|
||||
return rc;
|
||||
}
|
||||
|
@ -874,12 +874,19 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr,
|
||||
ssize_t len;
|
||||
|
||||
device = dasd_device_from_cdev(to_ccwdev(dev));
|
||||
if (!IS_ERR(device) && device->discipline) {
|
||||
if (IS_ERR(device))
|
||||
goto out;
|
||||
else if (!device->discipline) {
|
||||
dasd_put_device(device);
|
||||
goto out;
|
||||
} else {
|
||||
len = snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
device->discipline->name);
|
||||
dasd_put_device(device);
|
||||
} else
|
||||
len = snprintf(buf, PAGE_SIZE, "none\n");
|
||||
return len;
|
||||
}
|
||||
out:
|
||||
len = snprintf(buf, PAGE_SIZE, "none\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user