LINUX: Restore negative dentry caching
authorAndrew Deason <adeason@sinenomine.net>
Mon, 25 Aug 2014 04:01:16 +0000 (23:01 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sun, 30 Aug 2015 16:34:48 +0000 (12:34 -0400)
One of the changes in commit 652f3bd9cb7a5d7833a760ba50ef7c2c67214bba
effectively disabled negative caching for dentries, by always
invalidating a negative dentry in afs_linux_dentry_revalidate. This
was because various temporary errors could result in ENOENT errors
being returned to afs_lookup, which created incorrect negative dentry
cache entries.

These incorrect ENOENT errors were rectified in change
Ib01e4309e44b532f843d53c8de2eae613e397bf6 . So, negative dentry cache
entries should work now, so remove the code to unconditionally
invalidate these negative entries.

Change-Id: Ic027147fd1f733beaa0fafbbabfa8c09f5656d34
Reviewed-on: http://gerrit.openafs.org/11789
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Daria Brashear <shadow@your-file-system.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/LINUX/osi_vnodeops.c

index 4c8ae35..36d00d4 100644 (file)
@@ -1299,23 +1299,21 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags)
        /* unlikely--the vcache entry hasn't changed */
 
        dput(parent);
+
     } else {
-#ifdef notyet
-       /* If this code is ever enabled, we should use dget_parent to handle
-        * getting the parent, and dput() to dispose of it. See above for an
-        * example ... */
-       pvcp = VTOAFS(dp->d_parent->d_inode);
-       if (hgetlo(pvcp->f.m.DataVersion) > dp->d_time)
-           goto bad_dentry;
-#endif
 
-       /* No change in parent's DataVersion so this negative
-        * lookup is still valid.  BUT, if a server is down a
-        * negative lookup can result so there should be a
-        * liftime as well.  For now, always expire.
-        */
+       /* 'dp' represents a cached negative lookup. */
+
+       parent = dget_parent(dp);
+       pvcp = VTOAFS(parent->d_inode);
+       parent_dv = parent_vcache_dv(parent->d_inode, credp);
+
+       if (parent_dv > dp->d_time || !(pvcp->f.states & CStatd)) {
+           dput(parent);
+           goto bad_dentry;
+       }
 
-       goto bad_dentry;
+       dput(parent);
     }
 
   good_dentry: