[PATCH v2 09/14] smb: common: compress: allow smb_lz77_compress() to overcompress
Enzo Matsumiya <[email protected]> Mon, 20 Jul 2026 16:49:20 -0300
| 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 | 5 ++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c index 37e92e2bc816..363ad58ad798 100644 --- a/fs/smb/client/compress.c +++ b/fs/smb/client/compress.c @@ -406,7 +406,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s ret = smb_compression_compress(SMB3_COMPRESS_LZ77, chained, use_pattern, src, slen, dst, &dlen); - if (!ret) { + if (!ret && dlen < slen) { struct smb2_compression_hdr *hdrp = dst, hdr = {}; struct smb_rqst comp_rq = { .rq_nvec = 3, }; struct kvec iov[3]; @@ -453,7 +453,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 999b7b11de85..59e78c3b042c 100644 --- a/fs/smb/server/compress.c +++ b/fs/smb/server/compress.c @@ -151,10 +151,9 @@ int ksmbd_compress_response(struct ksmbd_work *work) src, src_len, out + sizeof(__be32), &dst_len); - if (rc == -EMSGSIZE || dst_len >= src_len) { - rc = 0; + /* if dst_len >= src_len, rc is 0 */ + if (rc || dst_len >= src_len) goto out; - } *(__be32 *)out = cpu_to_be32(dst_len); -- 2.54.0