diff options
| author | Enzo Matsumiya <ematsumiya@suse.de> | 2025-09-12 13:31:45 -0300 |
|---|---|---|
| committer | Enzo Matsumiya <ematsumiya@suse.de> | 2025-10-07 11:00:06 -0300 |
| commit | 24f4274f02d11d9d0d5a2cba872acd46fa68dbaf (patch) | |
| tree | 0303fc829299458eb3b88417a58c60075423e231 | |
| parent | 554df0fec90f4ad4ad48c0b42506ef570b763164 (diff) | |
| download | linux-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.c | 26 |
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); + } } /* |
