smb3: allow controlling maximum number of cached directories
authorSteve French <stfrench@microsoft.com>
Fri, 1 Sep 2023 07:15:14 +0000 (02:15 -0500)
committerSteve French <stfrench@microsoft.com>
Thu, 7 Sep 2023 05:06:04 +0000 (00:06 -0500)
Allow adjusting the maximum number of cached directories per share
(defaults to 16) via mount parm "max_cached_dirs"

Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cached_dir.c
fs/smb/client/cached_dir.h
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/connect.c
fs/smb/client/fs_context.c
fs/smb/client/fs_context.h

index 9d84c4a7bd0cee862e21aca89d10bc0810771542..b17f067e4ada0503e61550a16e6536c96055ed96 100644 (file)
@@ -18,7 +18,8 @@ static void smb2_close_cached_fid(struct kref *ref);
 
 static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
                                                    const char *path,
-                                                   bool lookup_only)
+                                                   bool lookup_only,
+                                                   __u32 max_cached_dirs)
 {
        struct cached_fid *cfid;
 
@@ -43,7 +44,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
                spin_unlock(&cfids->cfid_list_lock);
                return NULL;
        }
-       if (cfids->num_entries >= MAX_CACHED_FIDS) {
+       if (cfids->num_entries >= max_cached_dirs) {
                spin_unlock(&cfids->cfid_list_lock);
                return NULL;
        }
@@ -162,7 +163,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        if (!utf16_path)
                return -ENOMEM;
 
-       cfid = find_or_create_cached_dir(cfids, path, lookup_only);
+       cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs);
        if (cfid == NULL) {
                kfree(utf16_path);
                return -ENOENT;
index facc9b154d0094cb954f79a0f199a6f80a578996..a82ff2cea789c68b1ecdaf70dc489b593ed7227a 100644 (file)
@@ -49,7 +49,7 @@ struct cached_fid {
        struct cached_dirents dirents;
 };
 
-#define MAX_CACHED_FIDS 16
+/* default MAX_CACHED_FIDS is 16 */
 struct cached_fids {
        /* Must be held when:
         * - accessing the cfids->entries list
index 52612bb52bd71bb693121c0a0f7d947f44a71ead..22869cda13565e5838b7711c844963f1a6d87bd9 100644 (file)
@@ -699,6 +699,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
        if (tcon->handle_timeout)
                seq_printf(s, ",handletimeout=%u", tcon->handle_timeout);
+       if (tcon->max_cached_dirs != MAX_CACHED_FIDS)
+               seq_printf(s, ",max_cached_dirs=%u", tcon->max_cached_dirs);
 
        /*
         * Display file and directory attribute timeout in seconds.
index 501426ee39e72ed8a0d3a7df6ca9079a692d334d..032d8716f6719cb0084d90aa9145b29c4a55cb03 100644 (file)
@@ -1210,6 +1210,7 @@ struct cifs_tcon {
        __u32 max_chunks;
        __u32 max_bytes_chunk;
        __u32 max_bytes_copy;
+       __u32 max_cached_dirs;
 #ifdef CONFIG_CIFS_FSCACHE
        u64 resource_id;                /* server resource id */
        struct fscache_volume *fscache; /* cookie for share */
index 3bd71f982170117b658a9fc3dfd98b4b5e36721c..687754791bf0af496029bf7ba19d3cf7c46cdae7 100644 (file)
@@ -2657,6 +2657,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
        tcon->retry = ctx->retry;
        tcon->nocase = ctx->nocase;
        tcon->broken_sparse_sup = ctx->no_sparse;
+       tcon->max_cached_dirs = ctx->max_cached_dirs;
        if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
                tcon->nohandlecache = ctx->nohandlecache;
        else
index 67e16c2ac90e6f7b2d34418cae4b0b936ccaf29f..e45ce31bbda7174c8754a89aed4dfe76d413b8b5 100644 (file)
@@ -150,6 +150,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
        fsparam_u32("closetimeo", Opt_closetimeo),
        fsparam_u32("echo_interval", Opt_echo_interval),
        fsparam_u32("max_credits", Opt_max_credits),
+       fsparam_u32("max_cached_dirs", Opt_max_cached_dirs),
        fsparam_u32("handletimeout", Opt_handletimeout),
        fsparam_u64("snapshot", Opt_snapshot),
        fsparam_u32("max_channels", Opt_max_channels),
@@ -1165,6 +1166,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
                if (result.uint_32 > 1)
                        ctx->multichannel = true;
                break;
+       case Opt_max_cached_dirs:
+               if (result.uint_32 < 1) {
+                       cifs_errorf(fc, "%s: Invalid max_cached_dirs, needs to be 1 or more\n",
+                                   __func__);
+                       goto cifs_parse_mount_err;
+               }
+               ctx->max_cached_dirs = result.uint_32;
+               break;
        case Opt_handletimeout:
                ctx->handle_timeout = result.uint_32;
                if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
@@ -1592,7 +1601,7 @@ int smb3_init_fs_context(struct fs_context *fc)
        ctx->acregmax = CIFS_DEF_ACTIMEO;
        ctx->acdirmax = CIFS_DEF_ACTIMEO;
        ctx->closetimeo = SMB3_DEF_DCLOSETIMEO;
-
+       ctx->max_cached_dirs = MAX_CACHED_FIDS;
        /* Most clients set timeout to 0, allows server to use its default */
        ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */
 
index f4eaf855890222924c99a92f693f131b0c69cde7..9d8d34af021147f646cc6421fdbd210f9cbfa8f2 100644 (file)
@@ -128,6 +128,7 @@ enum cifs_param {
        Opt_closetimeo,
        Opt_echo_interval,
        Opt_max_credits,
+       Opt_max_cached_dirs,
        Opt_snapshot,
        Opt_max_channels,
        Opt_handletimeout,
@@ -261,6 +262,7 @@ struct smb3_fs_context {
        __u32 handle_timeout; /* persistent and durable handle timeout in ms */
        unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */
        unsigned int max_channels;
+       unsigned int max_cached_dirs;
        __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */
        bool rootfs:1; /* if it's a SMB root file system */
        bool witness:1; /* use witness protocol */
@@ -287,7 +289,7 @@ extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
  */
 #define SMB3_MAX_DCLOSETIMEO (1 << 30)
 #define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
-
+#define MAX_CACHED_FIDS 16
 extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp);
 
 #endif