path: root/fs/locks.c
diff options
authorJ. Bruce Fields <bfields@redhat.com>2020-07-07 09:28:05 -0400
committerChuck Lever <chuck.lever@oracle.com>2020-07-13 17:28:46 -0400
commit94415b06eb8aed13481646026dc995f04a3a534a (patch)
tree78d8843cb8a3b8fe4370f214f35be02ecdc77257 /fs/locks.c
parentnfsd: Use seq_putc() in two functions (diff)
nfsd4: a client's own opens needn't prevent delegations
We recently fixed lease breaking so that a client's actions won't break its own delegations. But we still have an unnecessary self-conflict when granting delegations: a client's own write opens will prevent us from handing out a read delegation even when no other client has the file open for write. Fix that by turning off the checks for conflicting opens under vfs_setlease, and instead performing those checks in the nfsd code. We don't depend much on locks here: instead we acquire the delegation, then check for conflicts, and drop the delegation again if we find any. The check beforehand is an optimization of sorts, just to avoid acquiring the delegation unnecessarily. There's a race where the first check could cause us to deny the delegation when we could have granted it. But, that's OK, delegation grants are optional (and probably not even a good idea in that case). Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'fs/locks.c')
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 7df0f9fa66f4..d5de9039dbd7 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1807,6 +1807,9 @@ check_conflicting_open(struct file *filp, const long arg, int flags)
if (flags & FL_LAYOUT)
return 0;
+ if (flags & FL_DELEG)
+ /* We leave these checks to the caller. */
+ return 0;
if (arg == F_RDLCK)
return inode_is_open_for_write(inode) ? -EAGAIN : 0;