mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-18 22:14:16 +00:00 
			
		
		
		
	splice: fix i_mutex locking in generic_splice_write()
Rearrange locking of i_mutex on destination so it's only held while buffers are copied with the pipe_to_file() actor, and not while waiting for more data on the pipe. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
		
							parent
							
								
									2933970b96
								
							
						
					
					
						commit
						eb443e5a25
					
				
					 1 changed files with 23 additions and 11 deletions
				
			
		
							
								
								
									
										34
									
								
								fs/splice.c
									
										
									
									
									
								
							
							
						
						
									
										34
									
								
								fs/splice.c
									
										
									
									
									
								
							|  | @ -895,17 +895,29 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
| 	}; | ||||
| 	ssize_t ret; | ||||
| 
 | ||||
| 	WARN_ON(S_ISFIFO(inode->i_mode)); | ||||
| 	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||||
| 	ret = file_remove_suid(out); | ||||
| 	if (likely(!ret)) { | ||||
| 		if (pipe->inode) | ||||
| 			mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||||
| 		ret = __splice_from_pipe(pipe, &sd, pipe_to_file); | ||||
| 		if (pipe->inode) | ||||
| 			mutex_unlock(&pipe->inode->i_mutex); | ||||
| 	} | ||||
| 	mutex_unlock(&inode->i_mutex); | ||||
| 	if (pipe->inode) | ||||
| 		mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); | ||||
| 
 | ||||
| 	splice_from_pipe_begin(&sd); | ||||
| 	do { | ||||
| 		ret = splice_from_pipe_next(pipe, &sd); | ||||
| 		if (ret <= 0) | ||||
| 			break; | ||||
| 
 | ||||
| 		mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||||
| 		ret = file_remove_suid(out); | ||||
| 		if (!ret) | ||||
| 			ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); | ||||
| 		mutex_unlock(&inode->i_mutex); | ||||
| 	} while (ret > 0); | ||||
| 	splice_from_pipe_end(pipe, &sd); | ||||
| 
 | ||||
| 	if (pipe->inode) | ||||
| 		mutex_unlock(&pipe->inode->i_mutex); | ||||
| 
 | ||||
| 	if (sd.num_spliced) | ||||
| 		ret = sd.num_spliced; | ||||
| 
 | ||||
| 	if (ret > 0) { | ||||
| 		unsigned long nr_pages; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Miklos Szeredi
						Miklos Szeredi