forked from mirrors/linux
		
	scsi: always increment reference count
James reported:
> After e513cc1 module: Remove stop_machine from module unloading,
> module_refcount() is returning (unsigned long)-1 when called from within
> a routine that runs in module_exit.  This is confusing the scsi device
> put code which is coded to detect a module_refcount() of zero for
> running within a module exit routine and not try to do another
> module_put.  The fix is to restore the original behaviour of
> module_refcount() and return zero if we're running inside an exit
> routine.
The correct fix is to turn try_module_get() into __module_get(), and
always do the module_put().
Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
			
			
This commit is contained in:
		
							parent
							
								
									d5db139ab3
								
							
						
					
					
						commit
						dc4515ea26
					
				
					 1 changed files with 3 additions and 10 deletions
				
			
		|  | @ -986,9 +986,9 @@ int scsi_device_get(struct scsi_device *sdev) | ||||||
| 		return -ENXIO; | 		return -ENXIO; | ||||||
| 	if (!get_device(&sdev->sdev_gendev)) | 	if (!get_device(&sdev->sdev_gendev)) | ||||||
| 		return -ENXIO; | 		return -ENXIO; | ||||||
| 	/* We can fail this if we're doing SCSI operations
 | 	/* We can fail try_module_get if we're doing SCSI operations
 | ||||||
| 	 * from module exit (like cache flush) */ | 	 * from module exit (like cache flush) */ | ||||||
| 	try_module_get(sdev->host->hostt->module); | 	__module_get(sdev->host->hostt->module); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -1004,14 +1004,7 @@ EXPORT_SYMBOL(scsi_device_get); | ||||||
|  */ |  */ | ||||||
| void scsi_device_put(struct scsi_device *sdev) | void scsi_device_put(struct scsi_device *sdev) | ||||||
| { | { | ||||||
| #ifdef CONFIG_MODULE_UNLOAD | 	module_put(sdev->host->hostt->module); | ||||||
| 	struct module *module = sdev->host->hostt->module; |  | ||||||
| 
 |  | ||||||
| 	/* The module refcount will be zero if scsi_device_get()
 |  | ||||||
| 	 * was called from a module removal routine */ |  | ||||||
| 	if (module && module_refcount(module) != 0) |  | ||||||
| 		module_put(module); |  | ||||||
| #endif |  | ||||||
| 	put_device(&sdev->sdev_gendev); | 	put_device(&sdev->sdev_gendev); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(scsi_device_put); | EXPORT_SYMBOL(scsi_device_put); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Rusty Russell
						Rusty Russell