Skip to content

Commit 37e0333

Browse files
Jeff GarzikJames Bottomley
authored andcommitted
[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 <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent de77aaf commit 37e0333

File tree

1 file changed

+91
-40
lines changed

1 file changed

+91
-40
lines changed

drivers/scsi/osst.c

Lines changed: 91 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5206,12 +5206,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
52065206
priority = GFP_KERNEL;
52075207

52085208
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);
52105210
if (!tb) {
52115211
printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
52125212
return NULL;
52135213
}
5214-
memset(tb, 0, i);
5214+
52155215
tb->sg_segs = tb->orig_sg_segs = 0;
52165216
tb->use_sg = max_sg;
52175217
tb->in_use = 1;
@@ -5574,9 +5574,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
55745574

55755575
static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
55765576

5577-
static void osst_create_driverfs_files(struct device_driver *driverfs)
5577+
static int osst_create_driverfs_files(struct device_driver *driverfs)
55785578
{
5579-
driver_create_file(driverfs, &driver_attr_version);
5579+
return driver_create_file(driverfs, &driver_attr_version);
55805580
}
55815581

55825582
static void osst_remove_driverfs_files(struct device_driver *driverfs)
@@ -5662,50 +5662,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
56625662

56635663
static struct class *osst_sysfs_class;
56645664

5665-
static int osst_sysfs_valid = 0;
5666-
5667-
static void osst_sysfs_init(void)
5665+
static int osst_sysfs_init(void)
56685666
{
56695667
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;
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);
5671+
}
5672+
5673+
return 0;
56745674
}
56755675

5676-
static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5676+
static void osst_sysfs_destroy(dev_t dev)
56775677
{
5678-
struct class_device *osst_class_member;
5678+
class_device_destroy(osst_sysfs_class, dev);
5679+
}
56795680

5680-
if (!osst_sysfs_valid) return;
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;
56815685

5682-
osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
5686+
osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
5687+
device, "%s", name);
56835688
if (IS_ERR(osst_class_member)) {
56845689
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5685-
return;
5690+
return PTR_ERR(osst_class_member);
56865691
}
5692+
56875693
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);
5694-
}
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;
56955718

5696-
static void osst_sysfs_destroy(dev_t dev)
5697-
{
5698-
if (!osst_sysfs_valid) return;
5719+
return 0;
56995720

5700-
class_device_destroy(osst_sysfs_class, dev);
5721+
err_out:
5722+
osst_sysfs_destroy(dev);
5723+
return err;
57015724
}
57025725

57035726
static void osst_sysfs_cleanup(void)
57045727
{
5705-
if (osst_sysfs_valid) {
5706-
class_destroy(osst_sysfs_class);
5707-
osst_sysfs_valid = 0;
5708-
}
5728+
class_destroy(osst_sysfs_class);
57095729
}
57105730

57115731
/*
@@ -5720,7 +5740,7 @@ static int osst_probe(struct device *dev)
57205740
struct st_partstat * STps;
57215741
struct osst_buffer * buffer;
57225742
struct gendisk * drive;
5723-
int i, dev_num;
5743+
int i, dev_num, err = -ENODEV;
57245744

57255745
if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
57265746
return -ENODEV;
@@ -5848,13 +5868,20 @@ static int osst_probe(struct device *dev)
58485868
init_MUTEX(&tpnt->lock);
58495869
osst_nr_dev++;
58505870
write_unlock(&os_scsi_tapes_lock);
5871+
58515872
{
58525873
char name[8];
5874+
58535875
/* Rewind entry */
5854-
osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5876+
err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5877+
if (err)
5878+
goto out_free_buffer;
5879+
58555880
/* No-rewind entry */
58565881
snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5857-
osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5882+
err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5883+
if (err)
5884+
goto out_free_sysfs1;
58585885
}
58595886

58605887
sdev_printk(KERN_INFO, SDp,
@@ -5863,9 +5890,13 @@ static int osst_probe(struct device *dev)
58635890

58645891
return 0;
58655892

5893+
out_free_sysfs1:
5894+
osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
5895+
out_free_buffer:
5896+
kfree(buffer);
58665897
out_put_disk:
58675898
put_disk(drive);
5868-
return -ENODEV;
5899+
return err;
58695900
};
58705901

58715902
static int osst_remove(struct device *dev)
@@ -5902,19 +5933,39 @@ static int osst_remove(struct device *dev)
59025933

59035934
static int __init init_osst(void)
59045935
{
5936+
int err;
5937+
59055938
printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
59065939

59075940
validate_options();
5908-
osst_sysfs_init();
59095941

5910-
if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
5942+
err = osst_sysfs_init();
5943+
if (err)
5944+
return err;
5945+
5946+
err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
5947+
if (err < 0) {
59115948
printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5912-
osst_sysfs_cleanup();
5913-
return 1;
5949+
goto err_out;
59145950
}
5915-
osst_create_driverfs_files(&osst_template.gendrv);
5951+
5952+
err = scsi_register_driver(&osst_template.gendrv);
5953+
if (err)
5954+
goto err_out_chrdev;
5955+
5956+
err = osst_create_driverfs_files(&osst_template.gendrv);
5957+
if (err)
5958+
goto err_out_scsidrv;
59165959

59175960
return 0;
5961+
5962+
err_out_scsidrv:
5963+
scsi_unregister_driver(&osst_template.gendrv);
5964+
err_out_chrdev:
5965+
unregister_chrdev(OSST_MAJOR, "osst");
5966+
err_out:
5967+
osst_sysfs_cleanup();
5968+
return err;
59185969
}
59195970

59205971
static void __exit exit_osst (void)

0 commit comments

Comments
 (0)