aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2012-09-10 14:00:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:20:11 -0400
commit6168f62cbde8dcf4f58255794efbcdb8df603959 (patch)
tree897bac0b7539172aa171365337d964f7984b1a80 /fs/nfs/dir.c
parent57a51048da742c764b6ce5d028c7f334ae04d363 (diff)
NFSv4: Add ACCESS operation to OPEN compound
The OPEN operation has no way to differentiate an open for read and an open for execution - both look like read to the server. This allowed users to read files that didn't have READ access but did have EXEC access, which is obviously wrong. This patch adds an ACCESS call to the OPEN compound to handle the difference between OPENs for reading and execution. Since we're going through the trouble of calling ACCESS, we check all possible access bits and cache the results hopefully avoiding an ACCESS call in the future. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 627f108ede23..ce8cb926526b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2072,7 +2072,7 @@ found:
2072 nfs_access_free_entry(entry); 2072 nfs_access_free_entry(entry);
2073} 2073}
2074 2074
2075static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) 2075void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
2076{ 2076{
2077 struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); 2077 struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
2078 if (cache == NULL) 2078 if (cache == NULL)
@@ -2098,6 +2098,20 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
2098 spin_unlock(&nfs_access_lru_lock); 2098 spin_unlock(&nfs_access_lru_lock);
2099 } 2099 }
2100} 2100}
2101EXPORT_SYMBOL_GPL(nfs_access_add_cache);
2102
2103void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
2104{
2105 entry->mask = 0;
2106 if (access_result & NFS4_ACCESS_READ)
2107 entry->mask |= MAY_READ;
2108 if (access_result &
2109 (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
2110 entry->mask |= MAY_WRITE;
2111 if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
2112 entry->mask |= MAY_EXEC;
2113}
2114EXPORT_SYMBOL_GPL(nfs_access_set_mask);
2101 2115
2102static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) 2116static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2103{ 2117{