diff --git a/inc/ocf_io.h b/inc/ocf_io.h index c663645..e87ec06 100644 --- a/inc/ocf_io.h +++ b/inc/ocf_io.h @@ -337,6 +337,22 @@ void ocf_forward_write_zeros(ocf_volume_t volume, ocf_forward_token_t token, void ocf_forward_metadata(ocf_volume_t volume, ocf_forward_token_t token, int dir, uint64_t addr, uint64_t bytes, uint64_t offset); +/** + * @brief Forward io simple 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] token Forward token + * @param[in] volume Volume to which IO is being submitted + * @param[in] token Token representing IO to be forwarded + * @param[in] dir Direction OCF_READ/OCF_WRITE + * @param[in] addr Address to which IO is being submitted + * @param[in] bytes Length of the IO + */ +void ocf_forward_io_simple(ocf_volume_t volume, ocf_forward_token_t token, + int dir, uint64_t addr, uint64_t bytes); + /** * @brief Increment forwarded io refcount * diff --git a/inc/ocf_volume.h b/inc/ocf_volume.h index d3491e2..157e31d 100644 --- a/inc/ocf_volume.h +++ b/inc/ocf_volume.h @@ -143,6 +143,20 @@ struct ocf_volume_ops { int dir, uint64_t addr, uint64_t bytes, uint64_t offset); + /** + * @brief Forward the io directly to the volume in context + * where cache is not initialized yet + * + * @param[in] volume Volume to which IO is being submitted + * @param[in] token Token representing IO to be forwarded + * @param[in] dir Direction OCF_READ/OCF_WRITE + * @param[in] addr Address to which IO is being submitted + * @param[in] bytes Length of the IO + */ + void (*forward_io_simple)(ocf_volume_t volume, + ocf_forward_token_t token, int dir, + 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 8cac726..8902675 100644 --- a/src/ocf_request.c +++ b/src/ocf_request.c @@ -458,6 +458,17 @@ void ocf_req_forward_volume_discard(struct ocf_request *req, ocf_volume_forward_discard(volume, token, addr, bytes); } +void ocf_req_forward_volume_io_simple(struct ocf_request *req, + ocf_volume_t volume, int dir, uint64_t addr, uint64_t bytes) +{ + 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_io_simple(volume, token, dir, addr, bytes); +} + void ocf_req_forward_cache_io(struct ocf_request *req, int dir, uint64_t addr, uint64_t bytes, uint64_t offset) { @@ -629,6 +640,13 @@ void ocf_forward_metadata(ocf_volume_t volume, ocf_forward_token_t token, ocf_volume_forward_metadata(volume, token, dir, addr, bytes, offset); } +void ocf_forward_io_simple(ocf_volume_t volume, ocf_forward_token_t token, + int dir, uint64_t addr, uint64_t bytes) +{ + _ocf_forward_get(token); + ocf_volume_forward_io_simple(volume, token, dir, 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 97e6672..206718d 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -564,6 +564,9 @@ void ocf_req_forward_volume_flush(struct ocf_request *req, ocf_volume_t volume); void ocf_req_forward_volume_discard(struct ocf_request *req, ocf_volume_t volume, uint64_t addr, uint64_t bytes); +void ocf_req_forward_volume_io_simple(struct ocf_request *req, + ocf_volume_t volume, int dir, uint64_t addr, uint64_t bytes); + void ocf_req_forward_cache_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 6833a49..244f6a4 100644 --- a/src/ocf_volume.c +++ b/src/ocf_volume.c @@ -398,6 +398,25 @@ void ocf_volume_forward_metadata(ocf_volume_t volume, ocf_forward_token_t token, dir, addr, bytes, offset); } +void ocf_volume_forward_io_simple(ocf_volume_t volume, + ocf_forward_token_t token, int dir, + uint64_t addr, uint64_t bytes) +{ + + if (!volume->type->properties->ops.forward_io_simple) { + ocf_volume_forward_io(volume, token, dir, addr, bytes, 0); + return; + } + + if (!volume->opened) { + ocf_forward_end(token, -OCF_ERR_IO); + return; + } + + volume->type->properties->ops.forward_io_simple(volume, token, + dir, 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 3b31f39..1800518 100644 --- a/src/ocf_volume_priv.h +++ b/src/ocf_volume_priv.h @@ -61,6 +61,10 @@ void ocf_volume_forward_write_zeros(ocf_volume_t volume, void ocf_volume_forward_metadata(ocf_volume_t volume, ocf_forward_token_t token, int dir, uint64_t addr, uint64_t bytes, uint64_t offset); +void ocf_volume_forward_io_simple(ocf_volume_t volume, + ocf_forward_token_t token, int dir, + 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 a10e98a..86a888f 100644 --- a/tests/functional/pyocf/types/volume.py +++ b/tests/functional/pyocf/types/volume.py @@ -56,6 +56,7 @@ class VolumeOps(Structure): 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) FORWARD_METADATA = CFUNCTYPE(None, c_void_p, c_uint64, c_int, c_uint64, c_uint64, c_uint64) + FORWARD_IO_SIMPLE = CFUNCTYPE(None, c_void_p, c_uint64, c_int, 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) @@ -74,6 +75,7 @@ class VolumeOps(Structure): ("_forward_discard", FORWARD_DISCARD), ("_forward_write_zeros", FORWARD_WRITE_ZEROS), ("_forward_metadata", FORWARD_METADATA), + ("_forward_io_simple", FORWARD_IO_SIMPLE), ("_on_init", ON_INIT), ("_on_deinit", ON_DEINIT), ("_open", OPEN),