summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve Dickson <steved@redhat.com>2013-05-15 14:51:49 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-07-01 17:23:07 -0400
commit9a0590aec3ca5e86a64b87e004244abc4dd1faf9 (patch)
treef3864074aa12bace1ff2fd082ae1a839cfc4b547 /fs
parent57569a707082a337e4a61a657521d79cac3528bf (diff)
downloadlinux-9a0590aec3ca5e86a64b87e004244abc4dd1faf9.tar.bz2
NFSD: Don't give out read delegations on creates
When an exclusive create is done with the mode bits set (aka open(testfile, O_CREAT | O_EXCL, 0777)) this causes a OPEN op followed by a SETATTR op. When a read delegation is given in the OPEN, it causes the SETATTR to delay with EAGAIN until the delegation is recalled. This patch caused exclusive creates to give out a write delegation (which turn into no delegation) which allows the SETATTR seamlessly succeed. Signed-off-by: Steve Dickson <steved@redhat.com> [bfields: do this for any CREATE, not just exclusive; comment] Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4state.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index c4f63399832c..44dcea96bfcb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3113,8 +3113,17 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
goto out;
if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
goto out;
+ /*
+ * Also, if the file was opened for write or
+ * create, there's a good chance the client's
+ * about to write to it, resulting in an
+ * immediate recall (since we don't support
+ * write delegations):
+ */
if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
flag = NFS4_OPEN_DELEGATE_WRITE;
+ else if (open->op_create == NFS4_OPEN_CREATE)
+ flag = NFS4_OPEN_DELEGATE_WRITE;
else
flag = NFS4_OPEN_DELEGATE_READ;
break;