[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
	
	Block a user