diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-08-12 08:03:49 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@primarydata.com> | 2014-08-14 10:07:47 -0400 |
commit | b84d49f9440b2b039828f3eb114e4bd4ebeb0c54 (patch) | |
tree | 685156b25d833997ada9caf07bd7f2541efd53bd /fs | |
parent | 566709bd627caf933ab8edffaf598203a0c5c8b2 (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.c | 25 |
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 | } |