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>
This commit is contained in:
Родитель
57c8b13e3c
Коммит
3b6e2723f3
17
fs/locks.c
17
fs/locks.c
|
@ -427,18 +427,8 @@ static void lease_break_callback(struct file_lock *fl)
|
||||||
kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG);
|
kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lease_release_private_callback(struct file_lock *fl)
|
|
||||||
{
|
|
||||||
if (!fl->fl_file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
f_delown(fl->fl_file);
|
|
||||||
fl->fl_file->f_owner.signum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct lock_manager_operations lease_manager_ops = {
|
static const struct lock_manager_operations lease_manager_ops = {
|
||||||
.lm_break = lease_break_callback,
|
.lm_break = lease_break_callback,
|
||||||
.lm_release_private = lease_release_private_callback,
|
|
||||||
.lm_change = lease_modify,
|
.lm_change = lease_modify,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1155,8 +1145,13 @@ int lease_modify(struct file_lock **before, int arg)
|
||||||
return error;
|
return error;
|
||||||
lease_clear_pending(fl, arg);
|
lease_clear_pending(fl, arg);
|
||||||
locks_wake_up_blocks(fl);
|
locks_wake_up_blocks(fl);
|
||||||
if (arg == F_UNLCK)
|
if (arg == F_UNLCK) {
|
||||||
|
struct file *filp = fl->fl_file;
|
||||||
|
|
||||||
|
f_delown(filp);
|
||||||
|
filp->f_owner.signum = 0;
|
||||||
locks_delete_lock(before);
|
locks_delete_lock(before);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче