From d19ccabc31636d5893ec175c96ed87f8ecdd8d5e Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Fri, 12 Sep 2025 13:31:45 -0300 Subject: smb: client: fix dentry revalidation of cached root Don't check root dir dentry in cifs_dentry_needs_reval() as its inode was created before the cfid, so the time check will fail and trigger an unnecessary revalidation. Also account for dir_cache_timeout in time comparison, because if we have a cached dir, we have a lease for it, and, thus, may assume its children are (still) valid. To confirm that, let the ac*max checks go through for granular results. Signed-off-by: Enzo Matsumiya --- fs/smb/client/inode.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 35c5557d5ea1..053cdcbc87ff 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -2694,10 +2694,25 @@ cifs_dentry_needs_reval(struct dentry *dentry) if (!lookupCacheEnabled) return true; - cfid = find_cached_dir(tcon->cfids, dentry->d_parent, CFID_LOOKUP_DENTRY); - if (cfid) { - close_cached_dir(cfid); - return false; + if (dentry != dentry->d_parent) { + cfid = find_cached_dir(tcon->cfids, dentry->d_parent, CFID_LOOKUP_DENTRY); + if (cfid) { + /* + * We hold a lease for the cached parent. + * So as long as this inode is within cache dir lifetime, we don't need to + * revalidate it. + */ + if (time_before(cifs_i->time, cfid->time - dir_cache_timeout * HZ)) { + close_cached_dir(cfid); + return true; + } + + /* + * From cached dir perspective, we're done -- attr caching (ac*max) may + * have different requirements, so let the checks go through. + */ + close_cached_dir(cfid); + } } /* -- cgit v1.2.3