mirror of https://gitee.com/openkylin/linux.git
[SCSI] sd: fix cache flushing on module removal (and individual device removal)
The fix isn't actually in sd: it's in scsi_device_get(). I modified it to allow devices to be returned in SDEV_CANCEL, but not SDEV_DEL. This means that the device_remove_driver, which occurs in device_del() in scsi_remove_device() after the device has gone into SDEV_CANCEL is now effective at flushing the cache. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
86e33a296c
commit
85b6c720b0
|
@ -851,14 +851,14 @@ EXPORT_SYMBOL(scsi_track_queue_full);
|
|||
*/
|
||||
int scsi_device_get(struct scsi_device *sdev)
|
||||
{
|
||||
if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
|
||||
if (sdev->sdev_state == SDEV_DEL)
|
||||
return -ENXIO;
|
||||
if (!get_device(&sdev->sdev_gendev))
|
||||
return -ENXIO;
|
||||
if (!try_module_get(sdev->host->hostt->module)) {
|
||||
put_device(&sdev->sdev_gendev);
|
||||
return -ENXIO;
|
||||
}
|
||||
/* We can fail this if we're doing SCSI operations
|
||||
* from module exit (like cache flush) */
|
||||
try_module_get(sdev->host->hostt->module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_device_get);
|
||||
|
@ -873,7 +873,10 @@ EXPORT_SYMBOL(scsi_device_get);
|
|||
*/
|
||||
void scsi_device_put(struct scsi_device *sdev)
|
||||
{
|
||||
module_put(sdev->host->hostt->module);
|
||||
/* The module refcount will be zero if scsi_device_get()
|
||||
* was called from a module removal routine */
|
||||
if (likely(module_refcount(sdev->host->hostt->module) != 0))
|
||||
module_put(sdev->host->hostt->module);
|
||||
put_device(&sdev->sdev_gendev);
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_device_put);
|
||||
|
|
Loading…
Reference in New Issue