[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:
committed by
James Bottomley
parent
86e33a296c
commit
85b6c720b0
@@ -851,14 +851,14 @@ EXPORT_SYMBOL(scsi_track_queue_full);
|
|||||||
*/
|
*/
|
||||||
int scsi_device_get(struct scsi_device *sdev)
|
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;
|
return -ENXIO;
|
||||||
if (!get_device(&sdev->sdev_gendev))
|
if (!get_device(&sdev->sdev_gendev))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
if (!try_module_get(sdev->host->hostt->module)) {
|
/* We can fail this if we're doing SCSI operations
|
||||||
put_device(&sdev->sdev_gendev);
|
* from module exit (like cache flush) */
|
||||||
return -ENXIO;
|
try_module_get(sdev->host->hostt->module);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_device_get);
|
EXPORT_SYMBOL(scsi_device_get);
|
||||||
@@ -873,6 +873,9 @@ EXPORT_SYMBOL(scsi_device_get);
|
|||||||
*/
|
*/
|
||||||
void scsi_device_put(struct scsi_device *sdev)
|
void scsi_device_put(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
|
/* 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);
|
module_put(sdev->host->hostt->module);
|
||||||
put_device(&sdev->sdev_gendev);
|
put_device(&sdev->sdev_gendev);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user