aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 0127a2846819..8b8388eca05e 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -696,17 +696,28 @@ EXPORT_SYMBOL(posix_test_lock);
696 * Note: the above assumption may not be true when handling lock requests 696 * Note: the above assumption may not be true when handling lock requests
697 * from a broken NFS client. But broken NFS clients have a lot more to 697 * from a broken NFS client. But broken NFS clients have a lot more to
698 * worry about than proper deadlock detection anyway... --okir 698 * worry about than proper deadlock detection anyway... --okir
699 *
700 * However, the failure of this assumption (also possible in the case of
701 * multiple tasks sharing the same open file table) also means there's no
702 * guarantee that the loop below will terminate. As a hack, we give up
703 * after a few iterations.
699 */ 704 */
705
706#define MAX_DEADLK_ITERATIONS 10
707
700static int posix_locks_deadlock(struct file_lock *caller_fl, 708static int posix_locks_deadlock(struct file_lock *caller_fl,
701 struct file_lock *block_fl) 709 struct file_lock *block_fl)
702{ 710{
703 struct file_lock *fl; 711 struct file_lock *fl;
712 int i = 0;
704 713
705next_task: 714next_task:
706 if (posix_same_owner(caller_fl, block_fl)) 715 if (posix_same_owner(caller_fl, block_fl))
707 return 1; 716 return 1;
708 list_for_each_entry(fl, &blocked_list, fl_link) { 717 list_for_each_entry(fl, &blocked_list, fl_link) {
709 if (posix_same_owner(fl, block_fl)) { 718 if (posix_same_owner(fl, block_fl)) {
719 if (i++ > MAX_DEADLK_ITERATIONS)
720 return 0;
710 fl = fl->fl_next; 721 fl = fl->fl_next;
711 block_fl = fl; 722 block_fl = fl;
712 goto next_task; 723 goto next_task;