diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index b0ea332af35c..ebf85a5d95e4 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -559,6 +559,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",rsize=%u", cifs_sb->rsize); seq_printf(s, ",wsize=%u", cifs_sb->wsize); seq_printf(s, ",bsize=%u", cifs_sb->bsize); + if (tcon->ses->server->min_offload) + seq_printf(s, ",esize=%u", tcon->ses->server->min_offload); seq_printf(s, ",echo_interval=%lu", tcon->ses->server->echo_interval / HZ); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index d66106ac031a..6987fbc5a24a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -592,6 +592,7 @@ struct smb_vol { unsigned int bsize; unsigned int rsize; unsigned int wsize; + unsigned int min_offload; bool sockopt_tcp_nodelay:1; unsigned long actimeo; /* attribute cache timeout (jiffies) */ struct smb_version_operations *ops; @@ -745,6 +746,7 @@ struct TCP_Server_Info { #endif /* STATS2 */ unsigned int max_read; unsigned int max_write; + unsigned int min_offload; __le16 compress_algorithm; __le16 cipher_type; /* save initital negprot hash */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 17882cede197..e70112d67b0e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -103,6 +103,7 @@ enum { Opt_backupuid, Opt_backupgid, Opt_uid, Opt_cruid, Opt_gid, Opt_file_mode, Opt_dirmode, Opt_port, + Opt_min_enc_offload, Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, Opt_echo_interval, Opt_max_credits, Opt_handletimeout, Opt_snapshot, @@ -207,6 +208,7 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_dirmode, "dirmode=%s" }, { Opt_dirmode, "dir_mode=%s" }, { Opt_port, "port=%s" }, + { Opt_min_enc_offload, "esize=%s" }, { Opt_blocksize, "bsize=%s" }, { Opt_rsize, "rsize=%s" }, { Opt_wsize, "wsize=%s" }, @@ -2016,6 +2018,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } port = (unsigned short)option; break; + case Opt_min_enc_offload: + if (get_option_ul(args, &option)) { + cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n"); + goto cifs_parse_mount_err; + } + vol->min_offload = option; + break; case Opt_blocksize: if (get_option_ul(args, &option)) { cifs_dbg(VFS, "%s: Invalid blocksize value\n", @@ -2616,6 +2625,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) if (server->ignore_signature != vol->ignore_signature) return 0; + if (server->min_offload != vol->min_offload) + return 0; + return 1; } @@ -2790,6 +2802,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) module_put(THIS_MODULE); goto out_err_crypto_release; } + tcp_ses->min_offload = volume_info->min_offload; tcp_ses->tcpStatus = CifsNeedNegotiate; tcp_ses->nr_targets = 1; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index c74284484947..1cfb8d518132 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4121,8 +4121,8 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, * use more cores decrypting which can be expensive */ - /* TODO: make the size limit to enable decrypt offload configurable */ - if (server->pdu_size > (512 * 1024)) { + if ((server->min_offload) && + (server->pdu_size >= server->min_offload)) { dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); if (dw == NULL) goto non_offloaded_decrypt;