Skip to content

Commit 13026a6

Browse files
Jeff GarzikJames Bottomley
authored andcommitted
[SCSI] SCSI st: fix error handling in module init, sysfs
- Notice and handle sysfs errors in module init, tape init - Properly unwind errors in module init - Remove bogus st_sysfs_class==NULL test, it is guaranteed !NULL at that point Signed-off-by: Jeff Garzik <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent 5e4009b commit 13026a6

File tree

1 file changed

+78
-37
lines changed

1 file changed

+78
-37
lines changed

drivers/scsi/st.c

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
195195
static int st_probe(struct device *);
196196
static int st_remove(struct device *);
197197

198-
static void do_create_driverfs_files(void);
198+
static int do_create_driverfs_files(void);
199199
static void do_remove_driverfs_files(void);
200-
static void do_create_class_files(struct scsi_tape *, int, int);
200+
static int do_create_class_files(struct scsi_tape *, int, int);
201201

202202
static struct scsi_driver st_template = {
203203
.owner = THIS_MODULE,
@@ -4048,7 +4048,9 @@ static int st_probe(struct device *dev)
40484048
STm->cdevs[j] = cdev;
40494049

40504050
}
4051-
do_create_class_files(tpnt, dev_num, mode);
4051+
error = do_create_class_files(tpnt, dev_num, mode);
4052+
if (error)
4053+
goto out_free_tape;
40524054
}
40534055

40544056
sdev_printk(KERN_WARNING, SDp,
@@ -4157,32 +4159,45 @@ static void scsi_tape_release(struct kref *kref)
41574159

41584160
static int __init init_st(void)
41594161
{
4162+
int err;
4163+
41604164
validate_options();
41614165

4162-
printk(KERN_INFO
4163-
"st: Version %s, fixed bufsize %d, s/g segs %d\n",
4166+
printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
41644167
verstr, st_fixed_buffer_size, st_max_sg_segs);
41654168

41664169
st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
41674170
if (IS_ERR(st_sysfs_class)) {
4168-
st_sysfs_class = NULL;
41694171
printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
4170-
return 1;
4172+
return PTR_ERR(st_sysfs_class);
41714173
}
41724174

4173-
if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4174-
ST_MAX_TAPE_ENTRIES, "st")) {
4175-
if (scsi_register_driver(&st_template.gendrv) == 0) {
4176-
do_create_driverfs_files();
4177-
return 0;
4178-
}
4179-
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4180-
ST_MAX_TAPE_ENTRIES);
4175+
err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4176+
ST_MAX_TAPE_ENTRIES, "st");
4177+
if (err) {
4178+
printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4179+
SCSI_TAPE_MAJOR);
4180+
goto err_class;
41814181
}
4182-
class_destroy(st_sysfs_class);
41834182

4184-
printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
4185-
return 1;
4183+
err = scsi_register_driver(&st_template.gendrv);
4184+
if (err)
4185+
goto err_chrdev;
4186+
4187+
err = do_create_driverfs_files();
4188+
if (err)
4189+
goto err_scsidrv;
4190+
4191+
return 0;
4192+
4193+
err_scsidrv:
4194+
scsi_unregister_driver(&st_template.gendrv);
4195+
err_chrdev:
4196+
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4197+
ST_MAX_TAPE_ENTRIES);
4198+
err_class:
4199+
class_destroy(st_sysfs_class);
4200+
return err;
41864201
}
41874202

41884203
static void __exit exit_st(void)
@@ -4225,14 +4240,33 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf)
42254240
}
42264241
static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
42274242

4228-
static void do_create_driverfs_files(void)
4243+
static int do_create_driverfs_files(void)
42294244
{
42304245
struct device_driver *driverfs = &st_template.gendrv;
4246+
int err;
4247+
4248+
err = driver_create_file(driverfs, &driver_attr_try_direct_io);
4249+
if (err)
4250+
return err;
4251+
err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
4252+
if (err)
4253+
goto err_try_direct_io;
4254+
err = driver_create_file(driverfs, &driver_attr_max_sg_segs);
4255+
if (err)
4256+
goto err_attr_fixed_buf;
4257+
err = driver_create_file(driverfs, &driver_attr_version);
4258+
if (err)
4259+
goto err_attr_max_sg;
42314260

4232-
driver_create_file(driverfs, &driver_attr_try_direct_io);
4233-
driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
4234-
driver_create_file(driverfs, &driver_attr_max_sg_segs);
4235-
driver_create_file(driverfs, &driver_attr_version);
4261+
return 0;
4262+
4263+
err_attr_max_sg:
4264+
driver_remove_file(driverfs, &driver_attr_max_sg_segs);
4265+
err_attr_fixed_buf:
4266+
driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
4267+
err_try_direct_io:
4268+
driver_remove_file(driverfs, &driver_attr_try_direct_io);
4269+
return err;
42364270
}
42374271

42384272
static void do_remove_driverfs_files(void)
@@ -4293,15 +4327,12 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
42934327

42944328
CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
42954329

4296-
static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4330+
static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
42974331
{
42984332
int i, rew, error;
42994333
char name[10];
43004334
struct class_device *st_class_member;
43014335

4302-
if (!st_sysfs_class)
4303-
return;
4304-
43054336
for (rew=0; rew < 2; rew++) {
43064337
/* Make sure that the minor numbers corresponding to the four
43074338
first modes always get the same names */
@@ -4316,18 +4347,24 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
43164347
if (IS_ERR(st_class_member)) {
43174348
printk(KERN_WARNING "st%d: class_device_create failed\n",
43184349
dev_num);
4350+
error = PTR_ERR(st_class_member);
43194351
goto out;
43204352
}
43214353
class_set_devdata(st_class_member, &STp->modes[mode]);
43224354

4323-
class_device_create_file(st_class_member,
4324-
&class_device_attr_defined);
4325-
class_device_create_file(st_class_member,
4326-
&class_device_attr_default_blksize);
4327-
class_device_create_file(st_class_member,
4328-
&class_device_attr_default_density);
4329-
class_device_create_file(st_class_member,
4330-
&class_device_attr_default_compression);
4355+
error = class_device_create_file(st_class_member,
4356+
&class_device_attr_defined);
4357+
if (error) goto out;
4358+
error = class_device_create_file(st_class_member,
4359+
&class_device_attr_default_blksize);
4360+
if (error) goto out;
4361+
error = class_device_create_file(st_class_member,
4362+
&class_device_attr_default_density);
4363+
if (error) goto out;
4364+
error = class_device_create_file(st_class_member,
4365+
&class_device_attr_default_compression);
4366+
if (error) goto out;
4367+
43314368
if (mode == 0 && rew == 0) {
43324369
error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
43334370
&st_class_member->kobj,
@@ -4336,11 +4373,15 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
43364373
printk(KERN_ERR
43374374
"st%d: Can't create sysfs link from SCSI device.\n",
43384375
dev_num);
4376+
goto out;
43394377
}
43404378
}
43414379
}
4342-
out:
4343-
return;
4380+
4381+
return 0;
4382+
4383+
out:
4384+
return error;
43444385
}
43454386

43464387
/* The following functions may be useful for a larger audience. */

0 commit comments

Comments
 (0)