]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly.
authorNeilBrown <neilb@suse.de>
Mon, 25 Mar 2024 05:36:05 +0000 (16:36 +1100)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 20 May 2024 15:09:20 +0000 (11:09 -0400)
commit7c6c5249f061b64fc6b5b90bc147169a048691bf
tree4cee132b6fdee4725ba9f47071c21be42c1f0bf4
parent464b424fb09b894f792a494f10539c190db503cf
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>
fs/nfs/dir.c
fs/nfs/nfs3proc.c
fs/nfs/proc.c
include/linux/nfs_fs.h