]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
s390/dasd: fix double module refcount decrement
authorMiroslav Franc <mfranc@suse.cz>
Fri, 9 Feb 2024 12:45:22 +0000 (13:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:41:09 +0000 (07:41 +0200)
commit c3116e62ddeff79cae342147753ce596f01fcf06 upstream.

Once the discipline is associated with the device, deleting the device
takes care of decrementing the module's refcount.  Doing it manually on
this error path causes refcount to artificially decrease on each error
while it should just stay the same.

Fixes: c020d722b110 ("s390/dasd: fix panic during offline processing")
Signed-off-by: Miroslav Franc <mfranc@suse.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://lore.kernel.org/r/20240209124522.3697827-3-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[Minor context change fixed]
Signed-off-by: Feng Liu <Feng.Liu3@windriver.com>
Signed-off-by: He Zhe <Zhe.He@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/s390/block/dasd.c

index 0b09ed6ac13312459cc26f0a6205ea721a304547..a3eddca14cbfce143db6110b1c3975829f1f879f 100644 (file)
@@ -3637,12 +3637,11 @@ int dasd_generic_set_online(struct ccw_device *cdev,
                dasd_delete_device(device);
                return -EINVAL;
        }
+       device->base_discipline = base_discipline;
        if (!try_module_get(discipline->owner)) {
-               module_put(base_discipline->owner);
                dasd_delete_device(device);
                return -EINVAL;
        }
-       device->base_discipline = base_discipline;
        device->discipline = discipline;
 
        /* check_device will allocate block device if necessary */
@@ -3650,8 +3649,6 @@ int dasd_generic_set_online(struct ccw_device *cdev,
        if (rc) {
                pr_warn("%s Setting the DASD online with discipline %s failed with rc=%i\n",
                        dev_name(&cdev->dev), discipline->name, rc);
-               module_put(discipline->owner);
-               module_put(base_discipline->owner);
                dasd_delete_device(device);
                return rc;
        }