diff options
author | ChenXiaoSong <chenxiaosong2@huawei.com> | 2022-03-29 14:32:08 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-04-13 21:59:15 +0300 |
commit | 6f52d4cda0bf77ed53b6d0cd1339ddba46551b98 (patch) | |
tree | cb2df465d8b590ce7c89ddbcc6baca5d8b22b678 /fs/nfs/internal.h | |
parent | 9f0c217469e84e71f7423bce64527c0b56bf9228 (diff) | |
download | linux-6f52d4cda0bf77ed53b6d0cd1339ddba46551b98.tar.xz |
NFSv4: fix open failure with O_ACCMODE flag
[ Upstream commit b243874f6f9568b2daf1a00e9222cacdc15e159c ]
open() with O_ACCMODE|O_DIRECT flags secondly will fail.
Reproducer:
1. mount -t nfs -o vers=4.2 $server_ip:/ /mnt/
2. fd = open("/mnt/file", O_ACCMODE|O_DIRECT|O_CREAT)
3. close(fd)
4. fd = open("/mnt/file", O_ACCMODE|O_DIRECT)
Server nfsd4_decode_share_access() will fail with error nfserr_bad_xdr when
client use incorrect share access mode of 0.
Fix this by using NFS4_SHARE_ACCESS_BOTH share access mode in client,
just like firstly opening.
Fixes: ce4ef7c0a8a05 ("NFS: Split out NFS v4 file operations")
Signed-off-by: ChenXiaoSong <chenxiaosong2@huawei.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/nfs/internal.h')
-rw-r--r-- | fs/nfs/internal.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 7239118d98a3..c8845242d422 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -42,6 +42,16 @@ static inline bool nfs_lookup_is_soft_revalidate(const struct dentry *dentry) return true; } +static inline fmode_t flags_to_mode(int flags) +{ + fmode_t res = (__force fmode_t)flags & FMODE_EXEC; + if ((flags & O_ACCMODE) != O_WRONLY) + res |= FMODE_READ; + if ((flags & O_ACCMODE) != O_RDONLY) + res |= FMODE_WRITE; + return res; +} + /* * Note: RFC 1813 doesn't limit the number of auth flavors that * a server can return, so make something up. |