Skip to content

Commit

Permalink
smb3: allow controlling maximum number of cached directories
Browse files Browse the repository at this point in the history
[ Upstream commit 6a50d71 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Steve French authored and gregkh committed Nov 2, 2023
1 parent 9cb2ea5 commit 3027d30
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 6 deletions.
7 changes: 4 additions & 3 deletions fs/smb/client/cached_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion fs/smb/client/cached_dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions fs/smb/client/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions fs/smb/client/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,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 */
Expand Down
1 change: 1 addition & 0 deletions fs/smb/client/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion fs/smb/client/fs_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1593,7 +1602,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 */

Expand Down
4 changes: 3 additions & 1 deletion fs/smb/client/fs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand All @@ -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

0 comments on commit 3027d30

Please sign in to comment.