locks: prevent side-effects of locks_release_private before file_lock is initialized
When calling fcntl(fd, F_SETLEASE, lck) [with lck=F_WRLCK or F_RDLCK], the custom signal or owner (if any were previously set using F_SETSIG or F_SETOWN fcntls) would be reset when F_SETLEASE was called for the second time on the same file descriptor. This bug is a regression of 2.6.37 and is described here: https://bugzilla.kernel.org/show_bug.cgi?id=43336 This patch reverts a commit from Oct 2004 (with subject "nfs4 lease: move the f_delown processing") which originally introduced the lm_release_private callback. Signed-off-by: Filipe Brandenburger <filbranden@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
		
							parent
							
								
									57c8b13e3c
								
							
						
					
					
						commit
						3b6e2723f3
					
				
							
								
								
									
										17
									
								
								fs/locks.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								fs/locks.c
									
									
									
									
									
								
							| @ -427,18 +427,8 @@ static void lease_break_callback(struct file_lock *fl) | ||||
| 	kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); | ||||
| } | ||||
| 
 | ||||
| static void lease_release_private_callback(struct file_lock *fl) | ||||
| { | ||||
| 	if (!fl->fl_file) | ||||
| 		return; | ||||
| 
 | ||||
| 	f_delown(fl->fl_file); | ||||
| 	fl->fl_file->f_owner.signum = 0; | ||||
| } | ||||
| 
 | ||||
| static const struct lock_manager_operations lease_manager_ops = { | ||||
| 	.lm_break = lease_break_callback, | ||||
| 	.lm_release_private = lease_release_private_callback, | ||||
| 	.lm_change = lease_modify, | ||||
| }; | ||||
| 
 | ||||
| @ -1155,8 +1145,13 @@ int lease_modify(struct file_lock **before, int arg) | ||||
| 		return error; | ||||
| 	lease_clear_pending(fl, arg); | ||||
| 	locks_wake_up_blocks(fl); | ||||
| 	if (arg == F_UNLCK) | ||||
| 	if (arg == F_UNLCK) { | ||||
| 		struct file *filp = fl->fl_file; | ||||
| 
 | ||||
| 		f_delown(filp); | ||||
| 		filp->f_owner.signum = 0; | ||||
| 		locks_delete_lock(before); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user