summaryrefslogtreecommitdiff
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2016-09-23 00:44:16 -0500
committerSteve French <smfrench@gmail.com>2016-10-12 12:08:33 -0500
commit141891f4727c08829755be6c785e125d2e96c899 (patch)
treed2c32b7875356357062a0ab67044a4ae7287b689 /fs/cifs/connect.c
parent52ace1ef1259e119a24a34b45cb800c4e7529090 (diff)
downloadlwn-141891f4727c08829755be6c785e125d2e96c899.tar.gz
lwn-141891f4727c08829755be6c785e125d2e96c899.zip
SMB3: Add mount parameter to allow user to override max credits
Add mount option "max_credits" to allow setting maximum SMB3 credits to any value from 10 to 64000 (default is 32000). This can be useful to workaround servers with problems allocating credits, or to throttle the client to use smaller amount of simultaneous i/o or to workaround server performance issues. Also adds a cap, so that even if the server granted us more than 65000 credits due to a server bug, we would not use that many. Signed-off-by: Steve French <steve.french@primarydata.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7b67179521cf..657369db76df 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -63,7 +63,6 @@ extern mempool_t *cifs_req_poolp;
#define TLINK_IDLE_EXPIRE (600 * HZ)
enum {
-
/* Mount options that take no arguments */
Opt_user_xattr, Opt_nouser_xattr,
Opt_forceuid, Opt_noforceuid,
@@ -95,7 +94,7 @@ enum {
Opt_cruid, Opt_gid, Opt_file_mode,
Opt_dirmode, Opt_port,
Opt_rsize, Opt_wsize, Opt_actimeo,
- Opt_echo_interval,
+ Opt_echo_interval, Opt_max_credits,
/* Mount options which take string value */
Opt_user, Opt_pass, Opt_ip,
@@ -190,6 +189,7 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_wsize, "wsize=%s" },
{ Opt_actimeo, "actimeo=%s" },
{ Opt_echo_interval, "echo_interval=%s" },
+ { Opt_max_credits, "max_credits=%s" },
{ Opt_blank_user, "user=" },
{ Opt_blank_user, "username=" },
@@ -1586,6 +1586,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
}
vol->echo_interval = option;
break;
+ case Opt_max_credits:
+ if (get_option_ul(args, &option) || (option < 20) ||
+ (option > 60000)) {
+ cifs_dbg(VFS, "%s: Invalid max_credits value\n",
+ __func__);
+ goto cifs_parse_mount_err;
+ }
+ vol->max_credits = option;
+ break;
/* String Arguments */
@@ -3598,7 +3607,11 @@ try_mount_again:
bdi_destroy(&cifs_sb->bdi);
goto out;
}
-
+ if ((volume_info->max_credits < 20) ||
+ (volume_info->max_credits > 60000))
+ server->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
+ else
+ server->max_credits = volume_info->max_credits;
/* get a reference to a SMB session */
ses = cifs_get_smb_ses(server, volume_info);
if (IS_ERR(ses)) {