[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