]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-d-revalidate-redux-20050508
authorChas Williams <chas@cmf.nrl.navy.mil>
Mon, 23 May 2005 22:09:45 +0000 (22:09 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 23 May 2005 22:09:45 +0000 (22:09 +0000)
FIXES 18588

when the callback for a directory is broken the children of this vnode
are not invalidated as well. so VerifyVCache() always believes these
vnodes to be up to date since they will still have the CStatd flag.

perhaps breaking the callback on a directory should also clear CStatd
on children vnodes?

this isnt a problem for other operating system which go through the
dnlc which does purge the children entries for the vnode in question
during ClearCallBack().

since d_revalidate now avoids the dnlc (and afs_lookup) the following
patch tracks the parent vnode's DataVersion (just the lower half really
but this should be sufficient) in d_time. if the parent has changed
then the dentry is flagged as neededing updated.

(cherry picked from commit f6883dfbbcbe14f65c2b9e44f2841392050e755f)

src/afs/LINUX/osi_vnodeops.c

index 64b5131cc825d2ef5457d7d8680f0cfd0ab0ab10..762e3f987b121714297e663d382821ddcd18b7c7 100644 (file)
@@ -867,7 +867,7 @@ afs_linux_dentry_revalidate(struct dentry *dp)
     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_linux_dentry_revalidate(struct dentry *dp)
     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 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
 #endif
 
        dp->d_op = &afs_dentry_operations;
+       dp->d_time = hgetlo(ITOAFS(dip)->m.DataVersion);
        d_instantiate(dp, ip);
     }
 
@@ -1095,6 +1102,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
 #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_linux_unlink(struct inode *dip, struct dentry *dp)
        }
        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 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
        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));
     }