0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/types.h>
0012 #include <linux/kernel.h>
0013 #include <linux/time.h>
0014 #include <linux/fs.h>
0015 #include <linux/stat.h>
0016 #include <linux/errno.h>
0017 #include <linux/uaccess.h>
0018 #include <linux/string.h>
0019 #include <linux/list.h>
0020 #include <linux/sched.h>
0021 #include <linux/spinlock.h>
0022
0023 #include <linux/coda.h>
0024 #include "coda_psdev.h"
0025 #include "coda_linux.h"
0026 #include "coda_cache.h"
0027
0028 static atomic_t permission_epoch = ATOMIC_INIT(0);
0029
0030
0031 void coda_cache_enter(struct inode *inode, int mask)
0032 {
0033 struct coda_inode_info *cii = ITOC(inode);
0034
0035 spin_lock(&cii->c_lock);
0036 cii->c_cached_epoch = atomic_read(&permission_epoch);
0037 if (!uid_eq(cii->c_uid, current_fsuid())) {
0038 cii->c_uid = current_fsuid();
0039 cii->c_cached_perm = mask;
0040 } else
0041 cii->c_cached_perm |= mask;
0042 spin_unlock(&cii->c_lock);
0043 }
0044
0045
0046 void coda_cache_clear_inode(struct inode *inode)
0047 {
0048 struct coda_inode_info *cii = ITOC(inode);
0049 spin_lock(&cii->c_lock);
0050 cii->c_cached_epoch = atomic_read(&permission_epoch) - 1;
0051 spin_unlock(&cii->c_lock);
0052 }
0053
0054
0055 void coda_cache_clear_all(struct super_block *sb)
0056 {
0057 atomic_inc(&permission_epoch);
0058 }
0059
0060
0061
0062 int coda_cache_check(struct inode *inode, int mask)
0063 {
0064 struct coda_inode_info *cii = ITOC(inode);
0065 int hit;
0066
0067 spin_lock(&cii->c_lock);
0068 hit = (mask & cii->c_cached_perm) == mask &&
0069 uid_eq(cii->c_uid, current_fsuid()) &&
0070 cii->c_cached_epoch == atomic_read(&permission_epoch);
0071 spin_unlock(&cii->c_lock);
0072
0073 return hit;
0074 }
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 static void coda_flag_children(struct dentry *parent, int flag)
0092 {
0093 struct dentry *de;
0094
0095 spin_lock(&parent->d_lock);
0096 list_for_each_entry(de, &parent->d_subdirs, d_child) {
0097
0098 if (d_inode(de) )
0099 coda_flag_inode(d_inode(de), flag);
0100 }
0101 spin_unlock(&parent->d_lock);
0102 return;
0103 }
0104
0105 void coda_flag_inode_children(struct inode *inode, int flag)
0106 {
0107 struct dentry *alias_de;
0108
0109 if ( !inode || !S_ISDIR(inode->i_mode))
0110 return;
0111
0112 alias_de = d_find_alias(inode);
0113 if (!alias_de)
0114 return;
0115 coda_flag_children(alias_de, flag);
0116 shrink_dcache_parent(alias_de);
0117 dput(alias_de);
0118 }
0119