aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-02-12 12:13:55 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-18 12:06:39 -0500
commitee37e09d81a4acf328f68189af12f116401f8c0f (patch)
treeabac354cb40c47be3985c6e2efe399dd10dcdd87 /drivers/scsi/scsi_sysfs.c
parentd5469119f0098881ab7f991990ef4f81ef13a194 (diff)
[SCSI] fix duplicate removal on error path in scsi_sysfs_add_sdev
This patch (as1335) fixes a bug in scsi_sysfs_add_sdev(). Its callers always remove the device if anything goes wrong, so it should never remove the device. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 5a065055e68a..a4936c4e2f46 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -878,7 +878,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
878 struct request_queue *rq = sdev->request_queue; 878 struct request_queue *rq = sdev->request_queue;
879 struct scsi_target *starget = sdev->sdev_target; 879 struct scsi_target *starget = sdev->sdev_target;
880 880
881 if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) 881 error = scsi_device_set_state(sdev, SDEV_RUNNING);
882 if (error)
882 return error; 883 return error;
883 884
884 error = scsi_target_add(starget); 885 error = scsi_target_add(starget);
@@ -889,13 +890,13 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
889 error = device_add(&sdev->sdev_gendev); 890 error = device_add(&sdev->sdev_gendev);
890 if (error) { 891 if (error) {
891 printk(KERN_INFO "error 1\n"); 892 printk(KERN_INFO "error 1\n");
892 goto out_remove; 893 return error;
893 } 894 }
894 error = device_add(&sdev->sdev_dev); 895 error = device_add(&sdev->sdev_dev);
895 if (error) { 896 if (error) {
896 printk(KERN_INFO "error 2\n"); 897 printk(KERN_INFO "error 2\n");
897 device_del(&sdev->sdev_gendev); 898 device_del(&sdev->sdev_gendev);
898 goto out_remove; 899 return error;
899 } 900 }
900 transport_add_device(&sdev->sdev_gendev); 901 transport_add_device(&sdev->sdev_gendev);
901 sdev->is_visible = 1; 902 sdev->is_visible = 1;
@@ -910,14 +911,14 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
910 else 911 else
911 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); 912 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
912 if (error) 913 if (error)
913 goto out_remove; 914 return error;
914 915
915 if (sdev->host->hostt->change_queue_type) 916 if (sdev->host->hostt->change_queue_type)
916 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); 917 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
917 else 918 else
918 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); 919 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
919 if (error) 920 if (error)
920 goto out_remove; 921 return error;
921 922
922 error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); 923 error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
923 924
@@ -933,16 +934,11 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
933 error = device_create_file(&sdev->sdev_gendev, 934 error = device_create_file(&sdev->sdev_gendev,
934 sdev->host->hostt->sdev_attrs[i]); 935 sdev->host->hostt->sdev_attrs[i]);
935 if (error) 936 if (error)
936 goto out_remove; 937 return error;
937 } 938 }
938 } 939 }
939 940
940 return 0;
941
942 out_remove:
943 __scsi_remove_device(sdev);
944 return error; 941 return error;
945
946} 942}
947 943
948void __scsi_remove_device(struct scsi_device *sdev) 944void __scsi_remove_device(struct scsi_device *sdev)