diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:33:38 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-11-04 15:33:38 -0500 |
commit | d530838bfa507d67b40d13b00d9cbd7a46a47e78 (patch) | |
tree | f4b2be26c0a7b9ed3233a2be016b7e97427f8705 /fs/nfs/inode.c | |
parent | 4cecb76ff86db46d2823550256c828b6597f418e (diff) |
NFSv4: Fix problem with OPEN_DOWNGRADE
RFC 3530 states that for OPEN_DOWNGRADE "The share_access and share_deny
bits specified must be exactly equal to the union of the share_access and
share_deny bits specified for some subset of the OPENs in effect for
current openowner on the current file.
Setattr is currently violating the NFSv4 rules for OPEN_DOWNGRADE in that
it may cause a downgrade from OPEN4_SHARE_ACCESS_BOTH to
OPEN4_SHARE_ACCESS_WRITE despite the fact that there exists no open file
with O_WRONLY access mode.
Fix the problem by replacing nfs4_find_state() with a modified version of
nfs_find_open_context().
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index fc0f12ba89cc..24d2fbf549bd 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1009,13 +1009,18 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | |||
1009 | spin_unlock(&inode->i_lock); | 1009 | spin_unlock(&inode->i_lock); |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | struct nfs_open_context *nfs_find_open_context(struct inode *inode, int mode) | 1012 | /* |
1013 | * Given an inode, search for an open context with the desired characteristics | ||
1014 | */ | ||
1015 | struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode) | ||
1013 | { | 1016 | { |
1014 | struct nfs_inode *nfsi = NFS_I(inode); | 1017 | struct nfs_inode *nfsi = NFS_I(inode); |
1015 | struct nfs_open_context *pos, *ctx = NULL; | 1018 | struct nfs_open_context *pos, *ctx = NULL; |
1016 | 1019 | ||
1017 | spin_lock(&inode->i_lock); | 1020 | spin_lock(&inode->i_lock); |
1018 | list_for_each_entry(pos, &nfsi->open_files, list) { | 1021 | list_for_each_entry(pos, &nfsi->open_files, list) { |
1022 | if (cred != NULL && pos->cred != cred) | ||
1023 | continue; | ||
1019 | if ((pos->mode & mode) == mode) { | 1024 | if ((pos->mode & mode) == mode) { |
1020 | ctx = get_nfs_open_context(pos); | 1025 | ctx = get_nfs_open_context(pos); |
1021 | break; | 1026 | break; |