* [SMB CLIENT][PATCHES] directory lease debugging and configuration
@ 2025-09-30 4:30 Steve French
2025-09-30 13:11 ` Enzo Matsumiya
0 siblings, 1 reply; 4+ messages in thread
From: Steve French @ 2025-09-30 4:30 UTC (permalink / raw)
To: CIFS; +Cc: Bharath S M, samba-technical
[-- Attachment #1: Type: text/plain, Size: 2664 bytes --]
4 patches from Bharath to improve directory lease handling (see
attached). Lightly updated and rebased on current mainline, and
merged into cifs-2.6.git for-next. Feedback/review/comments welcome
commit a50843f864205ea4576638cb32321313d9c06e54
Author: Bharath SM <bharathsm@microsoft.com>
Date: Tue Sep 2 14:18:21 2025 +0530
smb: client: cap smb directory cache memory via module parameter
The CIFS directory entry cache could grow without a global
bound across mounts. Add a module-wide cap to limit memory
used by cached dirents and avoid unbounded growth.
Introduce a new module parameter, dir_cache_max_memory_kb
(KB units; 0 = unlimited). When unset and directory caching
is enabled (dir_cache_timeout != 0), default the cap to ~10%
of system RAM during module init. The parameter is exposed
under: /sys/module/cifs/parameters/dir_cache_max_memory_kb.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
commit 8e2727c9292125b6373b2a1edf1da59510081251
Author: Bharath SM <bharathsm@microsoft.com>
Date: Mon Sep 29 15:57:46 2025 -0500
smb: client: account smb directory cache usage and per-tcon totals
Add lightweight accounting for directory lease cache usage
to aid debugging and limiting cache size in future. Track
per-directory entry/byte counts and maintain per-tcon
aggregates. Also expose the totals in /proc/fs/cifs/open_dirs.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
commit 645b07fa68f5f001ad7a457166eac31832f1290b
Author: Bharath SM <bharathsm@microsoft.com>
Date: Tue Sep 2 16:46:03 2025 +0530
smb: client: show lease state as R/H/W (or NONE) in open_files
Print the lease/oplock caching state for each open file as a
compact string of letters: R (read), H (handle), W (write).
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
commit cfcf4725d2f7251232304e4780929a47e1bb3931
Author: Bharath SM <bharathsm@microsoft.com>
Date: Tue Sep 2 01:16:00 2025 +0530
smb: client: add drop_dir_cache module parameter to invalidate
cached dirents
Add write-only /sys/module/cifs/parameters/drop_dir_cache. Writing a
non-zero value iterates all tcons and calls invalidate_all_cached_dirs()
to drop cached directory entries. This is useful to force a dirent cache
drop across mounts for debugging and testing purpose.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
--
Thanks,
Steve
[-- Attachment #2: 0004-smb-client-add-drop_dir_cache-module-parameter-to-in.patch --]
[-- Type: text/x-patch, Size: 2366 bytes --]
From cfcf4725d2f7251232304e4780929a47e1bb3931 Mon Sep 17 00:00:00 2001
From: Bharath SM <bharathsm@microsoft.com>
Date: Tue, 2 Sep 2025 01:16:00 +0530
Subject: [PATCH 04/16] smb: client: add drop_dir_cache module parameter to
invalidate cached dirents
Add write-only /sys/module/cifs/parameters/drop_dir_cache. Writing a
non-zero value iterates all tcons and calls invalidate_all_cached_dirs()
to drop cached directory entries. This is useful to force a dirent cache
drop across mounts for debugging and testing purpose.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/client/cifsfs.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index dcb39d1b5958..9a83f528d39d 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -121,6 +121,44 @@ unsigned int dir_cache_timeout = 30;
module_param(dir_cache_timeout, uint, 0644);
MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 "
"Range: 1 to 65000 seconds, 0 to disable caching dir contents");
+
+/*
+ * Write-only module parameter to drop all cached directory entries across
+ * all CIFS mounts. Echo a non-zero value to trigger.
+ */
+static void cifs_drop_all_dir_caches(void)
+{
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ if (cifs_ses_exiting(ses))
+ continue;
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list)
+ invalidate_all_cached_dirs(tcon);
+ }
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+}
+
+static int cifs_param_set_drop_dir_cache(const char *val, const struct kernel_param *kp)
+{
+ bool bv;
+ int rc = kstrtobool(val, &bv);
+
+ if (rc)
+ return rc;
+ if (bv)
+ cifs_drop_all_dir_caches();
+ return 0;
+}
+
+module_param_call(drop_dir_cache, cifs_param_set_drop_dir_cache, NULL, NULL, 0200);
+MODULE_PARM_DESC(drop_dir_cache, "Write 1 to drop all cached directory entries across all CIFS mounts");
+
#ifdef CONFIG_CIFS_STATS2
unsigned int slow_rsp_threshold = 1;
module_param(slow_rsp_threshold, uint, 0644);
--
2.48.1
[-- Attachment #3: 0006-smb-client-account-smb-directory-cache-usage-and-per.patch --]
[-- Type: text/x-patch, Size: 7568 bytes --]
From 8e2727c9292125b6373b2a1edf1da59510081251 Mon Sep 17 00:00:00 2001
From: Bharath SM <bharathsm@microsoft.com>
Date: Mon, 29 Sep 2025 15:57:46 -0500
Subject: [PATCH 06/16] smb: client: account smb directory cache usage and
per-tcon totals
Add lightweight accounting for directory lease cache usage
to aid debugging and limiting cache size in future. Track
per-directory entry/byte counts and maintain per-tcon
aggregates. Also expose the totals in /proc/fs/cifs/open_dirs.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/client/cached_dir.c | 18 +++++++++++++++++
fs/smb/client/cached_dir.h | 9 +++++++++
fs/smb/client/cifs_debug.c | 8 +++++++-
fs/smb/client/cifsfs.c | 2 ++
fs/smb/client/readdir.c | 40 +++++++++++++++++++++++++-------------
5 files changed, 63 insertions(+), 14 deletions(-)
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index b69daeb1301b..b6f538a1d5af 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -697,6 +697,21 @@ static void free_cached_dir(struct cached_fid *cfid)
kfree(dirent);
}
+ /* adjust tcon-level counters and reset per-dir accounting */
+ if (cfid->cfids) {
+ if (cfid->dirents.entries_count)
+ atomic_long_sub((long)cfid->dirents.entries_count,
+ &cfid->cfids->total_dirents_entries);
+ if (cfid->dirents.bytes_used) {
+ atomic64_sub((long long)cfid->dirents.bytes_used,
+ &cfid->cfids->total_dirents_bytes);
+ atomic64_sub((long long)cfid->dirents.bytes_used,
+ &cifs_dircache_bytes_used);
+ }
+ }
+ cfid->dirents.entries_count = 0;
+ cfid->dirents.bytes_used = 0;
+
kfree(cfid->path);
cfid->path = NULL;
kfree(cfid);
@@ -792,6 +807,9 @@ struct cached_fids *init_cached_dirs(void)
queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
dir_cache_timeout * HZ);
+ atomic_long_set(&cfids->total_dirents_entries, 0);
+ atomic64_set(&cfids->total_dirents_bytes, 0);
+
return cfids;
}
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index 46b5a2fdf15b..c98f02943311 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -27,6 +27,9 @@ struct cached_dirents {
struct mutex de_mutex;
loff_t pos; /* Expected ctx->pos */
struct list_head entries;
+ /* accounting for cached entries in this directory */
+ unsigned long entries_count;
+ unsigned long bytes_used;
};
struct cached_fid {
@@ -62,8 +65,14 @@ struct cached_fids {
struct list_head dying;
struct work_struct invalidation_work;
struct delayed_work laundromat_work;
+ /* aggregate accounting for all cached dirents under this tcon */
+ atomic_long_t total_dirents_entries;
+ atomic64_t total_dirents_bytes;
};
+/* Module-wide directory cache accounting (defined in cifsfs.c) */
+extern atomic64_t cifs_dircache_bytes_used; /* bytes across all mounts */
+
extern struct cached_fids *init_cached_dirs(void);
extern void free_cached_dirs(struct cached_fids *cfids);
extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 75f5f60f0bb8..1fb71d2d31b5 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -331,7 +331,10 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v)
if (!cfids)
continue;
spin_lock(&cfids->cfid_list_lock); /* check lock ordering */
- seq_printf(m, "Num entries: %d\n", cfids->num_entries);
+ seq_printf(m, "Num entries: %d, cached_dirents: %lu entries, %llu bytes\n",
+ cfids->num_entries,
+ (unsigned long)atomic_long_read(&cfids->total_dirents_entries),
+ (unsigned long long)atomic64_read(&cfids->total_dirents_bytes));
list_for_each_entry(cfid, &cfids->entries, entry) {
seq_printf(m, "0x%x 0x%llx 0x%llx %s",
tcon->tid,
@@ -342,6 +345,9 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v)
seq_printf(m, "\tvalid file info");
if (cfid->dirents.is_valid)
seq_printf(m, ", valid dirents");
+ if (!list_empty(&cfid->dirents.entries))
+ seq_printf(m, ", dirents: %lu entries, %lu bytes",
+ cfid->dirents.entries_count, cfid->dirents.bytes_used);
seq_printf(m, "\n");
}
spin_unlock(&cfids->cfid_list_lock);
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 9a83f528d39d..1775c2b7528f 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -121,6 +121,8 @@ unsigned int dir_cache_timeout = 30;
module_param(dir_cache_timeout, uint, 0644);
MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 "
"Range: 1 to 65000 seconds, 0 to disable caching dir contents");
+/* Module-wide total cached dirents (in bytes) across all tcons */
+atomic64_t cifs_dircache_bytes_used = ATOMIC64_INIT(0);
/*
* Write-only module parameter to drop all cached directory entries across
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index 4e5460206397..f0ce26622a14 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -874,39 +874,42 @@ static void finished_cached_dirents_count(struct cached_dirents *cde,
cde->is_valid = 1;
}
-static void add_cached_dirent(struct cached_dirents *cde,
- struct dir_context *ctx,
- const char *name, int namelen,
- struct cifs_fattr *fattr,
- struct file *file)
+static bool add_cached_dirent(struct cached_dirents *cde,
+ struct dir_context *ctx, const char *name,
+ int namelen, struct cifs_fattr *fattr,
+ struct file *file)
{
struct cached_dirent *de;
if (cde->file != file)
- return;
+ return false;
if (cde->is_valid || cde->is_failed)
- return;
+ return false;
if (ctx->pos != cde->pos) {
cde->is_failed = 1;
- return;
+ return false;
}
de = kzalloc(sizeof(*de), GFP_ATOMIC);
if (de == NULL) {
cde->is_failed = 1;
- return;
+ return false;
}
de->namelen = namelen;
de->name = kstrndup(name, namelen, GFP_ATOMIC);
if (de->name == NULL) {
kfree(de);
cde->is_failed = 1;
- return;
+ return false;
}
de->pos = ctx->pos;
memcpy(&de->fattr, fattr, sizeof(struct cifs_fattr));
list_add_tail(&de->entry, &cde->entries);
+ /* update accounting */
+ cde->entries_count++;
+ cde->bytes_used += sizeof(*de) + (size_t)namelen + 1;
+ return true;
}
static bool cifs_dir_emit(struct dir_context *ctx,
@@ -915,7 +918,8 @@ static bool cifs_dir_emit(struct dir_context *ctx,
struct cached_fid *cfid,
struct file *file)
{
- bool rc;
+ size_t delta_bytes = 0;
+ bool rc, added = false;
ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
rc = dir_emit(ctx, name, namelen, ino, fattr->cf_dtype);
@@ -923,10 +927,20 @@ static bool cifs_dir_emit(struct dir_context *ctx,
return rc;
if (cfid) {
+ /* Cost of this entry */
+ delta_bytes = sizeof(struct cached_dirent) + (size_t)namelen + 1;
+
mutex_lock(&cfid->dirents.de_mutex);
- add_cached_dirent(&cfid->dirents, ctx, name, namelen,
- fattr, file);
+ added = add_cached_dirent(&cfid->dirents, ctx, name, namelen,
+ fattr, file);
mutex_unlock(&cfid->dirents.de_mutex);
+
+ if (added) {
+ /* per-tcon then global for consistency with free path */
+ atomic64_add((long long)delta_bytes, &cfid->cfids->total_dirents_bytes);
+ atomic_long_inc(&cfid->cfids->total_dirents_entries);
+ atomic64_add((long long)delta_bytes, &cifs_dircache_bytes_used);
+ }
}
return rc;
--
2.48.1
[-- Attachment #4: 0005-smb-client-show-lease-state-as-R-H-W-or-NONE-in-open.patch --]
[-- Type: text/x-patch, Size: 2433 bytes --]
From 645b07fa68f5f001ad7a457166eac31832f1290b Mon Sep 17 00:00:00 2001
From: Bharath SM <bharathsm@microsoft.com>
Date: Tue, 2 Sep 2025 16:46:03 +0530
Subject: [PATCH 05/16] smb: client: show lease state as R/H/W (or NONE) in
open_files
Print the lease/oplock caching state for each open file as a
compact string of letters: R (read), H (handle), W (write).
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/client/cifs_debug.c | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 35c4d27d2cc0..75f5f60f0bb8 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -240,14 +240,18 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
struct cifs_ses *ses;
struct cifs_tcon *tcon;
struct cifsFileInfo *cfile;
+ struct inode *inode;
+ struct cifsInodeInfo *cinode;
+ char lease[4];
+ int n;
seq_puts(m, "# Version:1\n");
seq_puts(m, "# Format:\n");
seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
#ifdef CONFIG_CIFS_DEBUG2
- seq_printf(m, " <filename> <mid>\n");
+ seq_puts(m, " <filename> <lease> <mid>\n");
#else
- seq_printf(m, " <filename>\n");
+ seq_puts(m, " <filename> <lease>\n");
#endif /* CIFS_DEBUG2 */
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
@@ -267,11 +271,30 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
cfile->pid,
from_kuid(&init_user_ns, cfile->uid),
cfile->dentry);
+
+ /* Append lease/oplock caching state as RHW letters */
+ inode = d_inode(cfile->dentry);
+ n = 0;
+ if (inode) {
+ cinode = CIFS_I(inode);
+ if (CIFS_CACHE_READ(cinode))
+ lease[n++] = 'R';
+ if (CIFS_CACHE_HANDLE(cinode))
+ lease[n++] = 'H';
+ if (CIFS_CACHE_WRITE(cinode))
+ lease[n++] = 'W';
+ }
+ lease[n] = '\0';
+ seq_puts(m, " ");
+ if (n)
+ seq_printf(m, "%s", lease);
+ else
+ seq_puts(m, "NONE");
+
#ifdef CONFIG_CIFS_DEBUG2
- seq_printf(m, " %llu\n", cfile->fid.mid);
-#else
+ seq_printf(m, " %llu", cfile->fid.mid);
+#endif /* CONFIG_CIFS_DEBUG2 */
seq_printf(m, "\n");
-#endif /* CIFS_DEBUG2 */
}
spin_unlock(&tcon->open_file_lock);
}
--
2.48.1
[-- Attachment #5: 0007-smb-client-cap-smb-directory-cache-memory-via-module.patch --]
[-- Type: text/x-patch, Size: 4912 bytes --]
From a50843f864205ea4576638cb32321313d9c06e54 Mon Sep 17 00:00:00 2001
From: Bharath SM <bharathsm@microsoft.com>
Date: Tue, 2 Sep 2025 14:18:21 +0530
Subject: [PATCH 07/16] smb: client: cap smb directory cache memory via module
parameter
The CIFS directory entry cache could grow without a global
bound across mounts. Add a module-wide cap to limit memory
used by cached dirents and avoid unbounded growth.
Introduce a new module parameter, dir_cache_max_memory_kb
(KB units; 0 = unlimited). When unset and directory caching
is enabled (dir_cache_timeout != 0), default the cap to ~10%
of system RAM during module init. The parameter is exposed
under: /sys/module/cifs/parameters/dir_cache_max_memory_kb.
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
fs/smb/client/cached_dir.h | 1 +
fs/smb/client/cifsfs.c | 15 +++++++++++++++
fs/smb/client/readdir.c | 25 ++++++++++++++++++++-----
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index c98f02943311..ed58b41bf0df 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -72,6 +72,7 @@ struct cached_fids {
/* Module-wide directory cache accounting (defined in cifsfs.c) */
extern atomic64_t cifs_dircache_bytes_used; /* bytes across all mounts */
+extern unsigned long dir_cache_max_memory_kb; /* cap in KB; 0 = unlimited */
extern struct cached_fids *init_cached_dirs(void);
extern void free_cached_dirs(struct cached_fids *cfids);
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 1775c2b7528f..b54740d806e9 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -121,6 +121,10 @@ unsigned int dir_cache_timeout = 30;
module_param(dir_cache_timeout, uint, 0644);
MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 "
"Range: 1 to 65000 seconds, 0 to disable caching dir contents");
+/* Directory cache memory cap in KB (0 = unlimited). Defaults to ~10% of RAM. */
+unsigned long dir_cache_max_memory_kb;
+module_param(dir_cache_max_memory_kb, ulong, 0644);
+MODULE_PARM_DESC(dir_cache_max_memory_kb, "Module-wide memory cap for cached directory entries in KB (0 = unlimited). Default: ~10% of RAM");
/* Module-wide total cached dirents (in bytes) across all tcons */
atomic64_t cifs_dircache_bytes_used = ATOMIC64_INIT(0);
@@ -1935,6 +1939,17 @@ init_cifs(void)
cifs_dbg(VFS, "dir_cache_timeout set to max of 65000 seconds\n");
}
+ /* Set a default cap of ~10% of RAM if not specified (and caching isn't disabled) */
+ if (dir_cache_timeout != 0 && dir_cache_max_memory_kb == 0) {
+ u64 total_bytes;
+ unsigned long default_kb;
+
+ total_bytes = (u64)totalram_pages() << PAGE_SHIFT;
+ /* ~10% of RAM in KB */
+ default_kb = (unsigned long)((total_bytes / 10) >> 10);
+ dir_cache_max_memory_kb = default_kb;
+ }
+
cifsiod_wq = alloc_workqueue("cifsiod",
WQ_FREEZABLE | WQ_MEM_RECLAIM | WQ_PERCPU,
0);
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index f0ce26622a14..f75e157835b7 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -875,12 +875,16 @@ static void finished_cached_dirents_count(struct cached_dirents *cde,
}
static bool add_cached_dirent(struct cached_dirents *cde,
- struct dir_context *ctx, const char *name,
- int namelen, struct cifs_fattr *fattr,
- struct file *file)
+ struct dir_context *ctx, const char *name,
+ int namelen, struct cifs_fattr *fattr,
+ struct file *file, bool can_cache)
{
struct cached_dirent *de;
-
+ /* If we can't cache due to memory cap, mark cache as failed */
+ if (!can_cache) {
+ cde->is_failed = 1;
+ return false;
+ }
if (cde->file != file)
return false;
if (cde->is_valid || cde->is_failed)
@@ -921,6 +925,9 @@ static bool cifs_dir_emit(struct dir_context *ctx,
size_t delta_bytes = 0;
bool rc, added = false;
ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
+ u64 cap_bytes = 0;
+ u64 used_bytes = 0;
+ bool can_cache = true;
rc = dir_emit(ctx, name, namelen, ino, fattr->cf_dtype);
if (!rc)
@@ -930,9 +937,17 @@ static bool cifs_dir_emit(struct dir_context *ctx,
/* Cost of this entry */
delta_bytes = sizeof(struct cached_dirent) + (size_t)namelen + 1;
+ /* Enforce module-wide memory cap if enabled */
+ if (dir_cache_max_memory_kb) {
+ cap_bytes = (u64)dir_cache_max_memory_kb << 10;
+ used_bytes = (u64)atomic64_read(&cifs_dircache_bytes_used);
+ if (used_bytes + (u64)delta_bytes > cap_bytes)
+ can_cache = false;
+ }
+
mutex_lock(&cfid->dirents.de_mutex);
added = add_cached_dirent(&cfid->dirents, ctx, name, namelen,
- fattr, file);
+ fattr, file, can_cache);
mutex_unlock(&cfid->dirents.de_mutex);
if (added) {
--
2.48.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [SMB CLIENT][PATCHES] directory lease debugging and configuration
2025-09-30 4:30 [SMB CLIENT][PATCHES] directory lease debugging and configuration Steve French
@ 2025-09-30 13:11 ` Enzo Matsumiya
2025-09-30 13:13 ` Enzo Matsumiya
2025-10-24 9:13 ` Bharath SM
0 siblings, 2 replies; 4+ messages in thread
From: Enzo Matsumiya @ 2025-09-30 13:11 UTC (permalink / raw)
To: Steve French; +Cc: CIFS, Bharath S M, samba-technical
Hi Steve, Bharath,
Sending my review based on the commit messages and the patches applied
manually on my local tree.
Please try sending the patches with git-send-email next time, as it's
much easier to apply and review. Thanks!
On 09/29, Steve French via samba-technical wrote:
>4 patches from Bharath to improve directory lease handling (see
>attached). Lightly updated and rebased on current mainline, and
>merged into cifs-2.6.git for-next. Feedback/review/comments welcome
>
>commit a50843f864205ea4576638cb32321313d9c06e54
>Author: Bharath SM <bharathsm@microsoft.com>
>Date: Tue Sep 2 14:18:21 2025 +0530
>
> smb: client: cap smb directory cache memory via module parameter
>
> The CIFS directory entry cache could grow without a global
> bound across mounts. Add a module-wide cap to limit memory
> used by cached dirents and avoid unbounded growth.
>
> Introduce a new module parameter, dir_cache_max_memory_kb
> (KB units; 0 = unlimited). When unset and directory caching
"0 = unlimited" should be "0 = ~10% of RAM"
> is enabled (dir_cache_timeout != 0), default the cap to ~10%
> of system RAM during module init. The parameter is exposed
> under: /sys/module/cifs/parameters/dir_cache_max_memory_kb.
>
> Signed-off-by: Bharath SM <bharathsm@microsoft.com>
> Signed-off-by: Steve French <stfrench@microsoft.com>
I think this should be a sysfs module parameter, as it assumes users
knows how much memory they'll need beforehand:
- one can't say how many entries are in the shares, or how many shares
will be mounted
- if they do, they need to calculate (nentries * (sizeof(struct
cached_dirents) + namelen (of each entry) + 1)), + round up(1024),
then finally divide by 1024, meaning they'll fallback to using the
default value
On the default value, I think 10% of RAM is too much for cifs cached
entries.
The max memory value should be module-wide, yes, but equally divided for
each tcon, because I might have an initial not-so-important share that
ends up filling the whole cache, then a more important/accessed one that
will not have the chance to cache entries.
>commit 8e2727c9292125b6373b2a1edf1da59510081251
>Author: Bharath SM <bharathsm@microsoft.com>
>Date: Mon Sep 29 15:57:46 2025 -0500
>
> smb: client: account smb directory cache usage and per-tcon totals
>
> Add lightweight accounting for directory lease cache usage
> to aid debugging and limiting cache size in future. Track
> per-directory entry/byte counts and maintain per-tcon
> aggregates. Also expose the totals in /proc/fs/cifs/open_dirs.
>
> Signed-off-by: Bharath SM <bharathsm@microsoft.com>
> Signed-off-by: Steve French <stfrench@microsoft.com>
Since per-tcon usage is the only value accounted for max memory limits,
per-cfid accounting should be wrapped in ifdef CONFIG_CIFS_DEBUG2.
You can decrement the entry/bytes_used in the loop when freeing each
cached_dirent.
>commit 645b07fa68f5f001ad7a457166eac31832f1290b
>Author: Bharath SM <bharathsm@microsoft.com>
>Date: Tue Sep 2 16:46:03 2025 +0530
>
> smb: client: show lease state as R/H/W (or NONE) in open_files
>
> Print the lease/oplock caching state for each open file as a
> compact string of letters: R (read), H (handle), W (write).
>
> Signed-off-by: Bharath SM <bharathsm@microsoft.com>
> Signed-off-by: Steve French <stfrench@microsoft.com>
>
>commit cfcf4725d2f7251232304e4780929a47e1bb3931
>Author: Bharath SM <bharathsm@microsoft.com>
>Date: Tue Sep 2 01:16:00 2025 +0530
>
> smb: client: add drop_dir_cache module parameter to invalidate
>cached dirents
>
> Add write-only /sys/module/cifs/parameters/drop_dir_cache. Writing a
> non-zero value iterates all tcons and calls invalidate_all_cached_dirs()
> to drop cached directory entries. This is useful to force a dirent cache
> drop across mounts for debugging and testing purpose.
>
> Signed-off-by: Bharath SM <bharathsm@microsoft.com>
> Signed-off-by: Steve French <stfrench@microsoft.com>
If it's for debugging and testing purposes, it should be wrapped in
ifdef CONFIG_CIFS_DEBUG2 too.
Also, cached dirs is racy by design (as it should), but in its current
state, I don't think it's a good idea to add another source of async
invalidation.
Cheers,
Enzo
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [SMB CLIENT][PATCHES] directory lease debugging and configuration
2025-09-30 13:11 ` Enzo Matsumiya
@ 2025-09-30 13:13 ` Enzo Matsumiya
2025-10-24 9:13 ` Bharath SM
1 sibling, 0 replies; 4+ messages in thread
From: Enzo Matsumiya @ 2025-09-30 13:13 UTC (permalink / raw)
To: Steve French; +Cc: CIFS, Bharath S M, samba-technical
On 09/30, Enzo Matsumiya wrote:
>Hi Steve, Bharath,
>
>Sending my review based on the commit messages and the patches applied
>manually on my local tree.
>
>Please try sending the patches with git-send-email next time, as it's
>much easier to apply and review. Thanks!
>
>On 09/29, Steve French via samba-technical wrote:
>>4 patches from Bharath to improve directory lease handling (see
>>attached). Lightly updated and rebased on current mainline, and
>>merged into cifs-2.6.git for-next. Feedback/review/comments welcome
>>
>>commit a50843f864205ea4576638cb32321313d9c06e54
>>Author: Bharath SM <bharathsm@microsoft.com>
>>Date: Tue Sep 2 14:18:21 2025 +0530
>>
>> smb: client: cap smb directory cache memory via module parameter
>>
>> The CIFS directory entry cache could grow without a global
>> bound across mounts. Add a module-wide cap to limit memory
>> used by cached dirents and avoid unbounded growth.
>>
>> Introduce a new module parameter, dir_cache_max_memory_kb
>> (KB units; 0 = unlimited). When unset and directory caching
>
>"0 = unlimited" should be "0 = ~10% of RAM"
>
>> is enabled (dir_cache_timeout != 0), default the cap to ~10%
>> of system RAM during module init. The parameter is exposed
>> under: /sys/module/cifs/parameters/dir_cache_max_memory_kb.
>>
>> Signed-off-by: Bharath SM <bharathsm@microsoft.com>
>> Signed-off-by: Steve French <stfrench@microsoft.com>
>
>I think this should be a sysfs module parameter, as it assumes users
shouldn't *
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [SMB CLIENT][PATCHES] directory lease debugging and configuration
2025-09-30 13:11 ` Enzo Matsumiya
2025-09-30 13:13 ` Enzo Matsumiya
@ 2025-10-24 9:13 ` Bharath SM
1 sibling, 0 replies; 4+ messages in thread
From: Bharath SM @ 2025-10-24 9:13 UTC (permalink / raw)
To: Enzo Matsumiya; +Cc: Steve French, CIFS, Bharath S M, samba-technical
Thanks for your comments. Apologies for getting back late on this.
On Tue, Sep 30, 2025 at 6:11 AM Enzo Matsumiya <ematsumiya@suse.de> wrote:
>
> Hi Steve, Bharath,
>
> Sending my review based on the commit messages and the patches applied
> manually on my local tree.
>
> Please try sending the patches with git-send-email next time, as it's
> much easier to apply and review. Thanks!
Ack.
>
> On 09/29, Steve French via samba-technical wrote:
> >4 patches from Bharath to improve directory lease handling (see
> >attached). Lightly updated and rebased on current mainline, and
> >merged into cifs-2.6.git for-next. Feedback/review/comments welcome
> >
> >commit a50843f864205ea4576638cb32321313d9c06e54
> >Author: Bharath SM <bharathsm@microsoft.com>
> >Date: Tue Sep 2 14:18:21 2025 +0530
> >
> > smb: client: cap smb directory cache memory via module parameter
> >
> > The CIFS directory entry cache could grow without a global
> > bound across mounts. Add a module-wide cap to limit memory
> > used by cached dirents and avoid unbounded growth.
> >
> > Introduce a new module parameter, dir_cache_max_memory_kb
> > (KB units; 0 = unlimited). When unset and directory caching
>
> "0 = unlimited" should be "0 = ~10% of RAM"
If the user wants behavior like today, then can explicitly write '0'
to make it unlimited.
Otherwise by default 10%of RAM.
>
> > is enabled (dir_cache_timeout != 0), default the cap to ~10%
> > of system RAM during module init. The parameter is exposed
> > under: /sys/module/cifs/parameters/dir_cache_max_memory_kb.
> >
> > Signed-off-by: Bharath SM <bharathsm@microsoft.com>
> > Signed-off-by: Steve French <stfrench@microsoft.com>
>
> I think this should be a sysfs module parameter, as it assumes users
> knows how much memory they'll need beforehand:
Ack. We can keep it in procfs.
> - one can't say how many entries are in the shares, or how many shares
> will be mounted
> - if they do, they need to calculate (nentries * (sizeof(struct
> cached_dirents) + namelen (of each entry) + 1)), + round up(1024),
> then finally divide by 1024, meaning they'll fallback to using the
> default value
>
> On the default value, I think 10% of RAM is too much for cifs cached
> entries.
Today, we don't have a limit on memory for cached entries. I took 10%
percent RAM
as default value to start with and we can tune it later based on need.
Please let me know if you have suggestions about limits.
>
> The max memory value should be module-wide, yes, but equally divided for
> each tcon, because I might have an initial not-so-important share that
> ends up filling the whole cache, then a more important/accessed one that
> will not have the chance to cache entries.
Ack. We can have more granular control later. But since we have dir
cache timeout of 30 seconds
unless it's reused again it is not a problem today. IMO memory will be
utilised by the mount which is
performing heavy metadata operations and that would actually need the
most caching.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-10-24 9:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-30 4:30 [SMB CLIENT][PATCHES] directory lease debugging and configuration Steve French
2025-09-30 13:11 ` Enzo Matsumiya
2025-09-30 13:13 ` Enzo Matsumiya
2025-10-24 9:13 ` Bharath SM
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).