ocf: Add management context
Add structure vbdev_ocf_mngt_ctx that is going to be used for asynchronous management operations. Using such context, dynamic memory allocations are no longer required (except for one time poller registration) This patch also adds functions to modify context in a predictable way. They are very important for complex flow of management operations in OCF bdev especially after whole OCF API gets changed to asynchronous. Change-Id: Ia402d51665330a553f7f3d74000e3636f0d6a598 Signed-off-by: Vitaliy Mysak <vitaliy.mysak@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/449556 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
bb64a7e511
commit
25df73f5d2
@ -34,6 +34,7 @@
|
||||
#include "spdk/stdinc.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "vbdev_ocf.h"
|
||||
|
||||
static char *cache_modes[ocf_cache_mode_max] = {
|
||||
[ocf_cache_mode_wt] = "wt",
|
||||
@ -66,3 +67,71 @@ ocf_get_cache_modename(ocf_cache_mode_t mode)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mngt_poll_fn(void *opaque)
|
||||
{
|
||||
struct vbdev_ocf *vbdev = opaque;
|
||||
|
||||
if (vbdev->mngt_ctx.poller_fn) {
|
||||
vbdev->mngt_ctx.poller_fn(vbdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vbdev_ocf_mngt_start(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn *path,
|
||||
vbdev_ocf_mngt_callback cb, void *cb_arg)
|
||||
{
|
||||
if (vbdev->mngt_ctx.current_step) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
memset(&vbdev->mngt_ctx, 0, sizeof(vbdev->mngt_ctx));
|
||||
|
||||
vbdev->mngt_ctx.poller = spdk_poller_register(mngt_poll_fn, vbdev, 200);
|
||||
if (vbdev->mngt_ctx.poller == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vbdev->mngt_ctx.current_step = path;
|
||||
vbdev->mngt_ctx.cb = cb;
|
||||
vbdev->mngt_ctx.cb_arg = cb_arg;
|
||||
|
||||
(*vbdev->mngt_ctx.current_step)(vbdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
vbdev_ocf_mngt_poll(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn fn)
|
||||
{
|
||||
assert(vbdev->mngt_ctx.poller != NULL);
|
||||
vbdev->mngt_ctx.poller_fn = fn;
|
||||
}
|
||||
|
||||
void
|
||||
vbdev_ocf_mngt_continue(struct vbdev_ocf *vbdev, int status)
|
||||
{
|
||||
if (vbdev->mngt_ctx.current_step == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert((*vbdev->mngt_ctx.current_step) != NULL);
|
||||
|
||||
vbdev->mngt_ctx.status = status;
|
||||
vbdev->mngt_ctx.poller_fn = NULL;
|
||||
|
||||
vbdev->mngt_ctx.current_step++;
|
||||
if (*vbdev->mngt_ctx.current_step) {
|
||||
(*vbdev->mngt_ctx.current_step)(vbdev);
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_poller_unregister(&vbdev->mngt_ctx.poller);
|
||||
if (vbdev->mngt_ctx.cb) {
|
||||
vbdev->mngt_ctx.cb(vbdev->mngt_ctx.status, vbdev->mngt_ctx.cb_arg);
|
||||
}
|
||||
memset(&vbdev->mngt_ctx, 0, sizeof(vbdev->mngt_ctx));
|
||||
}
|
||||
|
@ -35,8 +35,25 @@
|
||||
#define VBDEV_OCF_UTILS_H
|
||||
|
||||
#include <ocf/ocf.h>
|
||||
#include "vbdev_ocf.h"
|
||||
|
||||
ocf_cache_mode_t ocf_get_cache_mode(const char *cache_mode);
|
||||
const char *ocf_get_cache_modename(ocf_cache_mode_t mode);
|
||||
|
||||
/* Initiate management operation
|
||||
* Receives NULL terminated array of functions (path)
|
||||
* and callback (cb)
|
||||
* and callback argument (cb_arg)
|
||||
* This function may fail with ENOMEM or EBUSY */
|
||||
int vbdev_ocf_mngt_start(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn *path,
|
||||
vbdev_ocf_mngt_callback cb, void *cb_arg);
|
||||
|
||||
/* Continue execution with polling operation (fn)
|
||||
* fn must invoke vbdev_ocf_mngt_continue() to stop polling */
|
||||
void vbdev_ocf_mngt_poll(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn fn);
|
||||
|
||||
/* Continue execution with next function that is on path
|
||||
* If next function is NULL, finish management operation and invoke callback */
|
||||
void vbdev_ocf_mngt_continue(struct vbdev_ocf *vbdev, int status);
|
||||
|
||||
#endif
|
||||
|
@ -81,6 +81,31 @@ struct vbdev_ocf_config {
|
||||
struct ocf_mngt_core_config core;
|
||||
};
|
||||
|
||||
/* Types for management operations */
|
||||
typedef void (*vbdev_ocf_mngt_fn)(struct vbdev_ocf *);
|
||||
typedef void (*vbdev_ocf_mngt_callback)(int, void *);
|
||||
|
||||
/* Context for asynchronous management operations
|
||||
* Single management operation usually contains a list of sub procedures,
|
||||
* this structure handles sharing between those sub procedures */
|
||||
struct vbdev_ocf_mngt_ctx {
|
||||
/* Pointer to function that is currently being executed
|
||||
* It gets incremented on each step until it dereferences to NULL */
|
||||
vbdev_ocf_mngt_fn *current_step;
|
||||
|
||||
/* Poller, registered once per whole management operation */
|
||||
struct spdk_poller *poller;
|
||||
/* Function that gets invoked by poller on each iteration */
|
||||
vbdev_ocf_mngt_fn poller_fn;
|
||||
|
||||
/* Status of management operation */
|
||||
int status;
|
||||
|
||||
/* External callback and its argument */
|
||||
vbdev_ocf_mngt_callback cb;
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
/* Base device info */
|
||||
struct vbdev_ocf_base {
|
||||
/* OCF unique internal id */
|
||||
@ -125,6 +150,9 @@ struct vbdev_ocf {
|
||||
struct vbdev_ocf_config cfg;
|
||||
struct vbdev_ocf_state state;
|
||||
|
||||
/* Management context */
|
||||
struct vbdev_ocf_mngt_ctx mngt_ctx;
|
||||
|
||||
/* Exposed SPDK bdev. Registered in bdev layer */
|
||||
struct spdk_bdev exp_bdev;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user