[PATCH 06/10] smb: common: compress: allow smb_lz77_compress() to overcompress

Enzo Matsumiya <[email protected]>
Newsgroups org.kernel.vger.linux-cifs
Message-ID <[email protected]>
Change smb_lz77_compress() to return 0 on successful compression,
leaving it up to callers to decide if @dlen >= @slen is an error
(currently returns -EMSGSIZE on such cases).

This allows better compression in certain cases where Pattern_V1 got a
good compression already, but LZ77 chunk was overcompressed (which
usually yields good compressed data as a whole)

Other changes:
- adjust client and server callers to correctly interpret the
  new return value

Signed-off-by: Enzo Matsumiya <[email protected]>
---
 fs/smb/client/compress.c      |  4 ++--
 fs/smb/common/compress/lz77.c |  7 ++-----
 fs/smb/server/compress.c      | 15 ++++-----------
 3 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c
index 72ac727250f6..d94bacf3edbd 100644
--- a/fs/smb/client/compress.c
+++ b/fs/smb/client/compress.c
@@ -392,7 +392,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s
 
 	ret = smb_compression_compress(SMB3_COMPRESS_LZ77, server->compression.chained, use_pattern,
 				       src, slen, dst, &dlen, rq->rq_iov[0].iov_base, shdr_len);
-	if (!ret) {
+	if (!ret && dlen < slen) {
 		struct smb_rqst comp_rq = { .rq_nvec = 1, };
 		struct kvec iov = {
 			.iov_base = dst,
@@ -404,7 +404,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s
 		comp_rq.rq_iov = &iov;
 
 		ret = send_fn(server, 1, &comp_rq);
-	} else if (ret == -EMSGSIZE || dlen >= slen) {
+	} else if (!ret) {
 		ret = send_fn(server, 1, rq);
 	}
 err_free:
diff --git a/fs/smb/common/compress/lz77.c b/fs/smb/common/compress/lz77.c
index e32e2f3040d8..f88f49e01629 100644
--- a/fs/smb/common/compress/lz77.c
+++ b/fs/smb/common/compress/lz77.c
@@ -248,19 +248,16 @@ noinline int smb_lz77_compress(const void *src, const u32 slen, void *dst, u32 *
 	} while (srcp < end);
 out:
 	dstp = lz77_encode_literals(anchor, end, dstp, &flag, &flag_count, &flag_pos);
-
 	flag_count = LZ77_FLAG_MAX - flag_count;
 	flag <<= flag_count;
 	flag |= (1UL << flag_count) - 1;
 	mem_write32(flag_pos, flag);
 
+	/* Compression is successful from our POV -- let caller decide if @dlen suits them. */
 	*dlen = dstp - dst;
 	kvfree(htable);
 
-	if (*dlen < slen)
-		return 0;
-
-	return -EMSGSIZE;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(smb_lz77_compress);
 
diff --git a/fs/smb/server/compress.c b/fs/smb/server/compress.c
index e5851d603469..648660f8bfab 100644
--- a/fs/smb/server/compress.c
+++ b/fs/smb/server/compress.c
@@ -148,12 +148,10 @@ int ksmbd_compress_response(struct ksmbd_work *work)
 					      src, src_len,
 					      out + sizeof(__be32), &dst_len,
 					      NULL, 0);
-		if (rc == -EMSGSIZE || dst_len >= src_len) {
-			rc = 0;
-			goto out;
-		}
-		if (rc)
+		/* if dst_len >= src_len, rc is 0 */
+		if (rc || dst_len >= src_len)
 			goto out;
+
 		compressed_pdu_len = dst_len;
 	} else {
 		/*
@@ -164,12 +162,7 @@ int ksmbd_compress_response(struct ksmbd_work *work)
 		rc = smb_lz77_compress(src, src_len,
 				       out + sizeof(__be32) + sizeof(*chdr),
 				       &dst_len);
-		if (rc == -EMSGSIZE ||
-		    dst_len + sizeof(*chdr) >= src_len) {
-			rc = 0;
-			goto out;
-		}
-		if (rc)
+		if (rc || dst_len + sizeof(*chdr) >= src_len)
 			goto out;
 
 		compressed_pdu_len = sizeof(*chdr) + dst_len;
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.