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

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