From b9bc6254a8bec7ba233a9a454302a87f17f3142d Mon Sep 17 00:00:00 2001 From: paul luse Date: Tue, 9 Jul 2019 11:44:03 -0400 Subject: [PATCH] lib/reduce: fix critical issue with reduce optimization The first optimization to eliminate memcpy was too aggressive and did so for the read-modify-write operation as well. This didn't affect the fio tests used that the time but bdevio catches it right away. When over writing a chunk with data, we first need to read the old data before applying the new. This patch uses the scratch buffer for old data as sending it to the user buffer results in it not being written at the end of the read-modify-write. There is at least one more bug fix coming after this also found with bdevio but passed with fio Signed-off-by: paul luse Change-Id: I8fe074056434bb4757c68077e2df446861edfd94 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/461032 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto --- lib/reduce/reduce.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/reduce/reduce.c b/lib/reduce/reduce.c index f1136af61..4be7adfd5 100644 --- a/lib/reduce/reduce.c +++ b/lib/reduce/reduce.c @@ -1063,6 +1063,22 @@ _reduce_vol_compress_chunk(struct spdk_reduce_vol_request *req, reduce_request_f &req->backing_cb_args); } +static void +_reduce_vol_decompress_chunk_scratch(struct spdk_reduce_vol_request *req, reduce_request_fn next_fn) +{ + struct spdk_reduce_vol *vol = req->vol; + + req->backing_cb_args.cb_fn = next_fn; + req->backing_cb_args.cb_arg = req; + req->comp_buf_iov[0].iov_base = req->comp_buf; + req->comp_buf_iov[0].iov_len = req->chunk->compressed_size; + req->decomp_buf_iov[0].iov_base = req->decomp_buf; + req->decomp_buf_iov[0].iov_len = vol->params.chunk_size; + vol->backing_dev->decompress(vol->backing_dev, + req->comp_buf_iov, 1, req->decomp_buf_iov, 1, + &req->backing_cb_args); +} + static void _reduce_vol_decompress_chunk(struct spdk_reduce_vol_request *req, reduce_request_fn next_fn) { @@ -1180,7 +1196,7 @@ _write_read_done(void *_req, int reduce_errno) } if (req->chunk_is_compressed) { - _reduce_vol_decompress_chunk(req, _write_decompress_done); + _reduce_vol_decompress_chunk_scratch(req, _write_decompress_done); } else { _write_decompress_done(req, req->chunk->compressed_size); }