diff options
author | Kai Makisara <Kai.Makisara@kolumbus.fi> | 2005-08-02 05:21:51 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-02 11:14:36 -0400 |
commit | c2c96f46f46df072e49200a1181b3086cd2f08a6 (patch) | |
tree | fd85a89e3f3d10d7f604b45ae985ecbbc6f28fb6 /drivers/scsi | |
parent | c1a15468d58e75debc5437b2e4e12d02a89bb3a2 (diff) |
[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: Kai Makisara <kai.makisara@kolumbus.fi>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/st.c | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 0291a8fb654d..0a7839db5752 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -4149,12 +4149,10 @@ static int __init init_st(void) | |||
4149 | do_create_driverfs_files(); | 4149 | do_create_driverfs_files(); |
4150 | return 0; | 4150 | return 0; |
4151 | } | 4151 | } |
4152 | if (st_sysfs_class) | ||
4153 | class_destroy(st_sysfs_class); | ||
4154 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), | 4152 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), |
4155 | |||
4156 | ST_MAX_TAPE_ENTRIES); | 4153 | ST_MAX_TAPE_ENTRIES); |
4157 | } | 4154 | } |
4155 | class_destroy(st_sysfs_class); | ||
4158 | 4156 | ||
4159 | printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); | 4157 | printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); |
4160 | return 1; | 4158 | return 1; |
@@ -4162,13 +4160,11 @@ static int __init init_st(void) | |||
4162 | 4160 | ||
4163 | static void __exit exit_st(void) | 4161 | static void __exit exit_st(void) |
4164 | { | 4162 | { |
4165 | if (st_sysfs_class) | ||
4166 | class_destroy(st_sysfs_class); | ||
4167 | st_sysfs_class = NULL; | ||
4168 | do_remove_driverfs_files(); | 4163 | do_remove_driverfs_files(); |
4169 | scsi_unregister_driver(&st_template.gendrv); | 4164 | scsi_unregister_driver(&st_template.gendrv); |
4170 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), | 4165 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), |
4171 | ST_MAX_TAPE_ENTRIES); | 4166 | ST_MAX_TAPE_ENTRIES); |
4167 | class_destroy(st_sysfs_class); | ||
4172 | kfree(scsi_tapes); | 4168 | kfree(scsi_tapes); |
4173 | printk(KERN_INFO "st: Unloaded.\n"); | 4169 | printk(KERN_INFO "st: Unloaded.\n"); |
4174 | } | 4170 | } |