aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
authorFilipe Brandenburger <filbranden@gmail.com>2012-07-27 00:42:52 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-07-27 09:39:55 -0400
commit3b6e2723f32de42028617f2c99b244ccd72cd959 (patch)
treeaa16a8fdef80496ef394aa75c1d5cf9fd137252d /fs/locks.c
parent57c8b13e3cd0f94944c9691ce7f58e5fcef8a12d (diff)
locks: prevent side-effects of locks_release_private before file_lock is initialized
When calling fcntl(fd, F_SETLEASE, lck) [with lck=F_WRLCK or F_RDLCK], the custom signal or owner (if any were previously set using F_SETSIG or F_SETOWN fcntls) would be reset when F_SETLEASE was called for the second time on the same file descriptor. This bug is a regression of 2.6.37 and is described here: https://bugzilla.kernel.org/show_bug.cgi?id=43336 This patch reverts a commit from Oct 2004 (with subject "nfs4 lease: move the f_delown processing") which originally introduced the lm_release_private callback. Signed-off-by: Filipe Brandenburger <filbranden@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 814c51d0de47..86668dd211ae 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -427,18 +427,8 @@ static void lease_break_callback(struct file_lock *fl)
427 kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG); 427 kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG);
428} 428}
429 429
430static void lease_release_private_callback(struct file_lock *fl)
431{
432 if (!fl->fl_file)
433 return;
434
435 f_delown(fl->fl_file);
436 fl->fl_file->f_owner.signum = 0;
437}
438
439static const struct lock_manager_operations lease_manager_ops = { 430static const struct lock_manager_operations lease_manager_ops = {
440 .lm_break = lease_break_callback, 431 .lm_break = lease_break_callback,
441 .lm_release_private = lease_release_private_callback,
442 .lm_change = lease_modify, 432 .lm_change = lease_modify,
443}; 433};
444 434
@@ -1155,8 +1145,13 @@ int lease_modify(struct file_lock **before, int arg)
1155 return error; 1145 return error;
1156 lease_clear_pending(fl, arg); 1146 lease_clear_pending(fl, arg);
1157 locks_wake_up_blocks(fl); 1147 locks_wake_up_blocks(fl);
1158 if (arg == F_UNLCK) 1148 if (arg == F_UNLCK) {
1149 struct file *filp = fl->fl_file;
1150
1151 f_delown(filp);
1152 filp->f_owner.signum = 0;
1159 locks_delete_lock(before); 1153 locks_delete_lock(before);
1154 }
1160 return 0; 1155 return 0;
1161} 1156}
1162 1157