aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-10-04 05:32:54 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-04 14:14:16 -0400
commit5e4009ba3d5af40f5615fdb4304cc4a9947cca0a (patch)
treea6dd31cd9f6dfa1c85b3b5fefcded5b74d0ac2f5 /drivers
parent37e0333c68ca9cbddfc0108e1889556287563df0 (diff)
[SCSI] SCSI sd: fix module init/exit error handling
- Properly handle and unwind errors in init_sd(). Fixes leaks on error, if class_register() or scsi_register_driver() failed. - Ensure that exit_sd() execution order is the perfect inverse of initialization order. FIXME: If some-but-not-all register_blkdev() calls fail, we wind up calling unregister_blkdev() for block devices we did not register. This was a pre-existing bug. Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sd.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 638cff41d436..7a9d552f50e6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1795,7 +1795,7 @@ static void sd_shutdown(struct device *dev)
1795 **/ 1795 **/
1796static int __init init_sd(void) 1796static int __init init_sd(void)
1797{ 1797{
1798 int majors = 0, i; 1798 int majors = 0, i, err;
1799 1799
1800 SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); 1800 SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
1801 1801
@@ -1806,9 +1806,22 @@ static int __init init_sd(void)
1806 if (!majors) 1806 if (!majors)
1807 return -ENODEV; 1807 return -ENODEV;
1808 1808
1809 class_register(&sd_disk_class); 1809 err = class_register(&sd_disk_class);
1810 if (err)
1811 goto err_out;
1810 1812
1811 return scsi_register_driver(&sd_template.gendrv); 1813 err = scsi_register_driver(&sd_template.gendrv);
1814 if (err)
1815 goto err_out_class;
1816
1817 return 0;
1818
1819err_out_class:
1820 class_unregister(&sd_disk_class);
1821err_out:
1822 for (i = 0; i < SD_MAJORS; i++)
1823 unregister_blkdev(sd_major(i), "sd");
1824 return err;
1812} 1825}
1813 1826
1814/** 1827/**
@@ -1823,10 +1836,10 @@ static void __exit exit_sd(void)
1823 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); 1836 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
1824 1837
1825 scsi_unregister_driver(&sd_template.gendrv); 1838 scsi_unregister_driver(&sd_template.gendrv);
1839 class_unregister(&sd_disk_class);
1840
1826 for (i = 0; i < SD_MAJORS; i++) 1841 for (i = 0; i < SD_MAJORS; i++)
1827 unregister_blkdev(sd_major(i), "sd"); 1842 unregister_blkdev(sd_major(i), "sd");
1828
1829 class_unregister(&sd_disk_class);
1830} 1843}
1831 1844
1832module_init(init_sd); 1845module_init(init_sd);