aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-11-04 15:33:38 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-11-04 15:33:38 -0500
commitd530838bfa507d67b40d13b00d9cbd7a46a47e78 (patch)
treef4b2be26c0a7b9ed3233a2be016b7e97427f8705 /fs/nfs/inode.c
parent4cecb76ff86db46d2823550256c828b6597f418e (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.c7
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
1012struct 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 */
1015struct 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;