This is a note to let you know that I've just added the patch titled lockd: send correct lock when granting a delayed lock. to the 3.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: lockd-send-correct-lock-when-granting-a-delayed-lock.patch and it can be found in the queue-3.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 2ec197db1a56c9269d75e965f14c344b58b2a4f6 Mon Sep 17 00:00:00 2001 From: NeilBrown <neilb@xxxxxxx> Date: Fri, 7 Feb 2014 17:10:26 +1100 Subject: lockd: send correct lock when granting a delayed lock. From: NeilBrown <neilb@xxxxxxx> commit 2ec197db1a56c9269d75e965f14c344b58b2a4f6 upstream. If an NFS client attempts to get a lock (using NLM) and the lock is not available, the server will remember the request and when the lock becomes available it will send a GRANT request to the client to provide the lock. If the client already held an adjacent lock, the GRANT callback will report the union of the existing and new locks, which can confuse the client. This happens because __posix_lock_file (called by vfs_lock_file) updates the passed-in file_lock structure when adjacent or over-lapping locks are found. To avoid this problem we take a copy of the two fields that can be changed (fl_start and fl_end) before the call and restore them afterwards. An alternate would be to allocate a 'struct file_lock', initialise it, use locks_copy_lock() to take a copy, then locks_release_private() after the vfs_lock_file() call. But that is a lot more work. Reported-by: Olaf Kirch <okir@xxxxxxxx> Signed-off-by: NeilBrown <neilb@xxxxxxx> Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> -- v1 had a couple of issues (large on-stack struct and didn't really work properly). This version is much better tested. Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxx> --- fs/lockd/svclock.c | 8 ++++++++ 1 file changed, 8 insertions(+) --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -769,6 +769,7 @@ nlmsvc_grant_blocked(struct nlm_block *b struct nlm_file *file = block->b_file; struct nlm_lock *lock = &block->b_call->a_args.lock; int error; + loff_t fl_start, fl_end; dprintk("lockd: grant blocked lock %p\n", block); @@ -786,9 +787,16 @@ nlmsvc_grant_blocked(struct nlm_block *b } /* Try the lock operation again */ + /* vfs_lock_file() can mangle fl_start and fl_end, but we need + * them unchanged for the GRANT_MSG + */ lock->fl.fl_flags |= FL_SLEEP; + fl_start = lock->fl.fl_start; + fl_end = lock->fl.fl_end; error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); lock->fl.fl_flags &= ~FL_SLEEP; + lock->fl.fl_start = fl_start; + lock->fl.fl_end = fl_end; switch (error) { case 0: Patches currently in stable-queue which might be from neilb@xxxxxxx are queue-3.4/lockd-send-correct-lock-when-granting-a-delayed-lock.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html