z2ram_register_disk() stores the freshly allocated gendisk in z2ram_gendisk[minor] before calling add_disk(). If add_disk() fails, it drops the reference with put_disk() but leaves the array entry pointing at the now-freed gendisk instead of clearing it. z2_init() only aborts and unwinds when minor 0 fails; a later minor failing just leaves that dangling entry in place and the module still reports successful load. z2_exit() then unconditionally calls del_gendisk()/put_disk() on every entry in z2ram_gendisk[], so module removal walks into the stale pointer left behind by the earlier failure. Clear the array entry when add_disk() fails, and skip NULL entries in z2_exit(), matching how a minor that never registered is represented. Fixes: 76487f024142 ("z2ram: use separate gendisk for the different modes") Signed-off-by: Muhammad Bilal --- drivers/block/z2ram.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index b216cba1c3bf..e7fabaa53ba1 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -333,8 +333,10 @@ static int z2ram_register_disk(int minor) z2ram_gendisk[minor] = disk; err = add_disk(disk); - if (err) + if (err) { + z2ram_gendisk[minor] = NULL; put_disk(disk); + } return err; } @@ -379,6 +381,8 @@ static void __exit z2_exit(void) unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); for (i = 0; i < Z2MINOR_COUNT; i++) { + if (!z2ram_gendisk[i]) + continue; del_gendisk(z2ram_gendisk[i]); put_disk(z2ram_gendisk[i]); } -- 2.55.0