[OpenAFS] Callback/Cache Issues with 1.3.82 on FC3

chas williams - CONTRACTOR chas@cmf.nrl.navy.mil
Thu, 05 May 2005 10:10:46 -0400


ok, try this fix -- apply to 1.3.82 sources.  when you delete the file
from the other client, the callbacks for that directory are broken.
when afs breaks the callback for a directory, it doesnt update the
state any of the children of that directory.  so the dentry on the local
machine still believes its valid since the deleted vnode still has state
CStatd on the local machine.

for a quick fix, the parent's lower 32 bits of the DataVersion are stored
in d_time.  if the parent's version number has changed, this dentry
needs revalidated.

should ClearCallBack() also clear vnodes with a matching parentVnode?

--- src/afs/LINUX/osi_vnodeops.c.orig	2005-04-25 10:55:47.000000000 -0400
+++ src/afs/LINUX/osi_vnodeops.c	2005-05-05 09:28:26.000000000 -0400
@@ -867,7 +867,7 @@
     cred_t *credp = NULL;
     struct vrequest treq;
     int code, bad_dentry;
-    struct vcache *vcp, *parentvcp;
+    struct vcache *vcp, *pvcp;
 
 #ifdef AFS_LINUX24_ENV
     lock_kernel();
@@ -875,14 +875,20 @@
     AFS_GLOCK();
 
     vcp = ITOAFS(dp->d_inode);
-    parentvcp = ITOAFS(dp->d_parent->d_inode);		/* dget_parent()? */
+    pvcp = ITOAFS(dp->d_parent->d_inode);		/* dget_parent()? */
 
     /* If it's a negative dentry, it's never valid */
-    if (!vcp || !parentvcp) {
+    if (!vcp || !pvcp) {
 	bad_dentry = 1;
 	goto done;
     }
 
+    /* parent's DataVersion changed? */
+    if (hgetlo(pvcp->m.DataVersion) > dp->d_time) {
+	bad_dentry = 11;
+	goto done;
+    }
+
     /* If it's @sys, perhaps it has been changed */
     if (!afs_ENameOK(dp->d_name.name)) {
 	bad_dentry = 10;
@@ -1024,6 +1030,7 @@
 #endif
 
 	dp->d_op = &afs_dentry_operations;
+	dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
 	d_instantiate(dp, ip);
     }
 
@@ -1095,6 +1102,7 @@
 #endif
     }
     dp->d_op = &afs_dentry_operations;
+    dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
     d_add(dp, AFSTOI(vcp));
 
 #if defined(AFS_LINUX26_ENV)
@@ -1185,8 +1193,10 @@
 	}
 	AFS_GUNLOCK();
 
-	if (!code)
+	if (!code) {
+	    __dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
 	    d_move(dp, __dp);
+	}
 	dput(__dp);
 
 	goto out;
@@ -1252,6 +1262,7 @@
 	tvcp->v.v_fop = &afs_dir_fops;
 #endif
 	dp->d_op = &afs_dentry_operations;
+	dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
 	d_instantiate(dp, AFSTOI(tvcp));
     }