Root/
1 | /* |
2 | * Cache operations for Coda. |
3 | * For Linux 2.1: (C) 1997 Carnegie Mellon University |
4 | * For Linux 2.3: (C) 2000 Carnegie Mellon University |
5 | * |
6 | * Carnegie Mellon encourages users of this code to contribute improvements |
7 | * to the Coda project http://www.coda.cs.cmu.edu/ <coda@cs.cmu.edu>. |
8 | */ |
9 | |
10 | #include <linux/types.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/time.h> |
13 | #include <linux/fs.h> |
14 | #include <linux/stat.h> |
15 | #include <linux/errno.h> |
16 | #include <asm/uaccess.h> |
17 | #include <linux/string.h> |
18 | #include <linux/list.h> |
19 | #include <linux/sched.h> |
20 | |
21 | #include <linux/coda.h> |
22 | #include <linux/coda_linux.h> |
23 | #include <linux/coda_psdev.h> |
24 | #include <linux/coda_fs_i.h> |
25 | #include <linux/coda_cache.h> |
26 | |
27 | static atomic_t permission_epoch = ATOMIC_INIT(0); |
28 | |
29 | /* replace or extend an acl cache hit */ |
30 | void coda_cache_enter(struct inode *inode, int mask) |
31 | { |
32 | struct coda_inode_info *cii = ITOC(inode); |
33 | |
34 | cii->c_cached_epoch = atomic_read(&permission_epoch); |
35 | if (cii->c_uid != current_fsuid()) { |
36 | cii->c_uid = current_fsuid(); |
37 | cii->c_cached_perm = mask; |
38 | } else |
39 | cii->c_cached_perm |= mask; |
40 | } |
41 | |
42 | /* remove cached acl from an inode */ |
43 | void coda_cache_clear_inode(struct inode *inode) |
44 | { |
45 | struct coda_inode_info *cii = ITOC(inode); |
46 | cii->c_cached_epoch = atomic_read(&permission_epoch) - 1; |
47 | } |
48 | |
49 | /* remove all acl caches */ |
50 | void coda_cache_clear_all(struct super_block *sb) |
51 | { |
52 | atomic_inc(&permission_epoch); |
53 | } |
54 | |
55 | |
56 | /* check if the mask has been matched against the acl already */ |
57 | int coda_cache_check(struct inode *inode, int mask) |
58 | { |
59 | struct coda_inode_info *cii = ITOC(inode); |
60 | int hit; |
61 | |
62 | hit = (mask & cii->c_cached_perm) == mask && |
63 | cii->c_uid == current_fsuid() && |
64 | cii->c_cached_epoch == atomic_read(&permission_epoch); |
65 | |
66 | return hit; |
67 | } |
68 | |
69 | |
70 | /* Purging dentries and children */ |
71 | /* The following routines drop dentries which are not |
72 | in use and flag dentries which are in use to be |
73 | zapped later. |
74 | |
75 | The flags are detected by: |
76 | - coda_dentry_revalidate (for lookups) if the flag is C_PURGE |
77 | - coda_dentry_delete: to remove dentry from the cache when d_count |
78 | falls to zero |
79 | - an inode method coda_revalidate (for attributes) if the |
80 | flag is C_VATTR |
81 | */ |
82 | |
83 | /* this won't do any harm: just flag all children */ |
84 | static void coda_flag_children(struct dentry *parent, int flag) |
85 | { |
86 | struct list_head *child; |
87 | struct dentry *de; |
88 | |
89 | spin_lock(&dcache_lock); |
90 | list_for_each(child, &parent->d_subdirs) |
91 | { |
92 | de = list_entry(child, struct dentry, d_u.d_child); |
93 | /* don't know what to do with negative dentries */ |
94 | if ( ! de->d_inode ) |
95 | continue; |
96 | coda_flag_inode(de->d_inode, flag); |
97 | } |
98 | spin_unlock(&dcache_lock); |
99 | return; |
100 | } |
101 | |
102 | void coda_flag_inode_children(struct inode *inode, int flag) |
103 | { |
104 | struct dentry *alias_de; |
105 | |
106 | if ( !inode || !S_ISDIR(inode->i_mode)) |
107 | return; |
108 | |
109 | alias_de = d_find_alias(inode); |
110 | if (!alias_de) |
111 | return; |
112 | coda_flag_children(alias_de, flag); |
113 | shrink_dcache_parent(alias_de); |
114 | dput(alias_de); |
115 | } |
116 | |
117 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9