*/
while ((adp->f.states & CStatd)
&& (dcp->dflags & DFFetching)
- && hsame(adp->f.m.DataVersion, dcp->f.versionNo)) {
+ && afs_IsDCacheFresh(dcp, adp)) {
afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING,
__FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, dcp,
ICL_TYPE_INT32, dcp->dflags);
ObtainReadLock(&dcp->lock);
}
if (!(adp->f.states & CStatd)
- || !hsame(adp->f.m.DataVersion, dcp->f.versionNo)) {
+ || !afs_IsDCacheFresh(dcp, adp)) {
ReleaseReadLock(&dcp->lock);
ReleaseReadLock(&adp->lock);
afs_PutDCache(dcp);
int dynrootRetry = 1;
struct afs_fakestat_state fakestate;
int tryEvalOnly = 0;
+
+ /* Don't allow ENOENT errors, except for a specific code path where
+ * 'enoent_prohibited' is cleared below. */
+ int enoent_prohibited = 1;
+
OSI_VC_CONVERT(adp);
AFS_STATCNT(afs_lookup);
if (!afs_InReadDir(adp)) {
while ((adp->f.states & CStatd)
&& (tdc->dflags & DFFetching)
- && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) {
+ && afs_IsDCacheFresh(tdc, adp)) {
ReleaseReadLock(&tdc->lock);
ReleaseReadLock(&adp->lock);
afs_osi_Sleep(&tdc->validPos);
ObtainReadLock(&tdc->lock);
}
if (!(adp->f.states & CStatd)
- || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) {
+ || !afs_IsDCacheFresh(tdc, adp)) {
ReleaseReadLock(&tdc->lock);
ReleaseReadLock(&adp->lock);
afs_PutDCache(tdc);
ICL_TYPE_INT32, code);
if (code) {
- if (code != ENOENT) {
- /*printf("LOOKUP dirLookupOff -> %d\n", code);*/
+ if (code == ENOENT) {
+ /* The target name really doesn't exist (according to
+ * afs_dir_LookupOffset, anyway). */
+ enoent_prohibited = 0;
}
goto done;
}
*/
*avcp = NULL;
}
+ if (code == ENOENT && enoent_prohibited) {
+ /*
+ * We got an ENOENT error, but we didn't get it while looking up the
+ * dir entry in the relevant dir blob. That means we likely hit some
+ * other internal error; don't allow us to return ENOENT in this case,
+ * since some platforms cache ENOENT errors, and the target path name
+ * may actually exist.
+ */
+ code = EIO;
+ }
afs_PutFakeStat(&fakestate);
afs_DestroyReq(treq);