From cd544e8ee506ba9a8b3e0746241a311f2e20cbfa Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Fri, 13 Oct 2023 12:51:33 +0200 Subject: [PATCH] Introduce ocf_forward_write_zeros() This is meant to be used in atomic mode to avoid allocating huge buffers for zeroing data on drive. Signed-off-by: Robert Baldyga Signed-off-by: Michal Mielewczyk --- inc/ocf_io.h | 14 ++++++++++++++ inc/ocf_volume.h | 13 +++++++++++++ src/ocf_request.c | 19 +++++++++++++++++++ src/ocf_request.h | 3 +++ src/ocf_volume.c | 14 ++++++++++++++ src/ocf_volume_priv.h | 3 +++ tests/functional/pyocf/types/volume.py | 2 ++ 7 files changed, 68 insertions(+) diff --git a/inc/ocf_io.h b/inc/ocf_io.h index e7ff2b5..467eaa9 100644 --- a/inc/ocf_io.h +++ b/inc/ocf_io.h @@ -285,6 +285,20 @@ void ocf_forward_flush(ocf_volume_t volume, ocf_forward_token_t token); void ocf_forward_discard(ocf_volume_t volume, ocf_forward_token_t token, uint64_t addr, uint64_t bytes); +/** + * @brief Forward write_zeros to another subvolume + * + * Forwarding automatically increases forwarded io refcount, so at some + * point additional ocf_forward_end() needs to be called to balance it. + * + * @param[in] volume Volume to which IO is being submitted + * @param[in] token Token representing IO to be forwarded + * @param[in] addr Address to which IO is being submitted + * @param[in] bytes Length of the IO + */ +void ocf_forward_write_zeros(ocf_volume_t volume, ocf_forward_token_t token, + uint64_t addr, uint64_t bytes); + /** * @brief Increment forwarded io refcount * diff --git a/inc/ocf_volume.h b/inc/ocf_volume.h index 7a2f9a2..85f8d9b 100644 --- a/inc/ocf_volume.h +++ b/inc/ocf_volume.h @@ -116,6 +116,19 @@ struct ocf_volume_ops { void (*forward_discard)(ocf_volume_t volume, ocf_forward_token_t token, uint64_t addr, uint64_t bytes); + /** + * @brief Froward operation to write zeros to target address (including + * metadata extended LBAs in atomic mode) + * + * @param[in] volume Volume to which IO is being submitted + * @param[in] token Token representing IO to be forwarded + * @param[in] addr Address to which IO is being submitted + * @param[in] bytes Length of the IO + */ + void (*forward_write_zeros)(ocf_volume_t volume, + ocf_forward_token_t token, uint64_t addr, + uint64_t bytes); + /** * @brief Volume initialization callback, called when volume object * is being initialized diff --git a/src/ocf_request.c b/src/ocf_request.c index 82c75f8..0b8a7be 100644 --- a/src/ocf_request.c +++ b/src/ocf_request.c @@ -467,6 +467,18 @@ void ocf_req_forward_cache_discard(struct ocf_request *req, uint64_t addr, ocf_volume_forward_discard(volume, token, addr, bytes); } +void ocf_req_forward_cache_write_zeros(struct ocf_request *req, uint64_t addr, + uint64_t bytes) +{ + ocf_volume_t volume = ocf_cache_get_volume(req->cache); + ocf_forward_token_t token = ocf_req_to_cache_forward_token(req); + + req->cache_error = 0; + + ocf_req_forward_cache_get(req); + ocf_volume_forward_write_zeros(volume, token, addr, bytes); +} + void ocf_req_forward_core_io(struct ocf_request *req, int dir, uint64_t addr, uint64_t bytes, uint64_t offset) { @@ -544,6 +556,13 @@ void ocf_forward_discard(ocf_volume_t volume, ocf_forward_token_t token, ocf_volume_forward_discard(volume, token, addr, bytes); } +void ocf_forward_write_zeros(ocf_volume_t volume, ocf_forward_token_t token, + uint64_t addr, uint64_t bytes) +{ + _ocf_forward_get(token); + ocf_volume_forward_write_zeros(volume, token, addr, bytes); +} + void ocf_forward_end(ocf_forward_token_t token, int error) { struct ocf_request *req = ocf_req_forward_token_to_req(token); diff --git a/src/ocf_request.h b/src/ocf_request.h index 6fd5c2e..a3ad3d7 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -561,6 +561,9 @@ void ocf_req_forward_cache_flush(struct ocf_request *req); void ocf_req_forward_cache_discard(struct ocf_request *req, uint64_t addr, uint64_t bytes); +void ocf_req_forward_cache_write_zeros(struct ocf_request *req, uint64_t addr, + uint64_t bytes); + void ocf_req_forward_core_io(struct ocf_request *req, int dir, uint64_t addr, uint64_t bytes, uint64_t offset); diff --git a/src/ocf_volume.c b/src/ocf_volume.c index 143fd03..2ec2890 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -370,6 +370,20 @@ void ocf_volume_forward_discard(ocf_volume_t volume, ocf_forward_token_t token, addr, bytes); } +void ocf_volume_forward_write_zeros(ocf_volume_t volume, + ocf_forward_token_t token, uint64_t addr, uint64_t bytes) +{ + ENV_BUG_ON(!volume->type->properties->ops.forward_write_zeros); + + if (!volume->opened) { + ocf_forward_end(token, -OCF_ERR_IO); + return; + } + + volume->type->properties->ops.forward_write_zeros(volume, token, + addr, bytes); +} + int ocf_volume_open(ocf_volume_t volume, void *volume_params) { int ret; diff --git a/src/ocf_volume_priv.h b/src/ocf_volume_priv.h index d5942d9..4b730fc 100644 --- a/src/ocf_volume_priv.h +++ b/src/ocf_volume_priv.h @@ -55,6 +55,9 @@ void ocf_volume_forward_flush(ocf_volume_t volume, ocf_forward_token_t token); void ocf_volume_forward_discard(ocf_volume_t volume, ocf_forward_token_t token, uint64_t addr, uint64_t bytes); +void ocf_volume_forward_write_zeros(ocf_volume_t volume, + ocf_forward_token_t token, uint64_t addr, uint64_t bytes); + static inline void ocf_volume_submit_metadata(struct ocf_io *io) { ocf_volume_t volume = ocf_io_get_volume(io); diff --git a/tests/functional/pyocf/types/volume.py b/tests/functional/pyocf/types/volume.py index 858e289..4f6badb 100644 --- a/tests/functional/pyocf/types/volume.py +++ b/tests/functional/pyocf/types/volume.py @@ -54,6 +54,7 @@ class VolumeOps(Structure): FORWARD_IO = CFUNCTYPE(None, c_void_p, c_uint64, c_int, c_uint64, c_uint64, c_uint64) FORWARD_FLUSH = CFUNCTYPE(None, c_void_p, c_uint64) FORWARD_DISCARD = CFUNCTYPE(None, c_void_p, c_uint64, c_uint64, c_uint64) + FORWARD_WRITE_ZEROS = CFUNCTYPE(None, c_void_p, c_uint64, c_uint64, c_uint64) ON_INIT = CFUNCTYPE(c_int, c_void_p) ON_DEINIT = CFUNCTYPE(None, c_void_p) OPEN = CFUNCTYPE(c_int, c_void_p, c_void_p) @@ -70,6 +71,7 @@ class VolumeOps(Structure): ("_forward_io", FORWARD_IO), ("_forward_flush", FORWARD_FLUSH), ("_forward_discard", FORWARD_DISCARD), + ("_forward_write_zeros", FORWARD_WRITE_ZEROS), ("_on_init", ON_INIT), ("_on_deinit", ON_DEINIT), ("_open", OPEN),