From 6d12ebeefea1f9d5a5242d0587c4895a2196583e Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 11 May 2026 11:50:37 -0700 Subject: [PATCH] fix(mount): fall through to filer when cached dir misses a tracked inode (#9436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lookupEntry returned ENOENT whenever the metaCache had the parent marked cached but the child entry was absent. That's only correct when the kernel has no record of the path either — when inodeToPath still maps it, the three layers disagree (#9139). Triggers in practice under bursts of concurrent metadata ops and after delete/rename events from another mount drop the local entry without clearing the inode mapping; the test flake fixed in b94ad8247 was the same shape on a smaller scale. Trust the filer in that case: fall through to the existing GetEntry path, which already loudly logs (Warningf with layer state) when the filer also returns ErrNotFound, and otherwise serves the live entry. Drop the Warningf from the cached-dir miss branch; it fires thousands of times under 16-task rclone imports while the real error path downstream covers the genuine-drift signal. --- weed/mount/weedfs.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/weed/mount/weedfs.go b/weed/mount/weedfs.go index 9b4953e48..6c50ac04a 100644 --- a/weed/mount/weedfs.go +++ b/weed/mount/weedfs.go @@ -583,16 +583,15 @@ func (wfs *WFS) lookupEntry(fullpath util.FullPath) (*filer.Entry, fuse.Status) // our IsDirectoryCached check and FindEntry (e.g. markDirectoryReadThrough). // If it's no longer cached, fall through to the filer lookup below. if wfs.metaCache.IsDirectoryCached(dirPath) { - // If the kernel is still tracking this path's inode, the entry - // was known to exist recently; a cached-dir miss here suggests - // metaCache/parent-cache coherence drift. Log visibly so the - // next occurrence shows up in mount.log without -v=4. - if _, inodeFound := wfs.inodeToPath.GetInode(fullpath); inodeFound { - glog.Warningf("lookupEntry: %s missing from cache while parent %s is cached; inode still tracked (possible coherence bug)", fullpath, dirPath) - } else { + // Authoritative ENOENT only if inodeToPath also has no record. + // If the kernel still tracks this inode, the three layers + // disagree; trust the filer over the local cache (the + // filer-ErrNotFound branch below logs the confirmed drift). + if _, inodeFound := wfs.inodeToPath.GetInode(fullpath); !inodeFound { glog.V(4).Infof("lookupEntry cache miss (dir cached) %s", fullpath) + return nil, fuse.ENOENT } - return nil, fuse.ENOENT + glog.V(2).Infof("lookupEntry: %s missing from cache while parent %s is cached; inode tracked, consulting filer", fullpath, dirPath) } }