Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2c96f46 authored by Kai Makisara's avatar Kai Makisara Committed by James Bottomley
Browse files

[SCSI] Fix SCSI tape oops at module removal



Removing the SCSI tape module results in an oops in class_device_destroy if
any devices are present. The patch at the end of this message fixes the bug
by moving class_destroy() later in exit_st() so that the class still exists
when devices are removed. (The bug is old but class_simple_device_remove() did
nothing when the class did not exist.)

The patch also fixes a "class leak" in init_st() error path.

I would like to get this into 2.6.13 but it may be too late?

Signed-off-by: default avatarKai Makisara <kai.makisara@kolumbus.fi>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent c1a15468
Loading
Loading
Loading
Loading
+2 −6
Original line number Original line Diff line number Diff line
@@ -4149,12 +4149,10 @@ static int __init init_st(void)
			do_create_driverfs_files();
			do_create_driverfs_files();
			return 0;
			return 0;
		}
		}
		if (st_sysfs_class)
			class_destroy(st_sysfs_class);
		unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
		unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),

					 ST_MAX_TAPE_ENTRIES);
					 ST_MAX_TAPE_ENTRIES);
	}
	}
	class_destroy(st_sysfs_class);


	printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
	printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
	return 1;
	return 1;
@@ -4162,13 +4160,11 @@ static int __init init_st(void)


static void __exit exit_st(void)
static void __exit exit_st(void)
{
{
	if (st_sysfs_class)
		class_destroy(st_sysfs_class);
	st_sysfs_class = NULL;
	do_remove_driverfs_files();
	do_remove_driverfs_files();
	scsi_unregister_driver(&st_template.gendrv);
	scsi_unregister_driver(&st_template.gendrv);
	unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
	unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
				 ST_MAX_TAPE_ENTRIES);
				 ST_MAX_TAPE_ENTRIES);
	class_destroy(st_sysfs_class);
	kfree(scsi_tapes);
	kfree(scsi_tapes);
	printk(KERN_INFO "st: Unloaded.\n");
	printk(KERN_INFO "st: Unloaded.\n");
}
}