Commit 796bcdd1 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[PATCH] Fix posix file locking (1/9)

VFS: Fix up posix_same_owner() so that it only uses the
   file_lock->fl_owner field when determining lock equality.

VFS: Fix up posix locking routines to use posix_same_owner() instead
   of rolling their own checks.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0596d1c6
...@@ -414,14 +414,16 @@ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2) ...@@ -414,14 +414,16 @@ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
} }
/* /*
* Check whether two locks have the same owner. The apparently superfluous * Check whether two locks have the same owner.
* check for fl_pid enables us to distinguish between locks set by lockd.
*/ */
static inline int static inline int
posix_same_owner(struct file_lock *fl1, struct file_lock *fl2) posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
{ {
return (fl1->fl_owner == fl2->fl_owner) && /* FIXME: Replace this sort of thing with struct file_lock_operations */
(fl1->fl_pid == fl2->fl_pid); if ((fl1->fl_type | fl2->fl_type) & FL_LOCKD)
return fl1->fl_owner == fl2->fl_owner &&
fl1->fl_pid == fl2->fl_pid;
return fl1->fl_owner == fl2->fl_owner;
} }
/* Remove waiter from blocker's block list. /* Remove waiter from blocker's block list.
...@@ -631,24 +633,15 @@ int posix_locks_deadlock(struct file_lock *caller_fl, ...@@ -631,24 +633,15 @@ int posix_locks_deadlock(struct file_lock *caller_fl,
struct file_lock *block_fl) struct file_lock *block_fl)
{ {
struct list_head *tmp; struct list_head *tmp;
fl_owner_t caller_owner, blocked_owner;
unsigned int caller_pid, blocked_pid;
caller_owner = caller_fl->fl_owner;
caller_pid = caller_fl->fl_pid;
blocked_owner = block_fl->fl_owner;
blocked_pid = block_fl->fl_pid;
next_task: next_task:
if (caller_owner == blocked_owner && caller_pid == blocked_pid) if (posix_same_owner(caller_fl, block_fl))
return 1; return 1;
list_for_each(tmp, &blocked_list) { list_for_each(tmp, &blocked_list) {
struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
if ((fl->fl_owner == blocked_owner) if (posix_same_owner(fl, block_fl)) {
&& (fl->fl_pid == blocked_pid)) {
fl = fl->fl_next; fl = fl->fl_next;
blocked_owner = fl->fl_owner; block_fl = fl;
blocked_pid = fl->fl_pid;
goto next_task; goto next_task;
} }
} }
...@@ -1684,7 +1677,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) ...@@ -1684,7 +1677,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
lock_kernel(); lock_kernel();
while (*before != NULL) { while (*before != NULL) {
struct file_lock *fl = *before; struct file_lock *fl = *before;
if (IS_POSIX(fl) && (fl->fl_owner == owner)) { if (IS_POSIX(fl) && posix_same_owner(fl, &lock)) {
locks_delete_lock(before); locks_delete_lock(before);
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment