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 <paul.e.luse@intel.com>
Change-Id: I8fe074056434bb4757c68077e2df446861edfd94
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/461032
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
paul luse 2019-07-09 11:44:03 -04:00 committed by Darek Stojaczyk
parent b860c8dbce
commit b9bc6254a8

View File

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