2004-09-10 22:18:28

by Stuart Hayes

[permalink] [raw]
Subject: RE: flock/posix lock question

Hayes, Stuart wrote:
> Hello--
>
> This question regards file locks and code in fs/locks.c.
>
> I am seeing the kernel get stuck in posix_locks_deadlock() checking
> for deadlocks. It appears that samba (smbd) is getting both an flock
> and a posix lock for the same file, which results in a circular
> dependency in the blocked_list... and posix_locks_deadlock() is
getting
> stuck in that circle.
> The circular dependency gets into the blocked_list because deadlock
> situations aren't checked for when inserting flock requests into the
> blocked_list.
>
> Since flocks aren't supposed to do any deadlock checking, it seems
> like the right solution to this would be to modify
> posix_locks_deadlock() to only check for deadlock situations with
> other posix locks and lock requests, and ignore flocks. Of course,
> samba should also probably be fixed so that it doesn't do that, too...
> but it shouldn't be able to cause a kernel hang by doing so.
>
> Does this sound correct? Am I missing something?
>
> (I am seeing this on a RHEL3 update 3 (2.4.21-20) kernel.)
>
> Thanks!
> Stuart

Here's a patch (untested) just to illustrate what I think needs to be
done:

--- locks.c Wed Apr 21 23:09:18 2004
+++ locks.c.new Fri Sep 10 17:15:04 2004
@@ -685,7 +685,8 @@ next_task:
return 1;
list_for_each(tmp, &blocked_list) {
struct file_lock *fl = list_entry(tmp, struct file_lock,
fl_link);
- if ((fl->fl_owner == blocked_owner)
+ if ( (fl->fl_flags & FL_POSIX)
+ && (fl->fl_owner == blocked_owner)
&& (fl->fl_pid == blocked_pid)) {
fl = fl->fl_next;
blocked_owner = fl->fl_owner;