summaryrefslogtreecommitdiff
path: root/fs/nfs/proc.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2024-03-25 08:36:05 +0300
committerTrond Myklebust <trond.myklebust@hammerspace.com>2024-05-20 18:09:20 +0300
commit7c6c5249f061b64fc6b5b90bc147169a048691bf (patch)
tree4cee132b6fdee4725ba9f47071c21be42c1f0bf4 /fs/nfs/proc.c
parent464b424fb09b894f792a494f10539c190db503cf (diff)
downloadlinux-7c6c5249f061b64fc6b5b90bc147169a048691bf.tar.xz
NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly.
With two clients, each with NFSv3 mounts of the same directory, the sequence: client1 client2 ls -l afile echo hello there > afile echo HELLO > afile cat afile will show HELLO there because the O_TRUNC requested in the final 'echo' doesn't take effect. This is because the "Negative dentry, just create a file" section in lookup_open() assumes that the file *does* get created since the dentry was negative, so it sets FMODE_CREATED, and this causes do_open() to clear O_TRUNC and so the file doesn't get truncated. Even mounting with -o lookupcache=none does not help as nfs_neg_need_reval() always returns false if LOOKUP_CREATE is set. This patch fixes the problem by providing an atomic_open inode operation for NFSv3 (and v2). The code is largely the code from the branch in lookup_open() when atomic_open is not provided. The significant change is that the O_TRUNC flag is passed a new nfs_do_create() which add 'trunc' handling to nfs_create(). With this change we also optimise away an unnecessary LOOKUP before the file is created. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/proc.c')
-rw-r--r--fs/nfs/proc.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index ad3a321ae997..d105e5b2659d 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -695,6 +695,7 @@ static int nfs_have_delegation(struct inode *inode, fmode_t flags)
static const struct inode_operations nfs_dir_inode_operations = {
.create = nfs_create,
.lookup = nfs_lookup,
+ .atomic_open = nfs_atomic_open_v23,
.link = nfs_link,
.unlink = nfs_unlink,
.symlink = nfs_symlink,