Parametrize pipeline steps

This allows to reuse same step functions giving them different parameters
on each step.

Additionally move pipeline to utils, to make it accessible to other
subsystems of OCF (e.g. metadata).

Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
Robert Baldyga
2019-03-18 09:34:13 +01:00
parent 7a3b3fd84f
commit 23b0a32aec
7 changed files with 576 additions and 365 deletions

View File

@@ -458,83 +458,3 @@ int ocf_mngt_cache_visit_reverse(ocf_ctx_t ocf_ctx,
return result;
}
struct ocf_mngt_pipeline {
ocf_mngt_pipeline_step_t *steps;
int next_step;
ocf_mngt_pipeline_end_t cmpl;
struct ocf_request *req;
bool finish;
int error;
void *priv;
};
static int _ocf_mngt_pipeline_run_step(struct ocf_request *req)
{
ocf_mngt_pipeline_t pipeline = req->priv;
if (pipeline->steps[pipeline->next_step] && !pipeline->finish)
pipeline->steps[pipeline->next_step++](pipeline, pipeline->priv);
else
pipeline->cmpl(pipeline, pipeline->priv, pipeline->error);
return 0;
}
static const struct ocf_io_if _io_if_pipeline = {
.read = _ocf_mngt_pipeline_run_step,
.write = _ocf_mngt_pipeline_run_step,
};
int ocf_mngt_pipeline_create(ocf_mngt_pipeline_t *pipeline, ocf_cache_t cache,
ocf_mngt_pipeline_step_t *steps, ocf_mngt_pipeline_end_t cmpl,
void *priv)
{
ocf_mngt_pipeline_t tmp_pipeline;
struct ocf_request *req;
tmp_pipeline = env_vzalloc(sizeof(struct ocf_mngt_pipeline));
if (!tmp_pipeline)
return -OCF_ERR_NO_MEM;
req = ocf_req_new(cache->mngt_queue, NULL, 0, 0, 0);
if (!req) {
env_vfree(tmp_pipeline);
return -OCF_ERR_NO_MEM;
}
tmp_pipeline->steps = steps;
tmp_pipeline->next_step = 0;
tmp_pipeline->cmpl = cmpl;
tmp_pipeline->req = req;
tmp_pipeline->finish = false;
tmp_pipeline->error = 0;
tmp_pipeline->priv = priv;
req->info.internal = true;
req->io_if = &_io_if_pipeline;
req->priv = tmp_pipeline;
*pipeline = tmp_pipeline;
return 0;
}
void ocf_mngt_pipeline_destroy(ocf_mngt_pipeline_t pipeline)
{
ocf_req_put(pipeline->req);
env_vfree(pipeline);
}
void ocf_mngt_pipeline_next(ocf_mngt_pipeline_t pipeline)
{
ocf_engine_push_req_front(pipeline->req, true);
}
void ocf_mngt_pipeline_finish(ocf_mngt_pipeline_t pipeline, int error)
{
pipeline->finish = true;
pipeline->error = error;
ocf_engine_push_req_front(pipeline->req, true);
}