summaryrefslogtreecommitdiff
path: root/fs/smb
diff options
context:
space:
mode:
authorEnzo Matsumiya <ematsumiya@suse.de>2024-02-23 11:58:57 -0300
committerSteve French <stfrench@microsoft.com>2024-03-10 19:52:42 -0500
commit8fe7062b7d11fcd21c4dcb5f530eaa1a099b24e7 (patch)
treee18865670d456f31c3546d5401223de10c42a7eb /fs/smb
parent073dd87c8e1ee55ca163956f0c71249dc28aac51 (diff)
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: Enzo Matsumiya <ematsumiya@suse.de> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb')
-rw-r--r--fs/smb/client/cifs_debug.c32
-rw-r--r--fs/smb/client/cifsglob.h6
-rw-r--r--fs/smb/client/connect.c2
-rw-r--r--fs/smb/client/fs_context.c2
-rw-r--r--fs/smb/client/fs_context.h2
-rw-r--r--fs/smb/client/smb2pdu.c20
6 files changed, 49 insertions, 15 deletions
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 23d2622b969f..226d4835c92d 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -278,6 +278,24 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
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)
{
struct mid_q_entry *mid_entry;
@@ -423,12 +441,6 @@ skip_rdma:
server->echo_credits,
server->oplock_credits,
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)
seq_printf(m, " signed");
if (server->posix_ext_supported)
@@ -460,6 +472,14 @@ skip_rdma:
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: ");
i = 0;
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index a0506a45eae3..8be62ed053a2 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -769,7 +769,11 @@ struct TCP_Server_Info {
unsigned int max_write;
unsigned int min_offload;
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;
__le16 cipher_type;
/* save initital negprot hash */
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 5d82921d63d1..86ae578904a2 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -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->reconnect_instance = 1;
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->srv_lock);
spin_lock_init(&tcp_ses->mid_lock);
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 4b767efa47f1..bdcbe6ff2739 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -963,7 +963,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
switch (opt) {
case Opt_compress:
- ctx->compression = UNKNOWN_TYPE;
+ ctx->compress = true;
cifs_dbg(VFS,
"SMB3 compression support is experimental\n");
break;
diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h
index 1f09754977e7..7863f2248c4d 100644
--- a/fs/smb/client/fs_context.h
+++ b/fs/smb/client/fs_context.h
@@ -273,7 +273,7 @@ struct smb3_fs_context {
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 compress; /* enable SMB2 messages (READ/WRITE) de/compression */
bool rootfs:1; /* if it's a SMB root file system */
bool witness:1; /* use witness protocol */
char *leaf_fullpath;
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 7d0157e0061e..e5e6b14f8cae 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -731,7 +731,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
pneg_ctxt += sizeof(struct smb2_posix_neg_context);
neg_context_count++;
- if (server->compress_algorithm) {
+ if (server->compression.requested) {
build_compression_ctxt((struct smb2_compression_capabilities_context *)
pneg_ctxt);
ctxt_len = ALIGN(sizeof(struct smb2_compression_capabilities_context), 8);
@@ -779,6 +779,9 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
struct smb2_compression_capabilities_context *ctxt)
{
unsigned int len = le16_to_cpu(ctxt->DataLength);
+ __le16 alg;
+
+ server->compression.enabled = false;
/*
* Caller checked that DataLength remains within SMB boundary. We still
@@ -789,15 +792,22 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
pr_warn_once("server sent bad compression cntxt\n");
return;
}
+
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;
}
- 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;
}
- server->compress_algorithm = ctxt->CompressionAlgorithms[0];
+
+ server->compression.alg = alg;
+ server->compression.enabled = true;
}
static int decode_encrypt_ctx(struct TCP_Server_Info *server,