Skip to content

Commit

Permalink
Fix QAT allocation failure return value
Browse files Browse the repository at this point in the history
When qat_compress() fails to allocate the required contiguous memory
it mistakenly returns success.  This prevents the fallback software
compression from taking over and (un)compressing the block.

Resolve the issue by correctly setting the local 'status' variable
on all exit paths.  Furthermore, initialize it to CPA_STATUS_FAIL
to ensure qat_compress() always fails safe to guard against any
similar bugs in the future.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes openzfs#9784
Closes openzfs#9788
  • Loading branch information
behlendorf authored and tonyhutter committed Jan 22, 2020
1 parent 9111fe2 commit 8d26607
Showing 1 changed file with 18 additions and 15 deletions.
33 changes: 18 additions & 15 deletions module/zfs/qat_compress.c
Expand Up @@ -249,7 +249,7 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,
Cpa8U *buffer_meta_dst = NULL;
Cpa32U buffer_meta_size = 0;
CpaDcRqResults dc_results;
CpaStatus status = CPA_STATUS_SUCCESS;
CpaStatus status = CPA_STATUS_FAIL;
Cpa32U hdr_sz = 0;
Cpa32U compressed_sz;
Cpa32U num_src_buf = (src_len >> PAGE_SHIFT) + 2;
Expand Down Expand Up @@ -278,16 +278,19 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,
Cpa32U dst_buffer_list_mem_size = sizeof (CpaBufferList) +
((num_dst_buf + num_add_buf) * sizeof (CpaFlatBuffer));

if (QAT_PHYS_CONTIG_ALLOC(&in_pages,
num_src_buf * sizeof (struct page *)) != CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&in_pages,
num_src_buf * sizeof (struct page *));
if (status != CPA_STATUS_SUCCESS)
goto fail;

if (QAT_PHYS_CONTIG_ALLOC(&out_pages,
num_dst_buf * sizeof (struct page *)) != CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&out_pages,
num_dst_buf * sizeof (struct page *));
if (status != CPA_STATUS_SUCCESS)
goto fail;

if (QAT_PHYS_CONTIG_ALLOC(&add_pages,
num_add_buf * sizeof (struct page *)) != CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&add_pages,
num_add_buf * sizeof (struct page *));
if (status != CPA_STATUS_SUCCESS)
goto fail;

i = (Cpa32U)atomic_inc_32_nv(&inst_num) % num_inst;
Expand All @@ -296,28 +299,28 @@ qat_compress_impl(qat_compress_dir_t dir, char *src, int src_len,

cpaDcBufferListGetMetaSize(dc_inst_handle, num_src_buf,
&buffer_meta_size);
if (QAT_PHYS_CONTIG_ALLOC(&buffer_meta_src, buffer_meta_size) !=
CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&buffer_meta_src, buffer_meta_size);
if (status != CPA_STATUS_SUCCESS)
goto fail;

cpaDcBufferListGetMetaSize(dc_inst_handle, num_dst_buf + num_add_buf,
&buffer_meta_size);
if (QAT_PHYS_CONTIG_ALLOC(&buffer_meta_dst, buffer_meta_size) !=
CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&buffer_meta_dst, buffer_meta_size);
if (status != CPA_STATUS_SUCCESS)
goto fail;

/* build source buffer list */
if (QAT_PHYS_CONTIG_ALLOC(&buf_list_src, src_buffer_list_mem_size) !=
CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&buf_list_src, src_buffer_list_mem_size);
if (status != CPA_STATUS_SUCCESS)
goto fail;

flat_buf_src = (CpaFlatBuffer *)(buf_list_src + 1);

buf_list_src->pBuffers = flat_buf_src; /* always point to first one */

/* build destination buffer list */
if (QAT_PHYS_CONTIG_ALLOC(&buf_list_dst, dst_buffer_list_mem_size) !=
CPA_STATUS_SUCCESS)
status = QAT_PHYS_CONTIG_ALLOC(&buf_list_dst, dst_buffer_list_mem_size);
if (status != CPA_STATUS_SUCCESS)
goto fail;

flat_buf_dst = (CpaFlatBuffer *)(buf_list_dst + 1);
Expand Down

0 comments on commit 8d26607

Please sign in to comment.