51 lines
1.6 KiB
Diff
51 lines
1.6 KiB
Diff
Bugzilla: 1082586
|
|
Upstream-status: 3.15 and sent for stable
|
|
|
|
From f1c6bb2cb8b81013e8979806f8e15e3d53efb96d Mon Sep 17 00:00:00 2001
|
|
From: Jeff Layton <jlayton@redhat.com>
|
|
Date: Tue, 15 Apr 2014 06:17:49 -0400
|
|
Subject: [PATCH] locks: allow __break_lease to sleep even when break_time is 0
|
|
|
|
A fl->fl_break_time of 0 has a special meaning to the lease break code
|
|
that basically means "never break the lease". knfsd uses this to ensure
|
|
that leases don't disappear out from under it.
|
|
|
|
Unfortunately, the code in __break_lease can end up passing this value
|
|
to wait_event_interruptible as a timeout, which prevents it from going
|
|
to sleep at all. This makes __break_lease to spin in a tight loop and
|
|
causes soft lockups.
|
|
|
|
Fix this by ensuring that we pass a minimum value of 1 as a timeout
|
|
instead.
|
|
|
|
Cc: <stable@vger.kernel.org>
|
|
Cc: J. Bruce Fields <bfields@fieldses.org>
|
|
Reported-by: Terry Barnaby <terry1@beam.ltd.uk>
|
|
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
---
|
|
fs/locks.c | 7 +++----
|
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/fs/locks.c b/fs/locks.c
|
|
index 13fc7a6d380a..b380f5543614 100644
|
|
--- a/fs/locks.c
|
|
+++ b/fs/locks.c
|
|
@@ -1391,11 +1391,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
|
|
|
|
restart:
|
|
break_time = flock->fl_break_time;
|
|
- if (break_time != 0) {
|
|
+ if (break_time != 0)
|
|
break_time -= jiffies;
|
|
- if (break_time == 0)
|
|
- break_time++;
|
|
- }
|
|
+ if (break_time == 0)
|
|
+ break_time++;
|
|
locks_insert_block(flock, new_fl);
|
|
spin_unlock(&inode->i_lock);
|
|
error = wait_event_interruptible_timeout(new_fl->fl_wait,
|
|
--
|
|
1.9.0
|
|
|