Bläddra i källkod

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>
J. Bruce Fields 17 år sedan
förälder
incheckning
1a747ee0cc
4 ändrade filer med 4 tillägg och 6 borttagningar
  1. 1 1
      fs/lockd/svclock.c
  2. 2 2
      fs/locks.c
  3. 0 3
      fs/nfsd/nfs4state.c
  4. 1 0
      include/linux/fs.h

+ 1 - 1
fs/lockd/svclock.c

@@ -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);
 	}
 	}
 }
 }
 
 

+ 2 - 2
fs/locks.c

@@ -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;

+ 0 - 3
fs/nfsd/nfs4state.c

@@ -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! */

+ 1 - 0
include/linux/fs.h

@@ -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 *);