Commit 8fe7062b authored by Enzo Matsumiya's avatar Enzo Matsumiya Committed by Steve French

smb: client: negotiate compression algorithms

Change "compress=" mount option to a boolean flag, that, if set,
will enable negotiating compression algorithms with the server.

Do not de/compress anything for now.
Signed-off-by: default avatarEnzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 073dd87c
...@@ -278,6 +278,24 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) ...@@ -278,6 +278,24 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
return 0; return 0;
} }
static __always_inline const char *compression_alg_str(__le16 alg)
{
switch (alg) {
case SMB3_COMPRESS_NONE:
return "NONE";
case SMB3_COMPRESS_LZNT1:
return "LZNT1";
case SMB3_COMPRESS_LZ77:
return "LZ77";
case SMB3_COMPRESS_LZ77_HUFF:
return "LZ77-Huffman";
case SMB3_COMPRESS_PATTERN:
return "Pattern_V1";
default:
return "invalid";
}
}
static int cifs_debug_data_proc_show(struct seq_file *m, void *v) static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
{ {
struct mid_q_entry *mid_entry; struct mid_q_entry *mid_entry;
...@@ -423,12 +441,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -423,12 +441,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
server->echo_credits, server->echo_credits,
server->oplock_credits, server->oplock_credits,
server->dialect); server->dialect);
if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
seq_printf(m, " COMPRESS_LZNT1");
else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
seq_printf(m, " COMPRESS_LZ77");
else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF)
seq_printf(m, " COMPRESS_LZ77_HUFF");
if (server->sign) if (server->sign)
seq_printf(m, " signed"); seq_printf(m, " signed");
if (server->posix_ext_supported) if (server->posix_ext_supported)
...@@ -460,6 +472,14 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -460,6 +472,14 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
server->leaf_fullpath); server->leaf_fullpath);
} }
seq_puts(m, "\nCompression: ");
if (!server->compression.requested)
seq_puts(m, "disabled on mount");
else if (server->compression.enabled)
seq_printf(m, "enabled (%s)", compression_alg_str(server->compression.alg));
else
seq_puts(m, "disabled (not supported by this server)");
seq_printf(m, "\n\n\tSessions: "); seq_printf(m, "\n\n\tSessions: ");
i = 0; i = 0;
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
......
...@@ -769,7 +769,11 @@ struct TCP_Server_Info { ...@@ -769,7 +769,11 @@ struct TCP_Server_Info {
unsigned int max_write; unsigned int max_write;
unsigned int min_offload; unsigned int min_offload;
unsigned int retrans; unsigned int retrans;
__le16 compress_algorithm; struct {
bool requested; /* "compress" mount option set*/
bool enabled; /* actually negotiated with server */
__le16 alg; /* preferred alg negotiated with server */
} compression;
__u16 signing_algorithm; __u16 signing_algorithm;
__le16 cipher_type; __le16 cipher_type;
/* save initital negprot hash */ /* save initital negprot hash */
......
...@@ -1736,7 +1736,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, ...@@ -1736,7 +1736,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */ tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */
tcp_ses->reconnect_instance = 1; tcp_ses->reconnect_instance = 1;
tcp_ses->lstrp = jiffies; tcp_ses->lstrp = jiffies;
tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression); tcp_ses->compression.requested = ctx->compress;
spin_lock_init(&tcp_ses->req_lock); spin_lock_init(&tcp_ses->req_lock);
spin_lock_init(&tcp_ses->srv_lock); spin_lock_init(&tcp_ses->srv_lock);
spin_lock_init(&tcp_ses->mid_lock); spin_lock_init(&tcp_ses->mid_lock);
......
...@@ -963,7 +963,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, ...@@ -963,7 +963,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
switch (opt) { switch (opt) {
case Opt_compress: case Opt_compress:
ctx->compression = UNKNOWN_TYPE; ctx->compress = true;
cifs_dbg(VFS, cifs_dbg(VFS,
"SMB3 compression support is experimental\n"); "SMB3 compression support is experimental\n");
break; break;
......
...@@ -273,7 +273,7 @@ struct smb3_fs_context { ...@@ -273,7 +273,7 @@ struct smb3_fs_context {
unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */
unsigned int max_channels; unsigned int max_channels;
unsigned int max_cached_dirs; unsigned int max_cached_dirs;
__u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ bool compress; /* enable SMB2 messages (READ/WRITE) de/compression */
bool rootfs:1; /* if it's a SMB root file system */ bool rootfs:1; /* if it's a SMB root file system */
bool witness:1; /* use witness protocol */ bool witness:1; /* use witness protocol */
char *leaf_fullpath; char *leaf_fullpath;
......
...@@ -731,7 +731,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, ...@@ -731,7 +731,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
pneg_ctxt += sizeof(struct smb2_posix_neg_context); pneg_ctxt += sizeof(struct smb2_posix_neg_context);
neg_context_count++; neg_context_count++;
if (server->compress_algorithm) { if (server->compression.requested) {
build_compression_ctxt((struct smb2_compression_capabilities_context *) build_compression_ctxt((struct smb2_compression_capabilities_context *)
pneg_ctxt); pneg_ctxt);
ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8); ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8);
...@@ -779,6 +779,9 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, ...@@ -779,6 +779,9 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
struct smb2_compression_capabilities_context *ctxt) struct smb2_compression_capabilities_context *ctxt)
{ {
unsigned int len = le16_to_cpu(ctxt->DataLength); unsigned int len = le16_to_cpu(ctxt->DataLength);
__le16 alg;
server->compression.enabled = false;
/* /*
* Caller checked that DataLength remains within SMB boundary. We still * Caller checked that DataLength remains within SMB boundary. We still
...@@ -789,15 +792,22 @@ static void decode_compress_ctx(struct TCP_Server_Info *server, ...@@ -789,15 +792,22 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
pr_warn_once("server sent bad compression cntxt\n"); pr_warn_once("server sent bad compression cntxt\n");
return; return;
} }
if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) { if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) {
pr_warn_once("Invalid SMB3 compress algorithm count\n"); pr_warn_once("invalid SMB3 compress algorithm count\n");
return; return;
} }
if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) {
pr_warn_once("unknown compression algorithm\n"); alg = ctxt->CompressionAlgorithms[0];
/* 'NONE' (0) compressor type is never negotiated */
if (alg == 0 || le16_to_cpu(alg) > 3) {
pr_warn_once("invalid compression algorithm '%u'\n", alg);
return; return;
} }
server->compress_algorithm = ctxt->CompressionAlgorithms[0];
server->compression.alg = alg;
server->compression.enabled = true;
} }
static int decode_encrypt_ctx(struct TCP_Server_Info *server, static int decode_encrypt_ctx(struct TCP_Server_Info *server,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment