From 73387c8f2682f290a38c77f8325f3af72945d8b4 Mon Sep 17 00:00:00 2001 From: Roel Apfelbaum Date: Wed, 21 Jun 2023 05:51:09 -0400 Subject: [PATCH] Support set_data() with offset > 0 for core Signed-off-by: Roel Apfelbaum Signed-off-by: Michal Mielewczyk --- src/engine/engine_discard.c | 2 +- src/ocf_core.c | 3 +- src/ocf_request.h | 3 + src/utils/utils_io.c | 8 ++- tests/functional/tests/basic/test_offset.py | 74 +++++++++++++++++++++ 5 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 tests/functional/tests/basic/test_offset.py diff --git a/src/engine/engine_discard.c b/src/engine/engine_discard.c index bcef8c5..b270de9 100644 --- a/src/engine/engine_discard.c +++ b/src/engine/engine_discard.c @@ -51,7 +51,7 @@ static int _ocf_discard_core(struct ocf_request *req) } ocf_io_set_cmpl(io, req, NULL, _ocf_discard_core_complete); - err = ocf_io_set_data(io, req->data, 0); + err = ocf_io_set_data(io, req->data, req->offset); if (err) { _ocf_discard_core_complete(io, err); return err; diff --git a/src/ocf_core.c b/src/ocf_core.c index ee88efa..89ab195 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -438,11 +438,12 @@ static int ocf_core_io_set_data(struct ocf_io *io, OCF_CHECK_NULL(io); - if (!data || offset) + if (!data) return -OCF_ERR_INVAL; req = ocf_io_to_req(io); req->data = data; + req->offset = offset; return 0; } diff --git a/src/ocf_request.h b/src/ocf_request.h index 2872a8b..3ea539f 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -186,6 +186,9 @@ struct ocf_request { uint32_t alloc_core_line_count; /*! Number of core lines at time of request allocation */ + uint32_t offset; + /*!< Offset into request data*/ + int error; /*!< This filed indicates an error for OCF request */ diff --git a/src/utils/utils_io.c b/src/utils/utils_io.c index f33ffb8..4d34131 100644 --- a/src/utils/utils_io.c +++ b/src/utils/utils_io.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -273,7 +274,7 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); - err = ocf_io_set_data(io, req->data, offset); + err = ocf_io_set_data(io, req->data, req->offset + offset); if (err) { ocf_io_put(io); callback(req, err); @@ -322,7 +323,8 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); - err = ocf_io_set_data(io, req->data, offset + total_bytes); + err = ocf_io_set_data(io, req->data, + req->offset + offset + total_bytes); if (err) { ocf_io_put(io); /* Finish all IOs which left with ERROR */ @@ -359,7 +361,7 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req, } ocf_io_set_cmpl(io, req, callback, ocf_submit_volume_req_cmpl); - err = ocf_io_set_data(io, req->data, 0); + err = ocf_io_set_data(io, req->data, req->offset); if (err) { ocf_io_put(io); callback(req, err); diff --git a/tests/functional/tests/basic/test_offset.py b/tests/functional/tests/basic/test_offset.py new file mode 100644 index 0000000..2276bad --- /dev/null +++ b/tests/functional/tests/basic/test_offset.py @@ -0,0 +1,74 @@ +# +# Copyright(c) 2024 Huawei Technologies +# SPDX-License-Identifier: BSD-3-Clause +# + +from pyocf.types.cache import Cache +from pyocf.types.core import Core +from pyocf.types.data import Data, DataSeek +from pyocf.types.io import IoDir, Sync +from pyocf.types.volume import RamVolume +from pyocf.types.volume_core import CoreVolume +from pyocf.utils import Size + + +def test_data_with_offset(pyocf_ctx): + cache_device = RamVolume(Size.from_MiB(50)) + core_device = RamVolume(Size.from_MiB(50)) + + cache = Cache.start_on_device(cache_device) + core = Core.using_device(core_device) + queue = cache.get_default_queue() + + cache.add_core(core) + core_volume = CoreVolume(core) + core_volume.open() + + # Populate core backend volume + CL = cache.cache_line_size + data_1 = Data(CL) + for addr in range(0, CL, Size._SECTOR_SIZE): + data_1.seek(DataSeek.BEGIN, addr) + data_1.write(b"I\x00\x00\x00\x00", 5) + core_device.sync_io(queue, CL * 0, data_1, IoDir.WRITE) + core_device.sync_io(queue, CL * 1, data_1, IoDir.WRITE) + core_device.sync_io(queue, CL * 2, data_1, IoDir.WRITE) + core_device.sync_io(queue, CL * 3, data_1, IoDir.WRITE) + + # write using data with offset + B1 = b"12345" + B2 = b"67890" + data = Data(8192) + data.seek(DataSeek.BEGIN, 0) + data.write(B1, len(B1)) + data.seek(DataSeek.BEGIN, 4096) + data.write(B2, len(B2)) + + address = CL + length = CL + offset = CL + io = core_volume.new_io(queue, address, length, IoDir.WRITE, 0, 0) + io.set_data(data, offset) + Sync(io).submit() + + s = core_device.read_sync(queue, 0, 2 * CL) + for addr in range(0, CL, Size._SECTOR_SIZE): + assert chr(s[addr]) == "I", f"addr {addr}" + assert s[CL:CL + len(B2)] == B2 + + s = core_volume.read_sync(queue, 0, 2 * CL) + for addr in range(0, CL, Size._SECTOR_SIZE): + assert chr(s[addr]) == "I", f"addr {addr}" + assert s[CL:CL + len(B2)] == B2 + + # read using data with offset + data1 = Data(10000) + offset1 = 10 + io1 = core_volume.new_io(queue, address, length, IoDir.READ, 0, 0) + io1.set_data(data1, offset1) + Sync(io1).submit() + + s0 = data1.buffer[:offset1] + assert s0 == bytes([Data.DATA_POISON] * offset1) + s1 = data1.buffer[offset1:(offset1 + len(B2))] + assert s1 == B2