2 * Cache operations for Coda.
3 * For Linux 2.1: (C) 1997 Carnegie Mellon University
5 * Carnegie Mellon encourages users of this code to contribute improvements
6 * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
13 #include <linux/stat.h>
14 #include <linux/errno.h>
15 #include <linux/locks.h>
16 #include <asm/segment.h>
17 #include <asm/uaccess.h>
18 #include <linux/string.h>
19 #include <linux/list.h>
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>
27 static void coda_ccinsert(struct coda_cache
*el
, struct super_block
*sb
);
28 static void coda_cninsert(struct coda_cache
*el
, struct coda_inode_info
*cii
);
29 static void coda_ccremove(struct coda_cache
*el
);
30 static void coda_cnremove(struct coda_cache
*el
);
31 static void coda_cache_create(struct inode
*inode
, int mask
);
32 static struct coda_cache
* coda_cache_find(struct inode
*inode
);
35 /* insert a acl-cache entry in sb list */
36 static void coda_ccinsert(struct coda_cache
*el
, struct super_block
*sb
)
38 struct coda_sb_info
*sbi
= coda_sbp(sb
);
40 /* third test verifies cc was initialized before adding it
41 to the sblist. Probably superfluous */
42 if ( !sbi
|| !el
|| !list_empty(&el
->cc_cclist
) ) {
43 printk("coda_ccinsert: NULL sbi or el->cc_cclist not empty!\n");
47 list_add(&el
->cc_cclist
, &sbi
->sbi_cchead
);
50 /* insert a acl-cache entry in the inode list */
51 static void coda_cninsert(struct coda_cache
*el
, struct coda_inode_info
*cii
)
54 if ( !cii
|| !el
|| ! list_empty(&el
->cc_cnlist
)) {
55 printk("coda_cninsert: NULL cii or el->cc_cnlist not empty!\n");
58 list_add(&el
->cc_cnlist
, &cii
->c_cnhead
);
61 /* remove a cache entry from the superblock list */
62 static void coda_ccremove(struct coda_cache
*el
)
65 if ( ! list_empty(&el
->cc_cclist
) )
66 list_del(&el
->cc_cclist
);
68 printk("coda_cnremove: loose cc entry!");
71 /* remove a cache entry from the inode's list */
72 static void coda_cnremove(struct coda_cache
*el
)
75 if ( ! list_empty(&el
->cc_cnlist
) )
76 list_del(&el
->cc_cnlist
);
78 printk("coda_cnremove: loose cn entry!");
81 /* create a new cache entry and enlist it */
82 static void coda_cache_create(struct inode
*inode
, int mask
)
84 struct coda_inode_info
*cii
= ITOC(inode
);
85 struct super_block
*sb
= inode
->i_sb
;
86 struct coda_cache
*cc
= NULL
;
89 CODA_ALLOC(cc
, struct coda_cache
*, sizeof(*cc
));
92 printk("Out of memory in coda_cache_enter!\n");
96 INIT_LIST_HEAD(&cc
->cc_cclist
);
97 INIT_LIST_HEAD(&cc
->cc_cnlist
);
99 coda_load_creds(&cc
->cc_cred
);
101 coda_cninsert(cc
, cii
);
102 coda_ccinsert(cc
, sb
);
105 /* see if there is a match for the current
106 credentials already */
107 static struct coda_cache
* coda_cache_find(struct inode
*inode
)
109 struct coda_inode_info
*cii
= ITOC(inode
);
110 struct list_head
*lh
, *le
;
111 struct coda_cache
*cc
= NULL
;
113 le
= lh
= &cii
->c_cnhead
;
114 while( (le
= le
->next
) != lh
) {
115 /* compare name and creds */
116 cc
= list_entry(le
, struct coda_cache
, cc_cnlist
);
117 if ( !coda_cred_ok(&cc
->cc_cred
) )
119 CDEBUG(D_CACHE
, "HIT for ino %ld\n", inode
->i_ino
);
120 return cc
; /* cache hit */
125 /* create or extend an acl cache hit */
126 void coda_cache_enter(struct inode
*inode
, int mask
)
128 struct coda_cache
*cc
;
130 cc
= coda_cache_find(inode
);
135 coda_cache_create(inode
, mask
);
139 /* remove all cached acl matches from an inode */
140 void coda_cache_clear_inode(struct inode
*inode
)
142 struct list_head
*lh
, *le
;
143 struct coda_inode_info
*cii
;
144 struct coda_cache
*cc
;
148 CDEBUG(D_CACHE
, "coda_cache_clear_inode: NULL inode\n");
153 lh
= le
= &cii
->c_cnhead
;
154 while ( (le
= le
->next
) != lh
) {
155 cc
= list_entry(le
, struct coda_cache
, cc_cnlist
);
158 CODA_FREE(cc
, sizeof(*cc
));
162 /* remove all acl caches */
163 void coda_cache_clear_all(struct super_block
*sb
)
165 struct list_head
*lh
, *le
;
166 struct coda_cache
*cc
;
167 struct coda_sb_info
*sbi
= coda_sbp(sb
);
170 printk("coda_cache_clear_all: NULL sbi\n");
174 if ( list_empty(&sbi
->sbi_cchead
) )
177 lh
= le
= &sbi
->sbi_cchead
;
178 while ( (le
= le
->next
) != lh
) {
179 cc
= list_entry(le
, struct coda_cache
, cc_cclist
);
182 CODA_FREE(cc
, sizeof(*cc
));
186 /* remove all acl caches for a principal */
187 void coda_cache_clear_cred(struct super_block
*sb
, struct coda_cred
*cred
)
189 struct list_head
*lh
, *le
;
190 struct coda_cache
*cc
;
191 struct coda_sb_info
*sbi
= coda_sbp(sb
);
194 printk("coda_cache_clear_all: NULL sbi\n");
198 if (list_empty(&sbi
->sbi_cchead
))
201 lh
= le
= &sbi
->sbi_cchead
;
202 while ( (le
= le
->next
) != lh
) {
203 cc
= list_entry(le
, struct coda_cache
, cc_cclist
);
204 if ( coda_cred_eq(&cc
->cc_cred
, cred
)) {
207 CODA_FREE(cc
, sizeof(*cc
));
213 /* check if the mask has been matched against the acl
215 int coda_cache_check(struct inode
*inode
, int mask
)
217 struct coda_inode_info
*cii
= ITOC(inode
);
218 struct list_head
*lh
, *le
;
219 struct coda_cache
*cc
= NULL
;
221 le
= lh
= &cii
->c_cnhead
;
222 while( (le
= le
->next
) != lh
) {
223 /* compare name and creds */
224 cc
= list_entry(le
, struct coda_cache
, cc_cnlist
);
225 if ( (cc
->cc_mask
& mask
) != mask
)
227 if ( !coda_cred_ok(&cc
->cc_cred
) )
229 CDEBUG(D_CACHE
, "HIT for ino %ld\n", inode
->i_ino
);
230 return 1; /* cache hit */
232 CDEBUG(D_CACHE
, "MISS for ino %ld\n", inode
->i_ino
);
237 /* Purging dentries and children */
238 /* The following routines drop dentries which are not
239 in use and flag dentries which are in use to be
242 The flags are detected by:
243 - coda_dentry_revalidate (for lookups) if the flag is C_PURGE
244 - coda_dentry_delete: to remove dentry from the cache when d_count
246 - an inode method coda_revalidate (for attributes) if the
251 Some of this is pretty scary: what can disappear underneath us?
252 - shrink_dcache_parent calls on purge_one_dentry which is safe:
253 it only purges children.
254 - dput is evil since it may recurse up the dentry tree
257 void coda_purge_dentries(struct inode
*inode
)
259 struct list_head
*tmp
, *head
= &inode
->i_dentry
;
264 /* better safe than sorry: dput could kill us */
265 iget(inode
->i_sb
, inode
->i_ino
);
266 /* catch the dentries later if some are still busy */
267 coda_flag_inode(inode
, C_PURGE
);
271 while ((tmp
= tmp
->next
) != head
) {
272 struct dentry
*dentry
= list_entry(tmp
, struct dentry
, d_alias
);
273 if (!dentry
->d_count
) {
275 "coda_free_dentries: freeing %s/%s, i_count=%d\n",
276 dentry
->d_parent
->d_name
.name
, dentry
->d_name
.name
,
288 /* this won't do any harm: just flag all children */
289 static void coda_flag_children(struct dentry
*parent
, int flag
)
291 struct list_head
*child
;
294 child
= parent
->d_subdirs
.next
;
295 while ( child
!= &parent
->d_subdirs
) {
296 de
= list_entry(child
, struct dentry
, d_child
);
298 /* don't know what to do with negative dentries */
301 CDEBUG(D_DOWNCALL
, "%d for %*s/%*s\n", flag
,
302 de
->d_name
.len
, de
->d_name
.name
,
303 de
->d_parent
->d_name
.len
, de
->d_parent
->d_name
.name
);
304 coda_flag_inode(de
->d_inode
, flag
);
309 void coda_flag_inode_children(struct inode
*inode
, int flag
)
311 struct list_head
*alias
;
312 struct dentry
*alias_de
;
318 if (list_empty(&inode
->i_dentry
))
321 /* I believe that shrink_dcache_parent will not
322 remove dentries from the alias list. If it
325 alias
= inode
->i_dentry
.next
;
326 while ( alias
!= &inode
->i_dentry
) {
327 alias_de
= list_entry(alias
, struct dentry
, d_alias
);
328 coda_flag_children(alias_de
, flag
);
330 shrink_dcache_parent(alias_de
);
335 /* this will not zap the inode away */
336 void coda_flag_inode(struct inode
*inode
, int flag
)
338 struct coda_inode_info
*cii
;
341 CDEBUG(D_CACHE
, " no inode!\n");
346 cii
->c_flags
|= flag
;