patch-2.1.90 linux/fs/coda/cache.c
Next file: linux/fs/coda/cnode.c
Previous file: linux/fs/coda/Makefile
Back to the patch index
Back to the overall index
- Lines: 342
- Date:
Tue Mar 17 21:19:05 1998
- Orig file:
v2.1.89/linux/fs/coda/cache.c
- Orig date:
Tue Mar 10 10:03:33 1998
diff -u --recursive --new-file v2.1.89/linux/fs/coda/cache.c linux/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 @@
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 @@
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 @@
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 @@
}
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 @@
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_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 @@
}
}
+/* remove all acl caches */
void coda_cache_clear_all(struct super_block *sb)
{
struct list_head *lh, *le;
@@ -150,6 +167,9 @@
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 @@
}
}
+/* 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 @@
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 @@
}
}
}
-
+
+/* 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 @@
}
-/* 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;
- }
+void coda_flag_alias_children(struct inode *inode, int flag)
+{
+ struct list_head *alias;
+ struct dentry *alias_de;
- 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);
+ 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;
}
- return;
}
-static void coda_zap_cnode(struct coda_inode_info *cnp, int flags)
+void coda_flag_inode(struct inode *inode, int flag)
{
- cnp->c_flags |= flags;
- coda_cache_clear_cnp(cnp);
-}
+ struct coda_inode_info *cii;
-
-
-/* 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)
-{
- struct inode *inode = NULL;
- struct coda_inode_info *cnp;
-
- 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)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov