Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755972Ab0BXIpe (ORCPT ); Wed, 24 Feb 2010 03:45:34 -0500 Received: from mtagate1.de.ibm.com ([195.212.17.161]:60718 "EHLO mtagate1.de.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755874Ab0BXIoz (ORCPT ); Wed, 24 Feb 2010 03:44:55 -0500 Message-Id: <20100224084453.481566618@de.ibm.com> User-Agent: quilt/0.48-1 Date: Wed, 24 Feb 2010 09:45:00 +0100 From: Martin Schwidefsky To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Heiko Carstens , Stefan Haberland , Martin Schwidefsky Subject: [patch 30/32] [PATCH] dasd: fix refcounting. References: <20100224084430.193562869@de.ibm.com> Content-Disposition: inline; filename=129-dasd-refcounting.diff Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3180 Lines: 101 From: Stefan Haberland 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 Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 24 +++++++++++++++--------- drivers/s390/block/dasd_devmap.c | 13 ++++++++++--- 2 files changed, 25 insertions(+), 12 deletions(-) Index: quilt-2.6/drivers/s390/block/dasd.c =================================================================== --- quilt-2.6.orig/drivers/s390/block/dasd.c 2010-02-24 09:44:27.000000000 +0100 +++ quilt-2.6/drivers/s390/block/dasd.c 2010-02-24 09:44:29.000000000 +0100 @@ -1003,12 +1003,20 @@ 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 @@ 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 @@ } 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; } Index: quilt-2.6/drivers/s390/block/dasd_devmap.c =================================================================== --- quilt-2.6.orig/drivers/s390/block/dasd_devmap.c 2010-02-24 09:28:13.000000000 +0100 +++ quilt-2.6/drivers/s390/block/dasd_devmap.c 2010-02-24 09:44:29.000000000 +0100 @@ -874,12 +874,19 @@ 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; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/