aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-08-12 08:03:49 -0400
committerJeff Layton <jlayton@primarydata.com>2014-08-14 10:07:47 -0400
commitb84d49f9440b2b039828f3eb114e4bd4ebeb0c54 (patch)
tree685156b25d833997ada9caf07bd7f2541efd53bd /fs
parent566709bd627caf933ab8edffaf598203a0c5c8b2 (diff)
locks: don't reuse file_lock in __posix_lock_file
Currently in the case where a new file lock completely replaces the old one, we end up overwriting the existing lock with the new info. This means that we have to call fl_release_private inside i_lock. Change the code to instead copy the info to new_fl, insert that lock into the correct spot and then delete the old lock. In a later patch, we'll defer the freeing of the old lock until after the i_lock has been dropped. Acked-by: J. Bruce Fields <bfields@fieldses.org> Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/locks.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 2c2d4f5022a7..7dd4defb4d8d 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1022,18 +1022,21 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
1022 locks_delete_lock(before); 1022 locks_delete_lock(before);
1023 continue; 1023 continue;
1024 } 1024 }
1025 /* Replace the old lock with the new one. 1025 /*
1026 * Wake up anybody waiting for the old one, 1026 * Replace the old lock with new_fl, and
1027 * as the change in lock type might satisfy 1027 * remove the old one. It's safe to do the
1028 * their needs. 1028 * insert here since we know that we won't be
1029 * using new_fl later, and that the lock is
1030 * just replacing an existing lock.
1029 */ 1031 */
1030 locks_wake_up_blocks(fl); 1032 error = -ENOLCK;
1031 fl->fl_start = request->fl_start; 1033 if (!new_fl)
1032 fl->fl_end = request->fl_end; 1034 goto out;
1033 fl->fl_type = request->fl_type; 1035 locks_copy_lock(new_fl, request);
1034 locks_release_private(fl); 1036 request = new_fl;
1035 locks_copy_private(fl, request); 1037 new_fl = NULL;
1036 request = fl; 1038 locks_delete_lock(before);
1039 locks_insert_lock(before, request);
1037 added = true; 1040 added = true;
1038 } 1041 }
1039 } 1042 }