From: Chas Williams Date: Mon, 25 Apr 2005 15:54:54 +0000 (+0000) Subject: linux-dentry-revalidate-one-more-20050424 X-Git-Tag: openafs-devel-1_5_0~603 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=7631e20aa097ff062cbd3b04f2d483e3e7a95707 linux-dentry-revalidate-one-more-20050424 further updates --- diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index fe98fb0..64b5131 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -27,7 +27,6 @@ RCSID #include "afs/sysincludes.h" #include "afsincludes.h" #include "afs/afs_stats.h" -#include "afs/afs_osidnlc.h" #include "h/mm.h" #ifdef HAVE_MM_INLINE_H #include "h/mm_inline.h" @@ -867,8 +866,7 @@ afs_linux_dentry_revalidate(struct dentry *dp) { cred_t *credp = NULL; struct vrequest treq; - struct vcache *lookupvcp = NULL; - int code, bad_dentry = 1; + int code, bad_dentry; struct vcache *vcp, *parentvcp; #ifdef AFS_LINUX24_ENV @@ -877,60 +875,57 @@ afs_linux_dentry_revalidate(struct dentry *dp) AFS_GLOCK(); vcp = ITOAFS(dp->d_inode); - parentvcp = ITOAFS(dp->d_parent->d_inode); + parentvcp = ITOAFS(dp->d_parent->d_inode); /* dget_parent()? */ - /* If it's a negative dentry, then there's nothing to do. */ - if (!vcp || !parentvcp) - goto done; - - /* If it is the AFS root, then there's no chance it needs - * revalidating */ - if (vcp == afs_globalVp) { - bad_dentry = 0; + /* If it's a negative dentry, it's never valid */ + if (!vcp || !parentvcp) { + bad_dentry = 1; goto done; } - /* 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; + /* If it's @sys, perhaps it has been changed */ + if (!afs_ENameOK(dp->d_name.name)) { + bad_dentry = 10; goto done; } - credp = crref(); + /* If it's the AFS root no chance it needs revalidating */ + if (vcp == afs_globalVp) + goto good_dentry; - /* get a validated vcache entry */ + /* Get a validated vcache entry */ + credp = crref(); code = afs_InitReq(&treq, credp); - if (code) + if (code) { + bad_dentry = 2; goto done; + } code = afs_VerifyVCache(vcp, &treq); - if (!code) { - bad_dentry = 0; + if (code) { + bad_dentry = 3; goto done; } - code = afs_lookup(parentvcp, dp->d_name.name, &lookupvcp, credp); + /* If we aren't the last looker, verify access */ + if (vcp->last_looker != treq.uid) { + if (!afs_AccessOK(vcp, (vType(vcp) == VREG) ? PRSFS_READ : PRSFS_LOOKUP, &treq, CHECK_MODE_BITS)) { + bad_dentry = 5; + goto done; + } - /* Verify that the dentry does not point to an old inode */ - if (vcp != lookupvcp) - goto done; + vcp->last_looker = treq.uid; + } + good_dentry: bad_dentry = 0; done: /* Clean up */ - if (lookupvcp) - afs_PutVCache(lookupvcp); - AFS_GUNLOCK(); - if (bad_dentry) { shrink_dcache_parent(dp); d_drop(dp); } - #ifdef AFS_LINUX24_ENV unlock_kernel(); #endif