Commit 37e6ba00720c2786330dec2a9a5081e9e049422f

Authored by James Bottomley
1 parent 2caa731819

[SCSI] fix memory leak in initialization

The root cause of the problem is the fact that dev_set_name() now
allocates storage instead of using the original array within the kobj.
That means that the SCSI assumption that if you haven't made the
containing object or any sub objects visible, you can just destroy it
(and its component devices) lock stock and barrel becomes false.

Fix this by doing the get of sdev_dev at parent time and thus do an
extra put of it in scsi_destroy_sdev() (and all other destruction
without add paths).

Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

Showing 2 changed files with 4 additions and 5 deletions Side-by-side Diff

drivers/scsi/scsi_scan.c
... ... @@ -317,6 +317,7 @@
317 317 out_device_destroy:
318 318 scsi_device_set_state(sdev, SDEV_DEL);
319 319 transport_destroy_device(&sdev->sdev_gendev);
  320 + put_device(&sdev->sdev_dev);
320 321 put_device(&sdev->sdev_gendev);
321 322 out:
322 323 if (display_failure_msg)
... ... @@ -957,6 +958,7 @@
957 958 if (sdev->host->hostt->slave_destroy)
958 959 sdev->host->hostt->slave_destroy(sdev);
959 960 transport_destroy_device(&sdev->sdev_gendev);
  961 + put_device(&sdev->sdev_dev);
960 962 put_device(&sdev->sdev_gendev);
961 963 }
962 964  
drivers/scsi/scsi_sysfs.c
... ... @@ -864,10 +864,6 @@
864 864 goto clean_device;
865 865 }
866 866  
867   - /* take a reference for the sdev_dev; this is
868   - * released by the sdev_class .release */
869   - get_device(&sdev->sdev_gendev);
870   -
871 867 /* create queue files, which may be writable, depending on the host */
872 868 if (sdev->host->hostt->change_queue_depth)
873 869 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
... ... @@ -917,6 +913,7 @@
917 913  
918 914 device_del(&sdev->sdev_gendev);
919 915 transport_destroy_device(&sdev->sdev_gendev);
  916 + put_device(&sdev->sdev_dev);
920 917 put_device(&sdev->sdev_gendev);
921 918  
922 919 return error;
... ... @@ -1065,7 +1062,7 @@
1065 1062 sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
1066 1063  
1067 1064 device_initialize(&sdev->sdev_dev);
1068   - sdev->sdev_dev.parent = &sdev->sdev_gendev;
  1065 + sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
1069 1066 sdev->sdev_dev.class = &sdev_class;
1070 1067 dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d",
1071 1068 sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);