summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnzo Matsumiya <ematsumiya@suse.de>2025-09-12 13:31:45 -0300
committerEnzo Matsumiya <ematsumiya@suse.de>2025-10-07 11:00:06 -0300
commit24f4274f02d11d9d0d5a2cba872acd46fa68dbaf (patch)
tree0303fc829299458eb3b88417a58c60075423e231
parent554df0fec90f4ad4ad48c0b42506ef570b763164 (diff)
downloadlinux-24f4274f02d11d9d0d5a2cba872acd46fa68dbaf.tar.gz
linux-24f4274f02d11d9d0d5a2cba872acd46fa68dbaf.tar.bz2
linux-24f4274f02d11d9d0d5a2cba872acd46fa68dbaf.zip
smb: client: skip 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 <ematsumiya@suse.de>
-rw-r--r--fs/smb/client/inode.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 4d7e7843e959..7a20070d3511 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -2703,12 +2703,28 @@ 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) {
- bool valid = time_after(cifs_i->time, cfid->ctime);
+ if (!IS_ROOT(dentry)) {
+ 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 child is within cached dir lifetime, we don't need to
+ * revalidate it.
+ *
+ * Since cfid expiration is based on access time, use it for comparison
+ * instead of creation time.
+ */
+ if (time_after(cifs_i->time, cfid->atime - dir_cache_timeout * HZ)) {
+ close_cached_dir(cfid);
+ return true;
+ }
- close_cached_dir(cfid);
- return !valid;
+ /*
+ * 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);
+ }
}
/*