updated patch with Barath's suggestion of renaming it from /sys/module/cifs/parameters/max_dir_cache to /sys/module/cifs/parameters/dir_cache_timeout and also changed it so if set to zero we disable directory entry caching. See attached. On Sun, Aug 27, 2023 at 12:12 AM Steve French <smfrench@xxxxxxxxx> wrote: > > Currently with directory leases we cache directory contents for a fixed period > of time (default 30 seconds) but for many workloads this is too short. Allow > configuring the maximum amount of time directory entries are cached when a > directory lease is held on that directory (and set default timeout to > 60 seconds). > Add module load parm "max_dir_cache" > > For example to set the timeout to 10 minutes you would do: > > echo 600 > /sys/module/cifs/parameters/max_dir_cache > > Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> > --- > fs/smb/client/cached_dir.c | 2 +- > fs/smb/client/cifsfs.c | 12 ++++++++++++ > fs/smb/client/cifsglob.h | 1 + > 3 files changed, 14 insertions(+), 1 deletion(-) > > diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c > index 2d5e9a9d5b8b..e48a902efd52 100644 > --- a/fs/smb/client/cached_dir.c > +++ b/fs/smb/client/cached_dir.c > @@ -582,7 +582,7 @@ cifs_cfids_laundromat_thread(void *p) > return 0; > spin_lock(&cfids->cfid_list_lock); > list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { > - if (time_after(jiffies, cfid->time + HZ * 30)) { > + if (time_after(jiffies, cfid->time + HZ * max_dir_cache)) { > list_del(&cfid->entry); > list_add(&cfid->entry, &entry); > cfids->num_entries--; > diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c > index d49fd2bf71b0..7a89718d2a59 100644 > --- a/fs/smb/client/cifsfs.c > +++ b/fs/smb/client/cifsfs.c > @@ -117,6 +117,10 @@ module_param(cifs_max_pending, uint, 0444); > MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server for " > "CIFS/SMB1 dialect (N/A for SMB3) " > "Default: 32767 Range: 2 to 32767."); > +unsigned int max_dir_cache = 60; > +module_param(max_dir_cache, uint, 0644); > +MODULE_PARM_DESC(max_dir_cache, "Number of seconds to cache directory > contents for which we have a lease. Default: 60 " > + "Range: 1 to 65000 seconds"); > #ifdef CONFIG_CIFS_STATS2 > unsigned int slow_rsp_threshold = 1; > module_param(slow_rsp_threshold, uint, 0644); > @@ -1679,6 +1683,14 @@ init_cifs(void) > CIFS_MAX_REQ); > } > > + if (max_dir_cache < 1) { > + max_dir_cache = 1; > + cifs_dbg(VFS, "max_dir_cache timeout set to min of 1 second\n"); > + } else if (max_dir_cache > 65000) { > + max_dir_cache = 65000; > + cifs_dbg(VFS, "max_dir_cache timeout set to max of 65000 seconds\n"); > + } > + > cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); > if (!cifsiod_wq) { > rc = -ENOMEM; > diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h > index 259e231f8b4f..7aeeaa260cce 100644 > --- a/fs/smb/client/cifsglob.h > +++ b/fs/smb/client/cifsglob.h > @@ -2016,6 +2016,7 @@ extern unsigned int CIFSMaxBufSize; /* max size > not including hdr */ > extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ > extern unsigned int cifs_min_small; /* min size of small buf pool */ > extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ > +extern unsigned int max_dir_cache; /* max time for directory lease > caching of dir */ > extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ > extern atomic_t mid_count; > > > -- > Thanks, > > Steve -- Thanks, Steve
From c5e18f4d5e2a14ceb51314067984d488829e45ca Mon Sep 17 00:00:00 2001 From: Steve French <stfrench@xxxxxxxxxxxxx> Date: Wed, 30 Aug 2023 22:48:41 -0500 Subject: [PATCH] smb3: allow controlling length of time directory entries are cached with dir leases Currently with directory leases we cache directory contents for a fixed period of time (default 30 seconds) but for many workloads this is too short. Allow configuring the maximum amount of time directory entries are cached when a directory lease is held on that directory. Add module load parm "max_dir_cache" For example to set the timeout to 10 minutes you would do: echo 600 > /sys/module/cifs/parameters/dir_cache_timeout or to disable caching directory contents: echo 0 > /sys/module/cifs/parameters/dir_cache_timeout Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> --- fs/smb/client/cached_dir.c | 4 ++-- fs/smb/client/cifsfs.c | 10 ++++++++++ fs/smb/client/cifsglob.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 2d5e9a9d5b8b..9d84c4a7bd0c 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -145,7 +145,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, const char *npath; if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache || - is_smb1_server(tcon->ses->server)) + is_smb1_server(tcon->ses->server) || (dir_cache_timeout == 0)) return -EOPNOTSUPP; ses = tcon->ses; @@ -582,7 +582,7 @@ cifs_cfids_laundromat_thread(void *p) return 0; spin_lock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { - if (time_after(jiffies, cfid->time + HZ * 30)) { + if (time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { list_del(&cfid->entry); list_add(&cfid->entry, &entry); cfids->num_entries--; diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index d49fd2bf71b0..b92e9a138443 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -117,6 +117,10 @@ module_param(cifs_max_pending, uint, 0444); MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server for " "CIFS/SMB1 dialect (N/A for SMB3) " "Default: 32767 Range: 2 to 32767."); +unsigned int dir_cache_timeout = 60; +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: 60 " + "Range: 1 to 65000 seconds, 0 to disable caching dir contents"); #ifdef CONFIG_CIFS_STATS2 unsigned int slow_rsp_threshold = 1; module_param(slow_rsp_threshold, uint, 0644); @@ -1679,6 +1683,12 @@ init_cifs(void) CIFS_MAX_REQ); } + /* Limit max to about 18 hours, and setting to zero disables directory entry caching */ + if (dir_cache_timeout > 65000) { + dir_cache_timeout = 65000; + cifs_dbg(VFS, "dir_cache_timeout set to max of 65000 seconds\n"); + } + cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); if (!cifsiod_wq) { rc = -ENOMEM; diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 259e231f8b4f..501426ee39e7 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -2016,6 +2016,7 @@ extern unsigned int CIFSMaxBufSize; /* max size not including hdr */ extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ extern unsigned int cifs_min_small; /* min size of small buf pool */ extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ +extern unsigned int dir_cache_timeout; /* max time for directory lease caching of dir */ extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ extern atomic_t mid_count; -- 2.34.1