aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2022-01-06 18:24:03 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2022-01-07 11:59:31 -0500
commit1751fc1db36f6f411709e143d5393f92d12137a9 (patch)
tree0d6e8fefd8236b4b6ffe6a9665d66eee7e9246fb /fs/nfs/dir.c
parentNFSv4: Handle case where the lookup of a directory fails (diff)
downloadlinux-dev-1751fc1db36f6f411709e143d5393f92d12137a9.tar.xz
linux-dev-1751fc1db36f6f411709e143d5393f92d12137a9.zip
NFSv4: nfs_atomic_open() can race when looking up a non-regular file
If the file type changes back to being a regular file on the server between the failed OPEN and our LOOKUP, then we need to re-run the OPEN. Fixes: 0dd2b474d0b6 ("nfs: implement i_op->atomic_open()") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 408c3bb549b1..5df75ed09268 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1999,12 +1999,17 @@ no_open:
if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
!S_ISDIR(inode->i_mode))
res = ERR_PTR(-ENOTDIR);
+ else if (inode && S_ISREG(inode->i_mode))
+ res = ERR_PTR(-EOPENSTALE);
} else if (!IS_ERR(res)) {
inode = d_inode(res);
if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
!S_ISDIR(inode->i_mode)) {
dput(res);
res = ERR_PTR(-ENOTDIR);
+ } else if (inode && S_ISREG(inode->i_mode)) {
+ dput(res);
+ res = ERR_PTR(-EOPENSTALE);
}
}
if (switched) {