diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-18 17:17:51 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-18 17:17:51 +0000 |
commit | f1382dc4850bb459d24a81c6cb0ef93ea7bd4a79 (patch) | |
tree | 225271a3d5dcd4e9dea5ee393556abd754c964b1 /fs/coda/cache.c | |
parent | 135b00fc2e90e605ac2a96b20b0ebd93851a3f89 (diff) |
o Merge with Linux 2.1.90.
o Divide L1 cache sizes by 1024 before printing, makes the numbers a
bit more credible ...
Diffstat (limited to 'fs/coda/cache.c')
-rw-r--r-- | fs/coda/cache.c | 196 |
1 files changed, 91 insertions, 105 deletions
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 7673bfbdd..cdf586507 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -24,16 +24,22 @@ #include <linux/coda_fs_i.h> #include <linux/coda_cache.h> -/* Keep various stats */ -struct cfsnc_statistics cfsnc_stat; +static void coda_ccinsert(struct coda_cache *el, struct super_block *sb); +static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii); +static void coda_ccremove(struct coda_cache *el); +static void coda_cnremove(struct coda_cache *el); +static void coda_cache_create(struct inode *inode, int mask); +static struct coda_cache * coda_cache_find(struct inode *inode); -/* we need to call INIT_LIST_HEAD on cnp->c_cnhead and sbi->sbi_cchead */ +/* Keep various stats */ +struct cfsnc_statistics cfsnc_stat; -void coda_ccinsert(struct coda_cache *el, struct super_block *sb) +/* insert a acl-cache entry in sb list */ +static void coda_ccinsert(struct coda_cache *el, struct super_block *sb) { struct coda_sb_info *sbi = coda_sbp(sb); -ENTRY; + ENTRY; if ( !sbi || !el) { printk("coda_ccinsert: NULL sbi or el!\n"); return ; @@ -42,17 +48,19 @@ ENTRY; list_add(&el->cc_cclist, &sbi->sbi_cchead); } -void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cnp) +/* insert a acl-cache entry in the inode list */ +static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii) { -ENTRY; - if ( !cnp || !el) { - printk("coda_cninsert: NULL cnp or el!\n"); + ENTRY; + if ( !cii || !el) { + printk("coda_cninsert: NULL cii or el!\n"); return ; } - list_add(&el->cc_cnlist, &cnp->c_cnhead); + list_add(&el->cc_cnlist, &cii->c_cnhead); } -void coda_ccremove(struct coda_cache *el) +/* remove a cache entry from the superblock list */ +static void coda_ccremove(struct coda_cache *el) { ENTRY; if (el->cc_cclist.next && el->cc_cclist.prev) @@ -61,7 +69,8 @@ void coda_ccremove(struct coda_cache *el) printk("coda_cnremove: trying to remove 0 entry!"); } -void coda_cnremove(struct coda_cache *el) +/* remove a cache entry from the inode's list */ +static void coda_cnremove(struct coda_cache *el) { ENTRY; if (el->cc_cnlist.next && el->cc_cnlist.prev) @@ -70,10 +79,10 @@ void coda_cnremove(struct coda_cache *el) printk("coda_cnremove: trying to remove 0 entry!"); } - -void coda_cache_create(struct inode *inode, int mask) +/* create a new cache entry and enlist it */ +static void coda_cache_create(struct inode *inode, int mask) { - struct coda_inode_info *cnp = ITOC(inode); + struct coda_inode_info *cii = ITOC(inode); struct super_block *sb = inode->i_sb; struct coda_cache *cc = NULL; ENTRY; @@ -85,17 +94,19 @@ void coda_cache_create(struct inode *inode, int mask) } coda_load_creds(&cc->cc_cred); cc->cc_mask = mask; - coda_cninsert(cc, cnp); + coda_cninsert(cc, cii); coda_ccinsert(cc, sb); } -struct coda_cache * coda_cache_find(struct inode *inode) +/* see if there is a match for the current + credentials already */ +static struct coda_cache * coda_cache_find(struct inode *inode) { - struct coda_inode_info *cnp = ITOC(inode); + struct coda_inode_info *cii = ITOC(inode); struct list_head *lh, *le; struct coda_cache *cc = NULL; - le = lh = &cnp->c_cnhead; + le = lh = &cii->c_cnhead; while( (le = le->next ) != lh ) { /* compare name and creds */ cc = list_entry(le, struct coda_cache, cc_cnlist); @@ -107,6 +118,7 @@ struct coda_cache * coda_cache_find(struct inode *inode) return NULL; } +/* create or extend an acl cache hit */ void coda_cache_enter(struct inode *inode, int mask) { struct coda_cache *cc; @@ -120,17 +132,21 @@ void coda_cache_enter(struct inode *inode, int mask) } } -void coda_cache_clear_cnp(struct coda_inode_info *cnp) +/* remove all cached acl matches from an inode */ +void coda_cache_clear_inode(struct inode *inode) { struct list_head *lh, *le; + struct coda_inode_info *cii; struct coda_cache *cc; + ENTRY; - if ( !cnp ) { - printk("coda_cache_cnp_clear: NULL cnode\n"); + if ( !inode ) { + CDEBUG(D_CACHE, "coda_cache_clear_inode: NULL inode\n"); return; } + cii = ITOC(inode); - lh = le = &cnp->c_cnhead; + lh = le = &cii->c_cnhead; while ( (le = le->next ) != lh ) { cc = list_entry(le, struct coda_cache, cc_cnlist); coda_cnremove(cc); @@ -139,6 +155,7 @@ void coda_cache_clear_cnp(struct coda_inode_info *cnp) } } +/* remove all acl caches */ void coda_cache_clear_all(struct super_block *sb) { struct list_head *lh, *le; @@ -150,6 +167,9 @@ void coda_cache_clear_all(struct super_block *sb) return; } + if ( list_empty(&sbi->sbi_cchead) ) + return; + lh = le = &sbi->sbi_cchead; while ( (le = le->next ) != lh ) { cc = list_entry(le, struct coda_cache, cc_cclist); @@ -159,6 +179,7 @@ void coda_cache_clear_all(struct super_block *sb) } } +/* remove all acl caches for a principal */ void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred) { struct list_head *lh, *le; @@ -170,6 +191,9 @@ void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred) return; } + if (list_empty(&sbi->sbi_cchead)) + return; + lh = le = &sbi->sbi_cchead; while ( (le = le->next ) != lh ) { cc = list_entry(le, struct coda_cache, cc_cclist); @@ -180,15 +204,17 @@ void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred) } } } - + +/* check if the mask has been matched against the acl + already */ int coda_cache_check(struct inode *inode, int mask) { - struct coda_inode_info *cnp = ITOC(inode); + struct coda_inode_info *cii = ITOC(inode); struct list_head *lh, *le; struct coda_cache *cc = NULL; - le = lh = &cnp->c_cnhead; + le = lh = &cii->c_cnhead; while( (le = le->next ) != lh ) { /* compare name and creds */ cc = list_entry(le, struct coda_cache, cc_cnlist); @@ -204,110 +230,70 @@ int coda_cache_check(struct inode *inode, int mask) } -/* DENTRY related stuff */ +/* DCACHE & ZAPPING related stuff */ -/* when the dentry count falls to 0 this is called. If Venus has - asked for it to be flushed, we take it out of the dentry hash - table with d_drop */ - -static void coda_flag_children(struct dentry *parent) +/* the following routines set flags in the inodes. They are + detected by: + - a dentry method: coda_dentry_revalidate (for lookups) + if the flag is C_PURGE + - an inode method coda_revalidate (for attributes) if the + flag is C_ATTR +*/ +static void coda_flag_children(struct dentry *parent, int flag) { struct list_head *child; - struct coda_inode_info *cnp; struct dentry *de; child = parent->d_subdirs.next; while ( child != &parent->d_subdirs ) { de = list_entry(child, struct dentry, d_child); - cnp = ITOC(de->d_inode); - if (cnp) - cnp->c_flags |= C_ZAPFID; - CDEBUG(D_CACHE, "ZAPFID for %s\n", coda_f2s(&cnp->c_fid)); - + coda_flag_inode(de->d_inode, flag); + CDEBUG(D_CACHE, "%d for %*s/%*s\n", flag, + de->d_name.len, de->d_name.name, + de->d_parent->d_name.len, de->d_parent->d_name.name); child = child->next; + if ( !de->d_inode ) + d_drop(de); } return; } -/* flag dentry and possibly children of a dentry with C_ZAPFID */ -void coda_dentry_delete(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct coda_inode_info *cnp = NULL; - ENTRY; - if (inode) { - cnp = ITOC(inode); - if ( cnp ) - CHECK_CNODE(cnp); - } else { - CDEBUG(D_CACHE, "No inode for dentry_delete!\n"); - return; - } - - - if ( !cnp ) { - printk("No cnode for dentry_delete!\n"); - return; - } - - if ( cnp->c_flags & (C_ZAPFID | C_ZAPDIR) ) - d_drop(dentry); - if ( (cnp->c_flags & C_ZAPDIR) && S_ISDIR(inode->i_mode) ) { - coda_flag_children(dentry); - } - return; -} - -static void coda_zap_cnode(struct coda_inode_info *cnp, int flags) +void coda_flag_alias_children(struct inode *inode, int flag) { - cnp->c_flags |= flags; - coda_cache_clear_cnp(cnp); + struct list_head *alias; + struct dentry *alias_de; + + if ( !inode ) + return; + alias = inode->i_dentry.next; + while ( alias != &inode->i_dentry ) { + alias_de = list_entry(alias, struct dentry, d_alias); + if ( !alias_de ) { + printk("Corrupt alias list for %*s\n", + alias_de->d_name.len, alias_de->d_name.name); + return; + } + coda_flag_children(alias_de, flag); + alias= alias->next; + } } - - -/* the dache will notice the flags and drop entries (possibly with - children) the moment they are no longer in use */ -void coda_zapfid(struct ViceFid *fid, struct super_block *sb, int flag) +void coda_flag_inode(struct inode *inode, int flag) { - struct inode *inode = NULL; - struct coda_inode_info *cnp; + struct coda_inode_info *cii; - ENTRY; - - if ( !sb ) { - printk("coda_zapfid: no sb!\n"); + if ( !inode ) { + CDEBUG(D_CACHE, " no inode!\n"); return; } + cii = ITOC(inode); + cii->c_flags |= flag; +} - if ( !fid ) { - printk("coda_zapfid: no fid!\n"); - return; - } - if ( coda_fid_is_volroot(fid) ) { - struct list_head *lh, *le; - struct coda_sb_info *sbi = coda_sbp(sb); - le = lh = &sbi->sbi_volroothead; - while ( (le = le->next) != lh ) { - cnp = list_entry(le, struct coda_inode_info, c_volrootlist); - if ( cnp->c_fid.Volume == fid->Volume) - coda_zap_cnode(cnp, flag); - } - return; - } - inode = coda_fid_to_inode(fid, sb); - if ( !inode ) { - CDEBUG(D_CACHE, "coda_zapfid: no inode!\n"); - return; - } - cnp = ITOC(inode); - coda_zap_cnode(cnp, flag); -} - int cfsnc_nc_info(char *buffer, char **start, off_t offset, int length, int dummy) |