diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-09-01 14:27:43 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@primarydata.com> | 2014-10-07 14:06:13 -0400 |
commit | 843c6b2f4cef384af8e0de6b7ac7191675030e3a (patch) | |
tree | bd40fa64f4a6a5b4a9bcd9f37fafcb32e0efc9da | |
parent | c45198eda2794bb72601c9f96266d8b95db66dd5 (diff) |
locks: remove i_have_this_lease check from __break_lease
I think that the intent of this code was to ensure that a process won't
deadlock if it has one fd open with a lease on it and then breaks that
lease by opening another fd. In that case it'll treat the __break_lease
call as if it were non-blocking.
This seems wrong -- the process could (for instance) be multithreaded
and managing different fds via different threads. I also don't see any
mention of this limitation in the (somewhat sketchy) documentation.
Remove the check and the non-blocking behavior when i_have_this_lease
is true.
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
-rw-r--r-- | fs/locks.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/fs/locks.c b/fs/locks.c index c0f789dfa655..4e8cf5da2868 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1370,7 +1370,6 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | |||
1370 | struct file_lock *new_fl, *flock; | 1370 | struct file_lock *new_fl, *flock; |
1371 | struct file_lock *fl; | 1371 | struct file_lock *fl; |
1372 | unsigned long break_time; | 1372 | unsigned long break_time; |
1373 | int i_have_this_lease = 0; | ||
1374 | bool lease_conflict = false; | 1373 | bool lease_conflict = false; |
1375 | int want_write = (mode & O_ACCMODE) != O_RDONLY; | 1374 | int want_write = (mode & O_ACCMODE) != O_RDONLY; |
1376 | LIST_HEAD(dispose); | 1375 | LIST_HEAD(dispose); |
@@ -1391,8 +1390,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | |||
1391 | for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) { | 1390 | for (fl = flock; fl && IS_LEASE(fl); fl = fl->fl_next) { |
1392 | if (leases_conflict(fl, new_fl)) { | 1391 | if (leases_conflict(fl, new_fl)) { |
1393 | lease_conflict = true; | 1392 | lease_conflict = true; |
1394 | if (fl->fl_owner == current->files) | 1393 | break; |
1395 | i_have_this_lease = 1; | ||
1396 | } | 1394 | } |
1397 | } | 1395 | } |
1398 | if (!lease_conflict) | 1396 | if (!lease_conflict) |
@@ -1422,7 +1420,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) | |||
1422 | fl->fl_lmops->lm_break(fl); | 1420 | fl->fl_lmops->lm_break(fl); |
1423 | } | 1421 | } |
1424 | 1422 | ||
1425 | if (i_have_this_lease || (mode & O_NONBLOCK)) { | 1423 | if (mode & O_NONBLOCK) { |
1426 | trace_break_lease_noblock(inode, new_fl); | 1424 | trace_break_lease_noblock(inode, new_fl); |
1427 | error = -EWOULDBLOCK; | 1425 | error = -EWOULDBLOCK; |
1428 | goto out; | 1426 | goto out; |