diff options
author | Weston Andros Adamson <dros@netapp.com> | 2012-09-10 20:00:46 +0200 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-10-02 00:20:11 +0200 |
commit | 6168f62cbde8dcf4f58255794efbcdb8df603959 (patch) | |
tree | 897bac0b7539172aa171365337d964f7984b1a80 /fs/nfs/dir.c | |
parent | NFS: Use kzalloc() instead of kmalloc() in the idmapper (diff) | |
download | linux-6168f62cbde8dcf4f58255794efbcdb8df603959.tar.xz linux-6168f62cbde8dcf4f58255794efbcdb8df603959.zip |
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.c | 16 |
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: nfs_access_free_entry(entry); } -static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) +void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) { struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); if (cache == NULL) @@ -2098,6 +2098,20 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s spin_unlock(&nfs_access_lru_lock); } } +EXPORT_SYMBOL_GPL(nfs_access_add_cache); + +void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result) +{ + entry->mask = 0; + if (access_result & NFS4_ACCESS_READ) + entry->mask |= MAY_READ; + if (access_result & + (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE)) + entry->mask |= MAY_WRITE; + if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE)) + entry->mask |= MAY_EXEC; +} +EXPORT_SYMBOL_GPL(nfs_access_set_mask); static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) { |