[OpenAFS-devel] funny lookup/dnlc/dcache/...
chas williams - CONTRACTOR
chas@cmf.nrl.navy.mil
Thu, 21 Apr 2005 21:59:54 -0400
In message <20050422013246.GA21341@tellurium.club.cc.cmu.edu>,"John S. Bucy" writes:
>Bingo ... Chaz' patch fixes it. On my stat microbenchmark, AFS now is
>just as fast as the local filesystem, as it should be since its all
>dentry cache hits.
it not really a fix but more of a reversion. at some point the
d_revalidate was rewritten. the original looked something like
the attached. afs_VerifyVCache() is used to check the status of the
vcache entry.
the current version of d_revalidate() seems to want to double check the
inode/vcache currently held by the dentry. this shouldnt be necessary?
if we have a dentry with a non-negative inode reference, it should
always point to a valid inode/vcache. at one point this might not
have been true due to trouble handling dentries in the afs code.
its been a while, since i looked at this so i could be completely
off the wall.
anyway, d_revalidate could probably be even simpler. just checking
Cstatd and calling vcache2inode() for the 'good' dentries should be
enough.
Index: src/afs/LINUX/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v
retrieving revision 1.100
diff -u -u -r1.100 osi_vnodeops.c
--- src/afs/LINUX/osi_vnodeops.c 18 Apr 2005 14:28:05 -0000 1.100
+++ src/afs/LINUX/osi_vnodeops.c 22 Apr 2005 01:43:47 -0000
@@ -865,16 +865,11 @@
afs_linux_dentry_revalidate(struct dentry *dp)
#endif
{
- char *name = NULL;
- cred_t *credp = crref();
+ cred_t *credp = NULL;
struct vrequest treq;
- struct vcache *lookupvcp = NULL;
- int code, bad_dentry = 1;
- struct sysname_info sysState;
+ int code, bad_dentry;
struct vcache *vcp, *parentvcp;
- sysState.allocked = 0;
-
#ifdef AFS_LINUX24_ENV
lock_kernel();
#endif
@@ -885,53 +880,37 @@
/* If it's a negative dentry, then there's nothing to do. */
if (!vcp || !parentvcp)
- goto done;
+ goto bad_dentry;
/* If it is the AFS root, then there's no chance it needs
* revalidating */
- if (vcp == afs_globalVp) {
- bad_dentry = 0;
- goto done;
- }
-
- if ((code = afs_InitReq(&treq, credp)))
- goto done;
-
- Check_AtSys(parentvcp, dp->d_name.name, &sysState, &treq);
- name = sysState.name;
-
- /* First try looking up the DNLC */
- if ((lookupvcp = osi_dnlc_lookup(parentvcp, name, WRITE_LOCK))) {
- /* Verify that the dentry does not point to an old inode */
- if (vcp != lookupvcp)
- goto done;
- /* Check and correct mvid */
- if (*name != '/' && vcp->mvstat == 2)
- check_bad_parent(dp);
+ if (vcp == afs_globalVp)
+ goto good_dentry;
+
+ /* check parentvcp->CStatd as well? */
+
+ /* Make this a fast path (no crref), since it's called so often. */
+ if (vcp->states & CStatd) {
+ if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
+ check_bad_parent(dp); /* check and correct mvid */
vcache2inode(vcp);
- bad_dentry = 0;
- goto done;
+ goto good_dentry;
}
- /* A DNLC lookup failure cannot be trusted. Try a real lookup.
- Make sure to try the real name and not the @sys expansion;
- afs_lookup will expand @sys itself. */
-
- code = afs_lookup(parentvcp, dp->d_name.name, &lookupvcp, credp);
-
- /* Verify that the dentry does not point to an old inode */
- if (vcp != lookupvcp)
- goto done;
+ credp = crref();
- bad_dentry = 0;
+ /* get a validated vcache entry */
+ code = afs_InitReq(&treq, credp);
+ if (code)
+ goto bad_dentry;
+ code = afs_VerifyVCache(vcp, &treq);
+ if (code)
+ goto bad_dentry;
- done:
- /* Clean up */
- if (lookupvcp)
- afs_PutVCache(lookupvcp);
- if (sysState.allocked)
- osi_FreeLargeSpace(name);
+ good_dentry:
+ bad_dentry = 0;
+ out:
AFS_GUNLOCK();
if (bad_dentry) {
@@ -942,9 +921,15 @@
#ifdef AFS_LINUX24_ENV
unlock_kernel();
#endif
- crfree(credp);
+
+ if (credp)
+ crfree(credp);
return !bad_dentry;
+
+ bad_dentry:
+ bad_dentry = 1;
+ goto out;
}
#if !defined(AFS_LINUX26_ENV)