lib_log: fix logfile compression corner case

This commit is contained in:
Thomas Schoebel-Theuer 2021-03-10 15:43:26 +01:00 committed by Thomas Schoebel-Theuer
parent 84f44fa106
commit 193c650377
2 changed files with 44 additions and 20 deletions

View File

@ -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;
}
}

View File

@ -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;