summaryrefslogtreecommitdiff
path: root/fs/smb/client/smb2pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/smb/client/smb2pdu.c')
-rw-r--r--fs/smb/client/smb2pdu.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 23801b028530..afd823c9cbca 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -589,12 +589,17 @@ build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
pneg_ctxt->DataLength =
cpu_to_le16(sizeof(struct smb2_compression_capabilities_context)
- sizeof(struct smb2_neg_context));
- pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(1);
+
+ /* This enables the usage of the Pattern_V1 algorithm */
+ pneg_ctxt->Flags = SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED;
+ pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(2);
+
/*
- * Send the only algorithm we support (XXX: add others as they're
+ * Send the algorithms we support (XXX: add others as they're
* implemented).
*/
pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77;
+ pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_PATTERN;
}
static unsigned int
@@ -782,9 +787,13 @@ 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;
+ __le16 count, i;
+ int chained;
server->compression.enabled = false;
+ server->compression.chained = false;
+ count = ctxt->CompressionAlgorithmCount;
+ chained = !!(ctxt->Flags & SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED);
/*
* Caller checked that DataLength remains within SMB boundary. We still
@@ -796,18 +805,27 @@ static void decode_compress_ctx(struct TCP_Server_Info *server,
return;
}
- if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) {
- pr_warn_once("invalid SMB3 compress algorithm count\n");
+ if (unlikely(count != 2)) {
+ pr_warn_once("invalid SMB3 compress algorithm count '%u'\n", count);
return;
}
- alg = ctxt->CompressionAlgorithms[0];
- if (!smb_compress_alg_valid(alg, false)) {
- pr_warn_once("invalid compression algorithm '%u'\n", alg);
- return;
+ for (i = 0; i < count; i++) {
+ __le16 alg = ctxt->CompressionAlgorithms[i];
+
+ if (!smb_compress_alg_valid(alg, false)) {
+ pr_warn_once("invalid compression algorithm '%u'\n", alg);
+ return;
+ }
+
+ if (alg == SMB3_COMPRESS_PATTERN) {
+ if (chained)
+ server->compression.chained = true;
+ } else {
+ server->compression.alg = alg;
+ }
}
- server->compression.alg = alg;
server->compression.enabled = true;
}