diff --git a/kernel/lib_log.c b/kernel/lib_log.c index 20109e71..4ebb5865 100644 --- a/kernel/lib_log.c +++ b/kernel/lib_log.c @@ -148,19 +148,43 @@ err: } static -int log_compress(struct log_status *logst, int len, __u32 *result_flags) +int log_compress(struct log_status *logst, int len, + int *padded_len, + __u32 *result_flags) { struct mref_object *mref = logst->log_mref; + void *inplace_buf; + void *compr_buf; + int compr_len; int res; if (unlikely(!mref || !mref->ref_data || len <= 0)) return 0; - res = mars_compress(mref->ref_data + logst->payload_offset, len, - NULL, 0, + compr_len = len + compress_overhead; + compr_buf = brick_mem_alloc(compr_len); + inplace_buf = mref->ref_data + logst->payload_offset; + + res = mars_compress(inplace_buf, len, + compr_buf, compr_len, enabled_log_compressions, result_flags); - used_log_compression = *result_flags; + + /* pad the resulting length */ + if (res > 0) { + int pad_len = ((res + (_LOG_PAD - 1)) / _LOG_PAD) * _LOG_PAD; + + /* Did compression pay off? */ + if (pad_len < len) { + *padded_len = pad_len; + used_log_compression = *result_flags; + memcpy(inplace_buf, compr_buf, res); + } else { + *padded_len = len; + res = 0; + } + } + brick_mem_free(compr_buf); return res; } @@ -411,13 +435,16 @@ bool log_finalize(struct log_status *logst, int len, void (*endio)(void *private decompr_len = 0; padded_len = len; if (logst->do_compress) { - int new_len = log_compress(logst, len, &check_flags); - int padded_new_len = ((new_len + (_LOG_PAD-1)) / _LOG_PAD) * _LOG_PAD; + __u32 new_check_flags = check_flags; + int new_len = log_compress(logst, len, + &padded_len, + &new_check_flags); - if (new_len > 0 && padded_new_len < len) { + /* When compression did not pay off, treat as uncompressed */ + if (new_len > 0) { + check_flags = new_check_flags; /* exchange the lengths */ decompr_len = len; - padded_len = padded_new_len; len = new_len; } } diff --git a/kernel/mars_generic.c b/kernel/mars_generic.c index 2bf80557..76ae419d 100644 --- a/kernel/mars_generic.c +++ b/kernel/mars_generic.c @@ -705,9 +705,7 @@ int mars_compress(void *src_data, if (!dst_data) { tmp_buf = brick_mem_alloc(max_len); } else if (dst_len < max_len) { - MARS_ERR("LZO compression buffer too small: %d < %d\n", - dst_len, max_len); - return 0; + return -ENOSPC; } wrkmem = brick_mem_alloc(LZO1X_1_MEM_COMPRESS); @@ -717,7 +715,7 @@ int mars_compress(void *src_data, /* ensure that the result is really smaller */ if (status == LZO_E_OK && res_len > 0 && - res_len < src_len) { + res_len <= dst_len) { used_compression = MREF_COMPRESS_LZO; *result_flags |= MREF_COMPRESS_LZO; res = res_len; @@ -746,9 +744,7 @@ int mars_compress(void *src_data, if (!dst_data) { tmp_buf = brick_mem_alloc(max_len); } else if (dst_len < max_len) { - MARS_ERR("LZ4 compression buffer too small: %d < %lu\n", - dst_len, max_len); - return 0; + return -ENOSPC; } wrkmem = brick_block_alloc(0, LZ4_MEM_COMPRESS); @@ -766,7 +762,9 @@ int mars_compress(void *src_data, tmp_buf, &res_len, wrkmem); #endif - if (likely(!status && res_len > 0 && res_len < src_len)) { + if (likely(!status && + res_len > 0 && + res_len <= dst_len)) { used_compression = MREF_COMPRESS_LZ4; *result_flags |= MREF_COMPRESS_LZ4; res = res_len; @@ -792,9 +790,7 @@ int mars_compress(void *src_data, if (!dst_data) { tmp_buf = brick_mem_alloc(src_len); } else if (dst_len < src_len) { - MARS_ERR("ZLIB compression buffer too small: %d < %d\n", - dst_len, src_len); - return 0; + return -ENOSPC; } status = zlib_deflateInit(&stream, mars_zlib_compression_level); @@ -813,7 +809,8 @@ int mars_compress(void *src_data, goto zlib_err; status = zlib_deflateEnd(&stream); - if (status == Z_OK && stream.total_out < src_len) { + if (status == Z_OK && + stream.total_out <= dst_len) { used_compression = MREF_COMPRESS_ZLIB; *result_flags |= MREF_COMPRESS_ZLIB; res = stream.total_out;