mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	locks: don't call ->copy_lock methods on return of conflicting locks
The file_lock structure is used both as a heavy-weight representation of an active lock, with pointers to reference-counted structures, etc., and as a simple container for parameters that describe a file lock. The conflicting lock returned from __posix_lock_file is an example of the latter; so don't call the filesystem or lock manager callbacks when copying to it. This also saves the need for an unnecessary locks_init_lock in the nfsv4 server. Thanks to Trond for pointing out the error. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
		
							parent
							
								
									17efa372cf
								
							
						
					
					
						commit
						1a747ee0cc
					
				
					 4 changed files with 4 additions and 6 deletions
				
			
		| 
						 | 
					@ -632,7 +632,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
 | 
				
			||||||
		block->b_flags |= B_TIMED_OUT;
 | 
							block->b_flags |= B_TIMED_OUT;
 | 
				
			||||||
	if (conf) {
 | 
						if (conf) {
 | 
				
			||||||
		if (block->b_fl)
 | 
							if (block->b_fl)
 | 
				
			||||||
			locks_copy_lock(block->b_fl, conf);
 | 
								__locks_copy_lock(block->b_fl, conf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,7 +224,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Initialize a new lock from an existing file_lock structure.
 | 
					 * Initialize a new lock from an existing file_lock structure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
 | 
					void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	new->fl_owner = fl->fl_owner;
 | 
						new->fl_owner = fl->fl_owner;
 | 
				
			||||||
	new->fl_pid = fl->fl_pid;
 | 
						new->fl_pid = fl->fl_pid;
 | 
				
			||||||
| 
						 | 
					@ -833,7 +833,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
 | 
				
			||||||
			if (!posix_locks_conflict(request, fl))
 | 
								if (!posix_locks_conflict(request, fl))
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			if (conflock)
 | 
								if (conflock)
 | 
				
			||||||
				locks_copy_lock(conflock, fl);
 | 
									__locks_copy_lock(conflock, fl);
 | 
				
			||||||
			error = -EAGAIN;
 | 
								error = -EAGAIN;
 | 
				
			||||||
			if (!(request->fl_flags & FL_SLEEP))
 | 
								if (!(request->fl_flags & FL_SLEEP))
 | 
				
			||||||
				goto out;
 | 
									goto out;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2712,9 +2712,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 | 
				
			||||||
	* Note: locks.c uses the BKL to protect the inode's lock list.
 | 
						* Note: locks.c uses the BKL to protect the inode's lock list.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* XXX?: Just to divert the locks_release_private at the start of
 | 
					 | 
				
			||||||
	 * locks_copy_lock: */
 | 
					 | 
				
			||||||
	locks_init_lock(&conflock);
 | 
					 | 
				
			||||||
	err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
 | 
						err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
 | 
				
			||||||
	switch (-err) {
 | 
						switch (-err) {
 | 
				
			||||||
	case 0: /* success! */
 | 
						case 0: /* success! */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -973,6 +973,7 @@ extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
 | 
				
			||||||
/* fs/locks.c */
 | 
					/* fs/locks.c */
 | 
				
			||||||
extern void locks_init_lock(struct file_lock *);
 | 
					extern void locks_init_lock(struct file_lock *);
 | 
				
			||||||
extern void locks_copy_lock(struct file_lock *, struct file_lock *);
 | 
					extern void locks_copy_lock(struct file_lock *, struct file_lock *);
 | 
				
			||||||
 | 
					extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
 | 
				
			||||||
extern void locks_remove_posix(struct file *, fl_owner_t);
 | 
					extern void locks_remove_posix(struct file *, fl_owner_t);
 | 
				
			||||||
extern void locks_remove_flock(struct file *);
 | 
					extern void locks_remove_flock(struct file *);
 | 
				
			||||||
extern void posix_test_lock(struct file *, struct file_lock *);
 | 
					extern void posix_test_lock(struct file *, struct file_lock *);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue