Fix ops(flush) engine

Flush I/O should be forwarded to core and cache device. In case of core
this is simple - just mirror the I/O from the top volume. Since
cache data is owned by OCF it makes sense to send a simple flush I/O
with 0 address and size.

Current implementation attempts to use cache data I/O interface
(ocf_submit_cache_reqs function) instead of submitting empty flush to
the underlying cache device. This function is designed to read/write
from mapped cachelines while there is no traversation/mapping
performed on flush I/O.

If request map allocation succeeds, this results in sending I/O to
addres 0 with size and flags inherited from the top adapter I/O.
This doesn't make any sense, and can even result in invalid I/O if the
size is greater than cache device size.

Even worse, if flush request map allocation fails (which happens
always in case of large flush requests) then the erroneous call to
ocf_submit_cache_reqs results in NULL pointer dereference.

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski
2022-05-16 14:16:36 +02:00
parent 8e16a26b6a
commit df7ed6920c
3 changed files with 24 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright(c) 2012-2021 Intel Corporation
* Copyright(c) 2012-2022 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "ocf/ocf.h"
@@ -37,10 +37,6 @@ static void _ocf_engine_ops_complete(struct ocf_request *req, int error)
int ocf_engine_ops(struct ocf_request *req)
{
struct ocf_cache *cache = req->cache;
OCF_DEBUG_TRACE(req->cache);
/* Get OCF request - increase reference counter */
ocf_req_get(req);
@@ -51,8 +47,9 @@ int ocf_engine_ops(struct ocf_request *req)
ocf_submit_volume_req(&req->core->volume, req,
_ocf_engine_ops_complete);
ocf_submit_cache_reqs(cache, req, req->rw, 0, req->byte_length,
1, _ocf_engine_ops_complete);
/* submit flush to cache device */
ocf_submit_cache_flush(req, _ocf_engine_ops_complete);
/* Put OCF request - decrease reference counter */
ocf_req_put(req);