1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse * Copyright (C) 2018 Intel Corporation.
307fe6a43SSeth Howell * All rights reserved.
407fe6a43SSeth Howell */
507fe6a43SSeth Howell
607fe6a43SSeth Howell #include "vbdev_ocf.h"
707fe6a43SSeth Howell #include "stats.h"
85bdaec63SRafal Stefanowski #include "utils.h"
907fe6a43SSeth Howell #include "spdk/log.h"
1007fe6a43SSeth Howell #include "spdk/rpc.h"
1107fe6a43SSeth Howell #include "spdk/string.h"
1207fe6a43SSeth Howell
136ee39210SRafal Stefanowski /* Common structure to hold the name parameter for RPC methods using bdev name only. */
146ee39210SRafal Stefanowski struct rpc_bdev_ocf_name {
156ee39210SRafal Stefanowski char *name; /* main vbdev name */
166ee39210SRafal Stefanowski };
176ee39210SRafal Stefanowski
186ee39210SRafal Stefanowski /* Common free function for RPC methods using bdev name only. */
196ee39210SRafal Stefanowski static void
free_rpc_bdev_ocf_name(struct rpc_bdev_ocf_name * r)206ee39210SRafal Stefanowski free_rpc_bdev_ocf_name(struct rpc_bdev_ocf_name *r)
216ee39210SRafal Stefanowski {
226ee39210SRafal Stefanowski free(r->name);
236ee39210SRafal Stefanowski }
246ee39210SRafal Stefanowski
256ee39210SRafal Stefanowski /* Common function to decode the name input parameter for RPC methods using bdev name only. */
266ee39210SRafal Stefanowski static const struct spdk_json_object_decoder rpc_bdev_ocf_name_decoders[] = {
276ee39210SRafal Stefanowski {"name", offsetof(struct rpc_bdev_ocf_name, name), spdk_json_decode_string},
286ee39210SRafal Stefanowski };
296ee39210SRafal Stefanowski
306ee39210SRafal Stefanowski
3107fe6a43SSeth Howell /* Structure to hold the parameters for this RPC method. */
32557f8ff9SPawel Kaminski struct rpc_bdev_ocf_create {
330130905aSJim Harris char *name; /* main vbdev */
3407fe6a43SSeth Howell char *mode; /* OCF mode (choose one) */
354d91b4efSrafalste uint64_t cache_line_size; /* OCF cache line size */
3607fe6a43SSeth Howell char *cache_bdev_name; /* sub bdev */
3707fe6a43SSeth Howell char *core_bdev_name; /* sub bdev */
3807fe6a43SSeth Howell };
3907fe6a43SSeth Howell
4007fe6a43SSeth Howell static void
free_rpc_bdev_ocf_create(struct rpc_bdev_ocf_create * r)41557f8ff9SPawel Kaminski free_rpc_bdev_ocf_create(struct rpc_bdev_ocf_create *r)
4207fe6a43SSeth Howell {
4307fe6a43SSeth Howell free(r->name);
4407fe6a43SSeth Howell free(r->core_bdev_name);
4507fe6a43SSeth Howell free(r->cache_bdev_name);
4607fe6a43SSeth Howell free(r->mode);
4707fe6a43SSeth Howell }
4807fe6a43SSeth Howell
4907fe6a43SSeth Howell /* Structure to decode the input parameters for this RPC method. */
50557f8ff9SPawel Kaminski static const struct spdk_json_object_decoder rpc_bdev_ocf_create_decoders[] = {
51557f8ff9SPawel Kaminski {"name", offsetof(struct rpc_bdev_ocf_create, name), spdk_json_decode_string},
52557f8ff9SPawel Kaminski {"mode", offsetof(struct rpc_bdev_ocf_create, mode), spdk_json_decode_string},
534d91b4efSrafalste {"cache_line_size", offsetof(struct rpc_bdev_ocf_create, cache_line_size), spdk_json_decode_uint64, true},
54557f8ff9SPawel Kaminski {"cache_bdev_name", offsetof(struct rpc_bdev_ocf_create, cache_bdev_name), spdk_json_decode_string},
55557f8ff9SPawel Kaminski {"core_bdev_name", offsetof(struct rpc_bdev_ocf_create, core_bdev_name), spdk_json_decode_string},
5607fe6a43SSeth Howell };
5707fe6a43SSeth Howell
5807fe6a43SSeth Howell static void
construct_cb(int status,struct vbdev_ocf * vbdev,void * cb_arg)5907fe6a43SSeth Howell construct_cb(int status, struct vbdev_ocf *vbdev, void *cb_arg)
6007fe6a43SSeth Howell {
6107fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg;
6207fe6a43SSeth Howell struct spdk_json_write_ctx *w;
6307fe6a43SSeth Howell
6407fe6a43SSeth Howell if (status) {
6507fe6a43SSeth Howell spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
6607fe6a43SSeth Howell "Could not create OCF vbdev: %d",
6707fe6a43SSeth Howell status);
6807fe6a43SSeth Howell } else {
6907fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request);
7007fe6a43SSeth Howell spdk_json_write_string(w, vbdev->name);
7107fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w);
7207fe6a43SSeth Howell }
7307fe6a43SSeth Howell }
7407fe6a43SSeth Howell
7507fe6a43SSeth Howell static void
rpc_bdev_ocf_create(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)7664807a1aSSeth Howell rpc_bdev_ocf_create(struct spdk_jsonrpc_request *request,
7707fe6a43SSeth Howell const struct spdk_json_val *params)
7807fe6a43SSeth Howell {
79557f8ff9SPawel Kaminski struct rpc_bdev_ocf_create req = {NULL};
8007fe6a43SSeth Howell int ret;
8107fe6a43SSeth Howell
82557f8ff9SPawel Kaminski ret = spdk_json_decode_object(params, rpc_bdev_ocf_create_decoders,
83557f8ff9SPawel Kaminski SPDK_COUNTOF(rpc_bdev_ocf_create_decoders),
8407fe6a43SSeth Howell &req);
8507fe6a43SSeth Howell if (ret) {
8607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
8707fe6a43SSeth Howell "Invalid parameters");
88557f8ff9SPawel Kaminski free_rpc_bdev_ocf_create(&req);
8907fe6a43SSeth Howell return;
9007fe6a43SSeth Howell }
9107fe6a43SSeth Howell
924d91b4efSrafalste vbdev_ocf_construct(req.name, req.mode, req.cache_line_size, req.cache_bdev_name,
934d91b4efSrafalste req.core_bdev_name, false, construct_cb, request);
94557f8ff9SPawel Kaminski free_rpc_bdev_ocf_create(&req);
9507fe6a43SSeth Howell }
9664807a1aSSeth Howell SPDK_RPC_REGISTER("bdev_ocf_create", rpc_bdev_ocf_create, SPDK_RPC_RUNTIME)
9707fe6a43SSeth Howell
9807fe6a43SSeth Howell static void
delete_cb(void * cb_arg,int status)9907fe6a43SSeth Howell delete_cb(void *cb_arg, int status)
10007fe6a43SSeth Howell {
10107fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg;
10207fe6a43SSeth Howell
10307fe6a43SSeth Howell if (status) {
10407fe6a43SSeth Howell spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
10507fe6a43SSeth Howell "Could not delete OCF vbdev: %d",
10607fe6a43SSeth Howell status);
10707fe6a43SSeth Howell } else {
108d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true);
10907fe6a43SSeth Howell }
11007fe6a43SSeth Howell }
11107fe6a43SSeth Howell
11207fe6a43SSeth Howell static void
rpc_bdev_ocf_delete(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)11364807a1aSSeth Howell rpc_bdev_ocf_delete(struct spdk_jsonrpc_request *request,
11407fe6a43SSeth Howell const struct spdk_json_val *params)
11507fe6a43SSeth Howell {
1166ee39210SRafal Stefanowski struct rpc_bdev_ocf_name req = {NULL};
11707fe6a43SSeth Howell struct vbdev_ocf *vbdev;
11807fe6a43SSeth Howell int status;
11907fe6a43SSeth Howell
1206ee39210SRafal Stefanowski status = spdk_json_decode_object(params, rpc_bdev_ocf_name_decoders,
1216ee39210SRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_name_decoders),
12207fe6a43SSeth Howell &req);
12307fe6a43SSeth Howell if (status) {
12407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
12507fe6a43SSeth Howell "Invalid parameters");
12607fe6a43SSeth Howell goto end;
12707fe6a43SSeth Howell }
12807fe6a43SSeth Howell
12907fe6a43SSeth Howell vbdev = vbdev_ocf_get_by_name(req.name);
13007fe6a43SSeth Howell if (vbdev == NULL) {
13107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
13207fe6a43SSeth Howell spdk_strerror(ENODEV));
13307fe6a43SSeth Howell goto end;
13407fe6a43SSeth Howell }
13507fe6a43SSeth Howell
1361ee2e81bSMarcin Dziegielewski status = vbdev_ocf_delete_clean(vbdev, delete_cb, request);
13707fe6a43SSeth Howell if (status) {
13807fe6a43SSeth Howell spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
13907fe6a43SSeth Howell "Could not delete OCF vbdev: %s",
14007fe6a43SSeth Howell spdk_strerror(-status));
14107fe6a43SSeth Howell goto end;
14207fe6a43SSeth Howell }
14307fe6a43SSeth Howell
14407fe6a43SSeth Howell end:
1456ee39210SRafal Stefanowski free_rpc_bdev_ocf_name(&req);
14607fe6a43SSeth Howell }
14764807a1aSSeth Howell SPDK_RPC_REGISTER("bdev_ocf_delete", rpc_bdev_ocf_delete, SPDK_RPC_RUNTIME)
14807fe6a43SSeth Howell
14920894340SMarcin Dziegielewski struct get_ocf_stats_ctx {
15020894340SMarcin Dziegielewski struct spdk_jsonrpc_request *request;
151d7a3a052SVitaliy Mysak char *core_name;
15220894340SMarcin Dziegielewski };
15320894340SMarcin Dziegielewski
15420894340SMarcin Dziegielewski static void
rpc_bdev_ocf_get_stats_cmpl(ocf_cache_t cache,void * priv,int error)15564807a1aSSeth Howell rpc_bdev_ocf_get_stats_cmpl(ocf_cache_t cache, void *priv, int error)
15620894340SMarcin Dziegielewski {
15720894340SMarcin Dziegielewski struct get_ocf_stats_ctx *ctx = (struct get_ocf_stats_ctx *) priv;
15820894340SMarcin Dziegielewski struct spdk_json_write_ctx *w;
15920894340SMarcin Dziegielewski struct vbdev_ocf_stats stats;
16020894340SMarcin Dziegielewski
16120894340SMarcin Dziegielewski if (error) {
16220894340SMarcin Dziegielewski goto end;
16320894340SMarcin Dziegielewski }
16420894340SMarcin Dziegielewski
165d7a3a052SVitaliy Mysak error = vbdev_ocf_stats_get(cache, ctx->core_name, &stats);
16620894340SMarcin Dziegielewski
16720894340SMarcin Dziegielewski ocf_mngt_cache_read_unlock(cache);
16820894340SMarcin Dziegielewski
16920894340SMarcin Dziegielewski if (error) {
17020894340SMarcin Dziegielewski goto end;
17120894340SMarcin Dziegielewski }
17220894340SMarcin Dziegielewski
17320894340SMarcin Dziegielewski w = spdk_jsonrpc_begin_result(ctx->request);
17420894340SMarcin Dziegielewski vbdev_ocf_stats_write_json(w, &stats);
17520894340SMarcin Dziegielewski spdk_jsonrpc_end_result(ctx->request, w);
17620894340SMarcin Dziegielewski
17720894340SMarcin Dziegielewski end:
17820894340SMarcin Dziegielewski if (error) {
17920894340SMarcin Dziegielewski spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
18020894340SMarcin Dziegielewski "Could not get stats: %s",
18120894340SMarcin Dziegielewski spdk_strerror(-error));
18220894340SMarcin Dziegielewski }
18320894340SMarcin Dziegielewski free(ctx);
18420894340SMarcin Dziegielewski }
18520894340SMarcin Dziegielewski
18607fe6a43SSeth Howell static void
rpc_bdev_ocf_get_stats(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)18764807a1aSSeth Howell rpc_bdev_ocf_get_stats(struct spdk_jsonrpc_request *request,
18895482c54SPawel Kaminski const struct spdk_json_val *params)
18907fe6a43SSeth Howell {
1906ee39210SRafal Stefanowski struct rpc_bdev_ocf_name req = {NULL};
19107fe6a43SSeth Howell struct vbdev_ocf *vbdev;
19220894340SMarcin Dziegielewski struct get_ocf_stats_ctx *ctx;
19320894340SMarcin Dziegielewski
19420894340SMarcin Dziegielewski ctx = calloc(1, sizeof(*ctx));
19520894340SMarcin Dziegielewski if (!ctx) {
19620894340SMarcin Dziegielewski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
19720894340SMarcin Dziegielewski "Not enough memory to process request");
19820894340SMarcin Dziegielewski goto end;
19920894340SMarcin Dziegielewski }
20007fe6a43SSeth Howell
2016ee39210SRafal Stefanowski if (spdk_json_decode_object(params, rpc_bdev_ocf_name_decoders,
2026ee39210SRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_name_decoders),
20307fe6a43SSeth Howell &req)) {
20407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
20507fe6a43SSeth Howell "Invalid parameters");
20620894340SMarcin Dziegielewski free(ctx);
20707fe6a43SSeth Howell goto end;
20807fe6a43SSeth Howell }
20907fe6a43SSeth Howell
21007fe6a43SSeth Howell vbdev = vbdev_ocf_get_by_name(req.name);
21107fe6a43SSeth Howell if (vbdev == NULL) {
21207fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
21307fe6a43SSeth Howell spdk_strerror(ENODEV));
21420894340SMarcin Dziegielewski free(ctx);
21507fe6a43SSeth Howell goto end;
21607fe6a43SSeth Howell }
21707fe6a43SSeth Howell
218d7a3a052SVitaliy Mysak ctx->core_name = vbdev->core.name;
21920894340SMarcin Dziegielewski ctx->request = request;
22064807a1aSSeth Howell ocf_mngt_cache_read_lock(vbdev->ocf_cache, rpc_bdev_ocf_get_stats_cmpl, ctx);
22107fe6a43SSeth Howell
22207fe6a43SSeth Howell end:
2236ee39210SRafal Stefanowski free_rpc_bdev_ocf_name(&req);
22407fe6a43SSeth Howell }
22564807a1aSSeth Howell SPDK_RPC_REGISTER("bdev_ocf_get_stats", rpc_bdev_ocf_get_stats, SPDK_RPC_RUNTIME)
22607fe6a43SSeth Howell
227*6b79f767SAmir Haroush static void
rpc_bdev_ocf_reset_stats_cmpl(ocf_cache_t cache,void * priv,int error)228*6b79f767SAmir Haroush rpc_bdev_ocf_reset_stats_cmpl(ocf_cache_t cache, void *priv, int error)
229*6b79f767SAmir Haroush {
230*6b79f767SAmir Haroush struct get_ocf_stats_ctx *ctx = (struct get_ocf_stats_ctx *) priv;
231*6b79f767SAmir Haroush
232*6b79f767SAmir Haroush if (error) {
233*6b79f767SAmir Haroush goto end;
234*6b79f767SAmir Haroush }
235*6b79f767SAmir Haroush
236*6b79f767SAmir Haroush error = vbdev_ocf_stats_reset(cache, ctx->core_name);
237*6b79f767SAmir Haroush
238*6b79f767SAmir Haroush ocf_mngt_cache_read_unlock(cache);
239*6b79f767SAmir Haroush
240*6b79f767SAmir Haroush end:
241*6b79f767SAmir Haroush if (error) {
242*6b79f767SAmir Haroush spdk_jsonrpc_send_error_response_fmt(ctx->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
243*6b79f767SAmir Haroush "Could not reset stats: %s",
244*6b79f767SAmir Haroush spdk_strerror(-error));
245*6b79f767SAmir Haroush } else {
246*6b79f767SAmir Haroush spdk_jsonrpc_send_bool_response(ctx->request, true);
247*6b79f767SAmir Haroush }
248*6b79f767SAmir Haroush free(ctx);
249*6b79f767SAmir Haroush }
250*6b79f767SAmir Haroush
251*6b79f767SAmir Haroush static void
rpc_bdev_ocf_reset_stats(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)252*6b79f767SAmir Haroush rpc_bdev_ocf_reset_stats(struct spdk_jsonrpc_request *request,
253*6b79f767SAmir Haroush const struct spdk_json_val *params)
254*6b79f767SAmir Haroush {
255*6b79f767SAmir Haroush struct rpc_bdev_ocf_name req = {NULL};
256*6b79f767SAmir Haroush struct vbdev_ocf *vbdev;
257*6b79f767SAmir Haroush struct get_ocf_stats_ctx *ctx;
258*6b79f767SAmir Haroush
259*6b79f767SAmir Haroush ctx = calloc(1, sizeof(*ctx));
260*6b79f767SAmir Haroush if (!ctx) {
261*6b79f767SAmir Haroush spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
262*6b79f767SAmir Haroush "Not enough memory to process request");
263*6b79f767SAmir Haroush goto end;
264*6b79f767SAmir Haroush }
265*6b79f767SAmir Haroush
266*6b79f767SAmir Haroush if (spdk_json_decode_object(params, rpc_bdev_ocf_name_decoders,
267*6b79f767SAmir Haroush SPDK_COUNTOF(rpc_bdev_ocf_name_decoders),
268*6b79f767SAmir Haroush &req)) {
269*6b79f767SAmir Haroush spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
270*6b79f767SAmir Haroush "Invalid parameters");
271*6b79f767SAmir Haroush free(ctx);
272*6b79f767SAmir Haroush goto end;
273*6b79f767SAmir Haroush }
274*6b79f767SAmir Haroush
275*6b79f767SAmir Haroush vbdev = vbdev_ocf_get_by_name(req.name);
276*6b79f767SAmir Haroush if (vbdev == NULL) {
277*6b79f767SAmir Haroush spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
278*6b79f767SAmir Haroush spdk_strerror(ENODEV));
279*6b79f767SAmir Haroush free(ctx);
280*6b79f767SAmir Haroush goto end;
281*6b79f767SAmir Haroush }
282*6b79f767SAmir Haroush
283*6b79f767SAmir Haroush ctx->core_name = vbdev->core.name;
284*6b79f767SAmir Haroush ctx->request = request;
285*6b79f767SAmir Haroush ocf_mngt_cache_read_lock(vbdev->ocf_cache, rpc_bdev_ocf_reset_stats_cmpl, ctx);
286*6b79f767SAmir Haroush
287*6b79f767SAmir Haroush end:
288*6b79f767SAmir Haroush free_rpc_bdev_ocf_name(&req);
289*6b79f767SAmir Haroush }
290*6b79f767SAmir Haroush SPDK_RPC_REGISTER("bdev_ocf_reset_stats", rpc_bdev_ocf_reset_stats, SPDK_RPC_RUNTIME)
291*6b79f767SAmir Haroush
29207fe6a43SSeth Howell /* Structure to decode the input parameters for this RPC method. */
29395482c54SPawel Kaminski static const struct spdk_json_object_decoder rpc_bdev_ocf_get_bdevs_decoders[] = {
2946ee39210SRafal Stefanowski {"name", offsetof(struct rpc_bdev_ocf_name, name), spdk_json_decode_string, true},
29507fe6a43SSeth Howell };
29607fe6a43SSeth Howell
2972c49e910SMaciej Wawryk struct bdev_get_bdevs_ctx {
29807fe6a43SSeth Howell char *name;
29907fe6a43SSeth Howell struct spdk_json_write_ctx *w;
30007fe6a43SSeth Howell };
30107fe6a43SSeth Howell
30207fe6a43SSeth Howell static void
bdev_get_bdevs_fn(struct vbdev_ocf * vbdev,void * ctx)3032c49e910SMaciej Wawryk bdev_get_bdevs_fn(struct vbdev_ocf *vbdev, void *ctx)
30407fe6a43SSeth Howell {
3052c49e910SMaciej Wawryk struct bdev_get_bdevs_ctx *cctx = ctx;
30607fe6a43SSeth Howell struct spdk_json_write_ctx *w = cctx->w;
30707fe6a43SSeth Howell
30807fe6a43SSeth Howell if (cctx->name != NULL &&
30907fe6a43SSeth Howell strcmp(vbdev->name, cctx->name) &&
31007fe6a43SSeth Howell strcmp(vbdev->cache.name, cctx->name) &&
31107fe6a43SSeth Howell strcmp(vbdev->core.name, cctx->name)) {
31207fe6a43SSeth Howell return;
31307fe6a43SSeth Howell }
31407fe6a43SSeth Howell
31507fe6a43SSeth Howell spdk_json_write_object_begin(w);
31607fe6a43SSeth Howell spdk_json_write_named_string(w, "name", vbdev->name);
31707fe6a43SSeth Howell spdk_json_write_named_bool(w, "started", vbdev->state.started);
31807fe6a43SSeth Howell
31907fe6a43SSeth Howell spdk_json_write_named_object_begin(w, "cache");
32007fe6a43SSeth Howell spdk_json_write_named_string(w, "name", vbdev->cache.name);
32107fe6a43SSeth Howell spdk_json_write_named_bool(w, "attached", vbdev->cache.attached);
32207fe6a43SSeth Howell spdk_json_write_object_end(w);
32307fe6a43SSeth Howell
32407fe6a43SSeth Howell spdk_json_write_named_object_begin(w, "core");
32507fe6a43SSeth Howell spdk_json_write_named_string(w, "name", vbdev->core.name);
32607fe6a43SSeth Howell spdk_json_write_named_bool(w, "attached", vbdev->core.attached);
32707fe6a43SSeth Howell spdk_json_write_object_end(w);
32807fe6a43SSeth Howell
32907fe6a43SSeth Howell spdk_json_write_object_end(w);
33007fe6a43SSeth Howell }
33107fe6a43SSeth Howell
33207fe6a43SSeth Howell static void
rpc_bdev_ocf_get_bdevs(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)33364807a1aSSeth Howell rpc_bdev_ocf_get_bdevs(struct spdk_jsonrpc_request *request,
33495482c54SPawel Kaminski const struct spdk_json_val *params)
33507fe6a43SSeth Howell {
33607fe6a43SSeth Howell struct spdk_json_write_ctx *w;
3376ee39210SRafal Stefanowski struct rpc_bdev_ocf_name req = {NULL};
3382c49e910SMaciej Wawryk struct bdev_get_bdevs_ctx cctx;
33907fe6a43SSeth Howell
34095482c54SPawel Kaminski if (params && spdk_json_decode_object(params, rpc_bdev_ocf_get_bdevs_decoders,
34195482c54SPawel Kaminski SPDK_COUNTOF(rpc_bdev_ocf_get_bdevs_decoders),
34207fe6a43SSeth Howell &req)) {
34307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
34407fe6a43SSeth Howell "Invalid parameters");
34507fe6a43SSeth Howell goto end;
34607fe6a43SSeth Howell }
34707fe6a43SSeth Howell
34807fe6a43SSeth Howell if (req.name) {
34907fe6a43SSeth Howell if (!(vbdev_ocf_get_by_name(req.name) || vbdev_ocf_get_base_by_name(req.name))) {
35007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request,
35107fe6a43SSeth Howell SPDK_JSONRPC_ERROR_INVALID_PARAMS,
35207fe6a43SSeth Howell spdk_strerror(ENODEV));
35307fe6a43SSeth Howell goto end;
35407fe6a43SSeth Howell }
35507fe6a43SSeth Howell }
35607fe6a43SSeth Howell
35707fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request);
35807fe6a43SSeth Howell
35907fe6a43SSeth Howell cctx.name = req.name;
36007fe6a43SSeth Howell cctx.w = w;
36107fe6a43SSeth Howell
36207fe6a43SSeth Howell spdk_json_write_array_begin(w);
3632c49e910SMaciej Wawryk vbdev_ocf_foreach(bdev_get_bdevs_fn, &cctx);
36407fe6a43SSeth Howell spdk_json_write_array_end(w);
36507fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w);
36607fe6a43SSeth Howell
36707fe6a43SSeth Howell end:
3686ee39210SRafal Stefanowski free_rpc_bdev_ocf_name(&req);
36907fe6a43SSeth Howell }
37064807a1aSSeth Howell SPDK_RPC_REGISTER("bdev_ocf_get_bdevs", rpc_bdev_ocf_get_bdevs, SPDK_RPC_RUNTIME)
3715bdaec63SRafal Stefanowski
3725bdaec63SRafal Stefanowski /* Structure to hold the parameters for this RPC method. */
3735bdaec63SRafal Stefanowski struct rpc_bdev_ocf_set_cache_mode {
3745bdaec63SRafal Stefanowski char *name; /* main vbdev name */
3755bdaec63SRafal Stefanowski char *mode; /* OCF cache mode to switch to */
3765bdaec63SRafal Stefanowski };
3775bdaec63SRafal Stefanowski
3785bdaec63SRafal Stefanowski static void
free_rpc_bdev_ocf_set_cache_mode(struct rpc_bdev_ocf_set_cache_mode * r)3795bdaec63SRafal Stefanowski free_rpc_bdev_ocf_set_cache_mode(struct rpc_bdev_ocf_set_cache_mode *r)
3805bdaec63SRafal Stefanowski {
3815bdaec63SRafal Stefanowski free(r->name);
3825bdaec63SRafal Stefanowski free(r->mode);
3835bdaec63SRafal Stefanowski }
3845bdaec63SRafal Stefanowski
3855bdaec63SRafal Stefanowski /* Structure to decode the input parameters for this RPC method. */
3865bdaec63SRafal Stefanowski static const struct spdk_json_object_decoder rpc_bdev_ocf_set_cache_mode_decoders[] = {
3875bdaec63SRafal Stefanowski {"name", offsetof(struct rpc_bdev_ocf_set_cache_mode, name), spdk_json_decode_string},
3885bdaec63SRafal Stefanowski {"mode", offsetof(struct rpc_bdev_ocf_set_cache_mode, mode), spdk_json_decode_string},
3895bdaec63SRafal Stefanowski };
3905bdaec63SRafal Stefanowski
3915bdaec63SRafal Stefanowski static void
cache_mode_cb(int status,struct vbdev_ocf * vbdev,void * cb_arg)3925bdaec63SRafal Stefanowski cache_mode_cb(int status, struct vbdev_ocf *vbdev, void *cb_arg)
3935bdaec63SRafal Stefanowski {
3945bdaec63SRafal Stefanowski struct spdk_jsonrpc_request *request = cb_arg;
3955bdaec63SRafal Stefanowski struct spdk_json_write_ctx *w;
3965bdaec63SRafal Stefanowski
3975bdaec63SRafal Stefanowski if (status) {
3985bdaec63SRafal Stefanowski spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
3995bdaec63SRafal Stefanowski "Could not change OCF vbdev cache mode: %d",
4005bdaec63SRafal Stefanowski status);
4015bdaec63SRafal Stefanowski } else {
4025bdaec63SRafal Stefanowski w = spdk_jsonrpc_begin_result(request);
4035bdaec63SRafal Stefanowski spdk_json_write_string(w, ocf_get_cache_modename(
4045bdaec63SRafal Stefanowski ocf_cache_get_mode(vbdev->ocf_cache)));
4055bdaec63SRafal Stefanowski spdk_jsonrpc_end_result(request, w);
4065bdaec63SRafal Stefanowski }
4075bdaec63SRafal Stefanowski }
4085bdaec63SRafal Stefanowski
4095bdaec63SRafal Stefanowski static void
rpc_bdev_ocf_set_cache_mode(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)4105bdaec63SRafal Stefanowski rpc_bdev_ocf_set_cache_mode(struct spdk_jsonrpc_request *request,
4115bdaec63SRafal Stefanowski const struct spdk_json_val *params)
4125bdaec63SRafal Stefanowski {
4135bdaec63SRafal Stefanowski struct rpc_bdev_ocf_set_cache_mode req = {NULL};
4145bdaec63SRafal Stefanowski struct vbdev_ocf *vbdev;
4155bdaec63SRafal Stefanowski int status;
4165bdaec63SRafal Stefanowski
4175bdaec63SRafal Stefanowski status = spdk_json_decode_object(params, rpc_bdev_ocf_set_cache_mode_decoders,
4185bdaec63SRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_set_cache_mode_decoders),
4195bdaec63SRafal Stefanowski &req);
4205bdaec63SRafal Stefanowski if (status) {
4215bdaec63SRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
4225bdaec63SRafal Stefanowski "Invalid parameters");
4235bdaec63SRafal Stefanowski goto end;
4245bdaec63SRafal Stefanowski }
4255bdaec63SRafal Stefanowski
4265bdaec63SRafal Stefanowski vbdev = vbdev_ocf_get_by_name(req.name);
4275bdaec63SRafal Stefanowski if (vbdev == NULL) {
4285bdaec63SRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
4295bdaec63SRafal Stefanowski spdk_strerror(ENODEV));
4305bdaec63SRafal Stefanowski goto end;
4315bdaec63SRafal Stefanowski }
4325bdaec63SRafal Stefanowski
4335bdaec63SRafal Stefanowski vbdev_ocf_set_cache_mode(vbdev, req.mode, cache_mode_cb, request);
4345bdaec63SRafal Stefanowski
4355bdaec63SRafal Stefanowski end:
4365bdaec63SRafal Stefanowski free_rpc_bdev_ocf_set_cache_mode(&req);
4375bdaec63SRafal Stefanowski }
4385bdaec63SRafal Stefanowski SPDK_RPC_REGISTER("bdev_ocf_set_cache_mode", rpc_bdev_ocf_set_cache_mode, SPDK_RPC_RUNTIME)
439494b1ba8SRafal Stefanowski
440494b1ba8SRafal Stefanowski static void
seqcutoff_cb(int status,void * cb_arg)441494b1ba8SRafal Stefanowski seqcutoff_cb(int status, void *cb_arg)
442494b1ba8SRafal Stefanowski {
443494b1ba8SRafal Stefanowski struct spdk_jsonrpc_request *request = cb_arg;
444494b1ba8SRafal Stefanowski
445494b1ba8SRafal Stefanowski if (status) {
446494b1ba8SRafal Stefanowski spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
447494b1ba8SRafal Stefanowski "OCF could not set sequential cutoff parameters: %d", status);
448494b1ba8SRafal Stefanowski } else {
449494b1ba8SRafal Stefanowski spdk_jsonrpc_send_bool_response(request, true);
450494b1ba8SRafal Stefanowski }
451494b1ba8SRafal Stefanowski }
452494b1ba8SRafal Stefanowski
453494b1ba8SRafal Stefanowski /* Structure to hold the parameters for this RPC method. */
454494b1ba8SRafal Stefanowski struct rpc_bdev_ocf_set_seqcutoff {
455494b1ba8SRafal Stefanowski char *name; /* main vbdev name */
456494b1ba8SRafal Stefanowski char *policy;
457494b1ba8SRafal Stefanowski uint32_t threshold;
458494b1ba8SRafal Stefanowski uint32_t promotion_count;
459494b1ba8SRafal Stefanowski };
460494b1ba8SRafal Stefanowski
461494b1ba8SRafal Stefanowski static void
free_rpc_bdev_ocf_set_seqcutoff(struct rpc_bdev_ocf_set_seqcutoff * r)462494b1ba8SRafal Stefanowski free_rpc_bdev_ocf_set_seqcutoff(struct rpc_bdev_ocf_set_seqcutoff *r)
463494b1ba8SRafal Stefanowski {
464494b1ba8SRafal Stefanowski free(r->name);
465494b1ba8SRafal Stefanowski free(r->policy);
466494b1ba8SRafal Stefanowski }
467494b1ba8SRafal Stefanowski
468494b1ba8SRafal Stefanowski /* Structure to decode the input parameters for this RPC method. */
469494b1ba8SRafal Stefanowski static const struct spdk_json_object_decoder rpc_bdev_ocf_set_seqcutoff_decoders[] = {
470494b1ba8SRafal Stefanowski {"name", offsetof(struct rpc_bdev_ocf_set_seqcutoff, name), spdk_json_decode_string},
471494b1ba8SRafal Stefanowski {"policy", offsetof(struct rpc_bdev_ocf_set_seqcutoff, policy), spdk_json_decode_string},
472494b1ba8SRafal Stefanowski {"threshold", offsetof(struct rpc_bdev_ocf_set_seqcutoff, threshold), spdk_json_decode_uint32, true},
473494b1ba8SRafal Stefanowski {"promotion_count", offsetof(struct rpc_bdev_ocf_set_seqcutoff, promotion_count), spdk_json_decode_uint32, true},
474494b1ba8SRafal Stefanowski };
475494b1ba8SRafal Stefanowski
476494b1ba8SRafal Stefanowski static void
rpc_bdev_ocf_set_seqcutoff(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)477494b1ba8SRafal Stefanowski rpc_bdev_ocf_set_seqcutoff(struct spdk_jsonrpc_request *request,
478494b1ba8SRafal Stefanowski const struct spdk_json_val *params)
479494b1ba8SRafal Stefanowski {
480494b1ba8SRafal Stefanowski struct rpc_bdev_ocf_set_seqcutoff req = {NULL};
481494b1ba8SRafal Stefanowski struct vbdev_ocf *vbdev;
482494b1ba8SRafal Stefanowski int ret;
483494b1ba8SRafal Stefanowski
484494b1ba8SRafal Stefanowski ret = spdk_json_decode_object(params, rpc_bdev_ocf_set_seqcutoff_decoders,
485494b1ba8SRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_set_seqcutoff_decoders), &req);
486494b1ba8SRafal Stefanowski if (ret) {
487494b1ba8SRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
488494b1ba8SRafal Stefanowski "Invalid parameters");
489494b1ba8SRafal Stefanowski goto end;
490494b1ba8SRafal Stefanowski }
491494b1ba8SRafal Stefanowski
492494b1ba8SRafal Stefanowski vbdev = vbdev_ocf_get_by_name(req.name);
493494b1ba8SRafal Stefanowski if (vbdev == NULL) {
494494b1ba8SRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
495494b1ba8SRafal Stefanowski spdk_strerror(ENODEV));
496494b1ba8SRafal Stefanowski goto end;
497494b1ba8SRafal Stefanowski }
498494b1ba8SRafal Stefanowski
499494b1ba8SRafal Stefanowski vbdev_ocf_set_seqcutoff(vbdev, req.policy, req.threshold, req.promotion_count, seqcutoff_cb,
500494b1ba8SRafal Stefanowski request);
501494b1ba8SRafal Stefanowski
502494b1ba8SRafal Stefanowski end:
503494b1ba8SRafal Stefanowski free_rpc_bdev_ocf_set_seqcutoff(&req);
504494b1ba8SRafal Stefanowski }
505494b1ba8SRafal Stefanowski SPDK_RPC_REGISTER("bdev_ocf_set_seqcutoff", rpc_bdev_ocf_set_seqcutoff, SPDK_RPC_RUNTIME)
5068000cedbSRafal Stefanowski
5078000cedbSRafal Stefanowski struct get_ocf_flush_start_ctx {
5088000cedbSRafal Stefanowski struct spdk_jsonrpc_request *request;
5098000cedbSRafal Stefanowski struct vbdev_ocf *vbdev;
5108000cedbSRafal Stefanowski };
5118000cedbSRafal Stefanowski
5128000cedbSRafal Stefanowski static void
rpc_bdev_ocf_flush_start_cmpl(ocf_cache_t cache,void * priv,int error)5138000cedbSRafal Stefanowski rpc_bdev_ocf_flush_start_cmpl(ocf_cache_t cache, void *priv, int error)
5148000cedbSRafal Stefanowski {
5158000cedbSRafal Stefanowski struct get_ocf_flush_start_ctx *ctx = priv;
5168000cedbSRafal Stefanowski
5178000cedbSRafal Stefanowski ctx->vbdev->flush.in_progress = false;
5188000cedbSRafal Stefanowski ctx->vbdev->flush.status = error;
5198000cedbSRafal Stefanowski
5208000cedbSRafal Stefanowski ocf_mngt_cache_read_unlock(cache);
5218000cedbSRafal Stefanowski
5228000cedbSRafal Stefanowski free(ctx);
5238000cedbSRafal Stefanowski }
5248000cedbSRafal Stefanowski
5258000cedbSRafal Stefanowski static void
rpc_bdev_ocf_flush_start_lock_cmpl(ocf_cache_t cache,void * priv,int error)5268000cedbSRafal Stefanowski rpc_bdev_ocf_flush_start_lock_cmpl(ocf_cache_t cache, void *priv, int error)
5278000cedbSRafal Stefanowski {
5288000cedbSRafal Stefanowski struct get_ocf_flush_start_ctx *ctx = priv;
5298000cedbSRafal Stefanowski
5308000cedbSRafal Stefanowski if (error) {
5318000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response_fmt(ctx->request,
5328000cedbSRafal Stefanowski SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
5338000cedbSRafal Stefanowski "Could not lock cache: %d", error);
5348000cedbSRafal Stefanowski free(ctx);
5358000cedbSRafal Stefanowski return;
5368000cedbSRafal Stefanowski }
5378000cedbSRafal Stefanowski
5388000cedbSRafal Stefanowski ctx->vbdev->flush.in_progress = true;
5398000cedbSRafal Stefanowski ocf_mngt_cache_flush(cache, rpc_bdev_ocf_flush_start_cmpl, ctx);
5408000cedbSRafal Stefanowski
5418000cedbSRafal Stefanowski spdk_jsonrpc_send_bool_response(ctx->request, true);
5428000cedbSRafal Stefanowski }
5438000cedbSRafal Stefanowski
5448000cedbSRafal Stefanowski static void
rpc_bdev_ocf_flush_start(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)5458000cedbSRafal Stefanowski rpc_bdev_ocf_flush_start(struct spdk_jsonrpc_request *request,
5468000cedbSRafal Stefanowski const struct spdk_json_val *params)
5478000cedbSRafal Stefanowski {
5488000cedbSRafal Stefanowski struct rpc_bdev_ocf_name req = {NULL};
5498000cedbSRafal Stefanowski struct get_ocf_flush_start_ctx *ctx;
5508000cedbSRafal Stefanowski int status;
5518000cedbSRafal Stefanowski
5528000cedbSRafal Stefanowski ctx = calloc(1, sizeof(*ctx));
5538000cedbSRafal Stefanowski if (!ctx) {
5548000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
5558000cedbSRafal Stefanowski "Not enough memory to process request");
5568000cedbSRafal Stefanowski goto end;
5578000cedbSRafal Stefanowski }
5588000cedbSRafal Stefanowski
5598000cedbSRafal Stefanowski status = spdk_json_decode_object(params, rpc_bdev_ocf_name_decoders,
5608000cedbSRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_name_decoders),
5618000cedbSRafal Stefanowski &req);
5628000cedbSRafal Stefanowski if (status) {
5638000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
5648000cedbSRafal Stefanowski "Invalid parameters");
5658000cedbSRafal Stefanowski free(ctx);
5668000cedbSRafal Stefanowski goto end;
5678000cedbSRafal Stefanowski }
5688000cedbSRafal Stefanowski
5698000cedbSRafal Stefanowski ctx->vbdev = vbdev_ocf_get_by_name(req.name);
5708000cedbSRafal Stefanowski if (ctx->vbdev == NULL) {
5718000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
5728000cedbSRafal Stefanowski spdk_strerror(ENODEV));
5738000cedbSRafal Stefanowski free(ctx);
5748000cedbSRafal Stefanowski goto end;
5758000cedbSRafal Stefanowski }
5768000cedbSRafal Stefanowski
5778000cedbSRafal Stefanowski if (!ctx->vbdev->ocf_cache) {
5788000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
5798000cedbSRafal Stefanowski "Couldn't flush cache: device not attached");
5808000cedbSRafal Stefanowski free(ctx);
5818000cedbSRafal Stefanowski goto end;
5828000cedbSRafal Stefanowski }
5838000cedbSRafal Stefanowski
5848000cedbSRafal Stefanowski ctx->request = request;
5858000cedbSRafal Stefanowski ocf_mngt_cache_read_lock(ctx->vbdev->ocf_cache, rpc_bdev_ocf_flush_start_lock_cmpl, ctx);
5868000cedbSRafal Stefanowski
5878000cedbSRafal Stefanowski end:
5888000cedbSRafal Stefanowski free_rpc_bdev_ocf_name(&req);
5898000cedbSRafal Stefanowski }
5908000cedbSRafal Stefanowski SPDK_RPC_REGISTER("bdev_ocf_flush_start", rpc_bdev_ocf_flush_start, SPDK_RPC_RUNTIME)
5918000cedbSRafal Stefanowski
5928000cedbSRafal Stefanowski static void
rpc_bdev_ocf_flush_status(struct spdk_jsonrpc_request * request,const struct spdk_json_val * params)5938000cedbSRafal Stefanowski rpc_bdev_ocf_flush_status(struct spdk_jsonrpc_request *request,
5948000cedbSRafal Stefanowski const struct spdk_json_val *params)
5958000cedbSRafal Stefanowski {
5968000cedbSRafal Stefanowski struct rpc_bdev_ocf_name req = {NULL};
5978000cedbSRafal Stefanowski struct spdk_json_write_ctx *w;
5988000cedbSRafal Stefanowski struct vbdev_ocf *vbdev;
5998000cedbSRafal Stefanowski int status;
6008000cedbSRafal Stefanowski
6018000cedbSRafal Stefanowski status = spdk_json_decode_object(params, rpc_bdev_ocf_name_decoders,
6028000cedbSRafal Stefanowski SPDK_COUNTOF(rpc_bdev_ocf_name_decoders),
6038000cedbSRafal Stefanowski &req);
6048000cedbSRafal Stefanowski if (status) {
6058000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
6068000cedbSRafal Stefanowski "Invalid parameters");
6078000cedbSRafal Stefanowski goto end;
6088000cedbSRafal Stefanowski }
6098000cedbSRafal Stefanowski
6108000cedbSRafal Stefanowski vbdev = vbdev_ocf_get_by_name(req.name);
6118000cedbSRafal Stefanowski if (vbdev == NULL) {
6128000cedbSRafal Stefanowski spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
6138000cedbSRafal Stefanowski spdk_strerror(ENODEV));
6148000cedbSRafal Stefanowski goto end;
6158000cedbSRafal Stefanowski }
6168000cedbSRafal Stefanowski
6178000cedbSRafal Stefanowski w = spdk_jsonrpc_begin_result(request);
6188000cedbSRafal Stefanowski
6198000cedbSRafal Stefanowski spdk_json_write_object_begin(w);
6208000cedbSRafal Stefanowski spdk_json_write_named_bool(w, "in_progress", vbdev->flush.in_progress);
6218000cedbSRafal Stefanowski if (!vbdev->flush.in_progress) {
6228000cedbSRafal Stefanowski spdk_json_write_named_int32(w, "status", vbdev->flush.status);
6238000cedbSRafal Stefanowski }
6248000cedbSRafal Stefanowski spdk_json_write_object_end(w);
6258000cedbSRafal Stefanowski
6268000cedbSRafal Stefanowski spdk_jsonrpc_end_result(request, w);
6278000cedbSRafal Stefanowski
6288000cedbSRafal Stefanowski end:
6298000cedbSRafal Stefanowski free_rpc_bdev_ocf_name(&req);
6308000cedbSRafal Stefanowski }
6318000cedbSRafal Stefanowski SPDK_RPC_REGISTER("bdev_ocf_flush_status", rpc_bdev_ocf_flush_status, SPDK_RPC_RUNTIME)
632