[SCSI] SCSI osst: add error handling to module init, sysfs

- check all sysfs-related return codes, and propagate them back to callers

- properly unwind errors in osst_probe(), init_osst(). This fixes a
leak that occured if scsi driver registration failed, and fixes an
oops if sysfs creation returned an error.

(unrelated)
- kzalloc() cleanup in new_tape_buf()

Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by Jeff Garzik and committed by James Bottomley 37e0333c de77aaff

+96 -45
+96 -45
drivers/scsi/osst.c
··· 5206 5206 priority = GFP_KERNEL; 5207 5207 5208 5208 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); 5209 - tb = (struct osst_buffer *)kmalloc(i, priority); 5209 + tb = kzalloc(i, priority); 5210 5210 if (!tb) { 5211 5211 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); 5212 5212 return NULL; 5213 5213 } 5214 - memset(tb, 0, i); 5214 + 5215 5215 tb->sg_segs = tb->orig_sg_segs = 0; 5216 5216 tb->use_sg = max_sg; 5217 5217 tb->in_use = 1; ··· 5574 5574 5575 5575 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); 5576 5576 5577 - static void osst_create_driverfs_files(struct device_driver *driverfs) 5577 + static int osst_create_driverfs_files(struct device_driver *driverfs) 5578 5578 { 5579 - driver_create_file(driverfs, &driver_attr_version); 5579 + return driver_create_file(driverfs, &driver_attr_version); 5580 5580 } 5581 5581 5582 5582 static void osst_remove_driverfs_files(struct device_driver *driverfs) ··· 5662 5662 5663 5663 static struct class *osst_sysfs_class; 5664 5664 5665 - static int osst_sysfs_valid = 0; 5666 - 5667 - static void osst_sysfs_init(void) 5665 + static int osst_sysfs_init(void) 5668 5666 { 5669 5667 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); 5670 - if ( IS_ERR(osst_sysfs_class) ) 5671 - printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); 5672 - else 5673 - osst_sysfs_valid = 1; 5674 - } 5675 - 5676 - static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5677 - { 5678 - struct class_device *osst_class_member; 5679 - 5680 - if (!osst_sysfs_valid) return; 5681 - 5682 - osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name); 5683 - if (IS_ERR(osst_class_member)) { 5684 - printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5685 - return; 5668 + if (IS_ERR(osst_sysfs_class)) { 5669 + printk(KERN_ERR "osst :W: Unable to register sysfs class\n"); 5670 + return PTR_ERR(osst_sysfs_class); 5686 5671 } 5687 - class_set_devdata(osst_class_member, STp); 5688 - class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); 5689 - class_device_create_file(osst_class_member, &class_device_attr_media_version); 5690 - class_device_create_file(osst_class_member, &class_device_attr_capacity); 5691 - class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); 5692 - class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); 5693 - class_device_create_file(osst_class_member, &class_device_attr_file_count); 5672 + 5673 + return 0; 5694 5674 } 5695 5675 5696 5676 static void osst_sysfs_destroy(dev_t dev) 5697 5677 { 5698 - if (!osst_sysfs_valid) return; 5699 - 5700 5678 class_device_destroy(osst_sysfs_class, dev); 5679 + } 5680 + 5681 + static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5682 + { 5683 + struct class_device *osst_class_member; 5684 + int err; 5685 + 5686 + osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, 5687 + device, "%s", name); 5688 + if (IS_ERR(osst_class_member)) { 5689 + printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5690 + return PTR_ERR(osst_class_member); 5691 + } 5692 + 5693 + class_set_devdata(osst_class_member, STp); 5694 + err = class_device_create_file(osst_class_member, 5695 + &class_device_attr_ADR_rev); 5696 + if (err) 5697 + goto err_out; 5698 + err = class_device_create_file(osst_class_member, 5699 + &class_device_attr_media_version); 5700 + if (err) 5701 + goto err_out; 5702 + err = class_device_create_file(osst_class_member, 5703 + &class_device_attr_capacity); 5704 + if (err) 5705 + goto err_out; 5706 + err = class_device_create_file(osst_class_member, 5707 + &class_device_attr_BOT_frame); 5708 + if (err) 5709 + goto err_out; 5710 + err = class_device_create_file(osst_class_member, 5711 + &class_device_attr_EOD_frame); 5712 + if (err) 5713 + goto err_out; 5714 + err = class_device_create_file(osst_class_member, 5715 + &class_device_attr_file_count); 5716 + if (err) 5717 + goto err_out; 5718 + 5719 + return 0; 5720 + 5721 + err_out: 5722 + osst_sysfs_destroy(dev); 5723 + return err; 5701 5724 } 5702 5725 5703 5726 static void osst_sysfs_cleanup(void) 5704 5727 { 5705 - if (osst_sysfs_valid) { 5706 - class_destroy(osst_sysfs_class); 5707 - osst_sysfs_valid = 0; 5708 - } 5728 + class_destroy(osst_sysfs_class); 5709 5729 } 5710 5730 5711 5731 /* ··· 5740 5720 struct st_partstat * STps; 5741 5721 struct osst_buffer * buffer; 5742 5722 struct gendisk * drive; 5743 - int i, dev_num; 5723 + int i, dev_num, err = -ENODEV; 5744 5724 5745 5725 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) 5746 5726 return -ENODEV; ··· 5868 5848 init_MUTEX(&tpnt->lock); 5869 5849 osst_nr_dev++; 5870 5850 write_unlock(&os_scsi_tapes_lock); 5851 + 5871 5852 { 5872 5853 char name[8]; 5854 + 5873 5855 /* Rewind entry */ 5874 - osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5856 + err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5857 + if (err) 5858 + goto out_free_buffer; 5859 + 5875 5860 /* No-rewind entry */ 5876 5861 snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); 5877 - osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5862 + err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5863 + if (err) 5864 + goto out_free_sysfs1; 5878 5865 } 5879 5866 5880 5867 sdev_printk(KERN_INFO, SDp, ··· 5890 5863 5891 5864 return 0; 5892 5865 5866 + out_free_sysfs1: 5867 + osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num)); 5868 + out_free_buffer: 5869 + kfree(buffer); 5893 5870 out_put_disk: 5894 5871 put_disk(drive); 5895 - return -ENODEV; 5872 + return err; 5896 5873 }; 5897 5874 5898 5875 static int osst_remove(struct device *dev) ··· 5933 5902 5934 5903 static int __init init_osst(void) 5935 5904 { 5905 + int err; 5906 + 5936 5907 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); 5937 5908 5938 5909 validate_options(); 5939 - osst_sysfs_init(); 5940 5910 5941 - if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { 5911 + err = osst_sysfs_init(); 5912 + if (err) 5913 + return err; 5914 + 5915 + err = register_chrdev(OSST_MAJOR, "osst", &osst_fops); 5916 + if (err < 0) { 5942 5917 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); 5943 - osst_sysfs_cleanup(); 5944 - return 1; 5918 + goto err_out; 5945 5919 } 5946 - osst_create_driverfs_files(&osst_template.gendrv); 5920 + 5921 + err = scsi_register_driver(&osst_template.gendrv); 5922 + if (err) 5923 + goto err_out_chrdev; 5924 + 5925 + err = osst_create_driverfs_files(&osst_template.gendrv); 5926 + if (err) 5927 + goto err_out_scsidrv; 5947 5928 5948 5929 return 0; 5930 + 5931 + err_out_scsidrv: 5932 + scsi_unregister_driver(&osst_template.gendrv); 5933 + err_out_chrdev: 5934 + unregister_chrdev(OSST_MAJOR, "osst"); 5935 + err_out: 5936 + osst_sysfs_cleanup(); 5937 + return err; 5949 5938 } 5950 5939 5951 5940 static void __exit exit_osst (void)