diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-08 02:51:13 +0300 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-08 02:51:13 +0300 |
commit | abaee091a18c19ccd86feb1c8374585d82e96777 (patch) | |
tree | 01602bae73e1278c3d98dafe1c269049927c58ce /drivers/scsi/scsi_sysfs.c | |
parent | a2746fb16e41b7c8f02aa4d2605ecce97abbebbd (diff) | |
parent | 3f8d6f2a0797e8c650a47e5c1b5c2601a46f4293 (diff) | |
download | linux-abaee091a18c19ccd86feb1c8374585d82e96777.tar.xz |
Merge branch 'jejb-scsi' into misc
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ef360533790d..4f18a851e2c7 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1182,6 +1182,14 @@ void __scsi_remove_device(struct scsi_device *sdev) { struct device *dev = &sdev->sdev_gendev; + /* + * This cleanup path is not reentrant and while it is impossible + * to get a new reference with scsi_device_get() someone can still + * hold a previously acquired one. + */ + if (sdev->sdev_state == SDEV_DEL) + return; + if (sdev->is_visible) { if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) return; @@ -1190,7 +1198,9 @@ void __scsi_remove_device(struct scsi_device *sdev) device_unregister(&sdev->sdev_dev); transport_remove_device(dev); scsi_dh_remove_device(sdev); - } + device_del(dev); + } else + put_device(&sdev->sdev_dev); /* * Stop accepting new requests and wait until all queuecommand() and @@ -1201,16 +1211,6 @@ void __scsi_remove_device(struct scsi_device *sdev) blk_cleanup_queue(sdev->request_queue); cancel_work_sync(&sdev->requeue_work); - /* - * Remove the device after blk_cleanup_queue() has been called such - * a possible bdi_register() call with the same name occurs after - * blk_cleanup_queue() has called bdi_destroy(). - */ - if (sdev->is_visible) - device_del(dev); - else - put_device(&sdev->sdev_dev); - if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); transport_destroy_device(dev); |