xref: /spdk/module/bdev/compress/vbdev_compress_rpc.c (revision ddd4603ceb2154dd59f14c6f2851f5f8cd1711c4)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2018 Intel Corporation.
3c77bc554SShuhei Matsumoto  *   Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
407fe6a43SSeth Howell  *   All rights reserved.
507fe6a43SSeth Howell  */
607fe6a43SSeth Howell 
707fe6a43SSeth Howell #include "vbdev_compress.h"
807fe6a43SSeth Howell #include "spdk/rpc.h"
907fe6a43SSeth Howell #include "spdk/util.h"
1007fe6a43SSeth Howell #include "spdk/string.h"
114e8e97c8STomasz Zawadzki #include "spdk/log.h"
1207fe6a43SSeth Howell 
1307fe6a43SSeth Howell struct rpc_bdev_compress_get_orphans {
1407fe6a43SSeth Howell 	char *name;
1507fe6a43SSeth Howell };
1607fe6a43SSeth Howell 
1707fe6a43SSeth Howell static void
1807fe6a43SSeth Howell free_rpc_bdev_compress_get_orphans(struct rpc_bdev_compress_get_orphans *r)
1907fe6a43SSeth Howell {
2007fe6a43SSeth Howell 	free(r->name);
2107fe6a43SSeth Howell }
2207fe6a43SSeth Howell 
2307fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_bdev_compress_get_orphans_decoders[] = {
2407fe6a43SSeth Howell 	{"name", offsetof(struct rpc_bdev_compress_get_orphans, name), spdk_json_decode_string, true},
2507fe6a43SSeth Howell };
2607fe6a43SSeth Howell 
2707fe6a43SSeth Howell static void
28347499e7SSeth Howell rpc_bdev_compress_get_orphans(struct spdk_jsonrpc_request *request,
2907fe6a43SSeth Howell 			      const struct spdk_json_val *params)
3007fe6a43SSeth Howell {
3107fe6a43SSeth Howell 	struct rpc_bdev_compress_get_orphans req = {};
3207fe6a43SSeth Howell 	struct spdk_json_write_ctx *w;
3307fe6a43SSeth Howell 	struct vbdev_compress *comp_bdev;
3407fe6a43SSeth Howell 	bool found = false;
3507fe6a43SSeth Howell 
3607fe6a43SSeth Howell 
3707fe6a43SSeth Howell 	if (params && spdk_json_decode_object(params, rpc_bdev_compress_get_orphans_decoders,
3807fe6a43SSeth Howell 					      SPDK_COUNTOF(rpc_bdev_compress_get_orphans_decoders),
3907fe6a43SSeth Howell 					      &req)) {
4007fe6a43SSeth Howell 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
4107fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
4207fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
4307fe6a43SSeth Howell 		free_rpc_bdev_compress_get_orphans(&req);
4407fe6a43SSeth Howell 		return;
4507fe6a43SSeth Howell 	}
4607fe6a43SSeth Howell 
4707fe6a43SSeth Howell 	if (req.name) {
4807fe6a43SSeth Howell 		if (compress_has_orphan(req.name) == false) {
4907fe6a43SSeth Howell 			spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
5007fe6a43SSeth Howell 			free_rpc_bdev_compress_get_orphans(&req);
5107fe6a43SSeth Howell 			return;
5207fe6a43SSeth Howell 		}
5307fe6a43SSeth Howell 		found = true;
5407fe6a43SSeth Howell 	}
5507fe6a43SSeth Howell 
5607fe6a43SSeth Howell 	w = spdk_jsonrpc_begin_result(request);
5707fe6a43SSeth Howell 	spdk_json_write_array_begin(w);
5807fe6a43SSeth Howell 	if (found) {
5907fe6a43SSeth Howell 		spdk_json_write_string(w, req.name);
6007fe6a43SSeth Howell 	} else {
6107fe6a43SSeth Howell 		for (comp_bdev = compress_bdev_first(); comp_bdev != NULL;
6207fe6a43SSeth Howell 		     comp_bdev = compress_bdev_next(comp_bdev)) {
6307fe6a43SSeth Howell 			if (compress_has_orphan(compress_get_name(comp_bdev))) {
6407fe6a43SSeth Howell 				spdk_json_write_string(w, compress_get_name(comp_bdev));
6507fe6a43SSeth Howell 			}
6607fe6a43SSeth Howell 		}
6707fe6a43SSeth Howell 	}
6807fe6a43SSeth Howell 	spdk_json_write_array_end(w);
6907fe6a43SSeth Howell 	spdk_jsonrpc_end_result(request, w);
7007fe6a43SSeth Howell 	free_rpc_bdev_compress_get_orphans(&req);
7107fe6a43SSeth Howell }
72347499e7SSeth Howell SPDK_RPC_REGISTER("bdev_compress_get_orphans", rpc_bdev_compress_get_orphans, SPDK_RPC_RUNTIME)
7307fe6a43SSeth Howell 
7407fe6a43SSeth Howell /* Structure to hold the parameters for this RPC method. */
7507fe6a43SSeth Howell struct rpc_construct_compress {
7607fe6a43SSeth Howell 	char *base_bdev_name;
7707fe6a43SSeth Howell 	char *pm_path;
7862b3b171Spaul luse 	uint32_t lb_size;
79*ddd4603cSYankun Li 	enum spdk_accel_comp_algo comp_algo;
80*ddd4603cSYankun Li 	uint32_t comp_level;
8107fe6a43SSeth Howell };
8207fe6a43SSeth Howell 
83*ddd4603cSYankun Li static int
84*ddd4603cSYankun Li rpc_decode_comp_algo(const struct spdk_json_val *val, void *out)
85*ddd4603cSYankun Li {
86*ddd4603cSYankun Li 	enum spdk_accel_comp_algo *algo = out;
87*ddd4603cSYankun Li 	char *name = NULL;
88*ddd4603cSYankun Li 	int rc;
89*ddd4603cSYankun Li 
90*ddd4603cSYankun Li 	rc = spdk_json_decode_string(val, &name);
91*ddd4603cSYankun Li 	if (rc != 0) {
92*ddd4603cSYankun Li 		return rc;
93*ddd4603cSYankun Li 	}
94*ddd4603cSYankun Li 
95*ddd4603cSYankun Li 	if (strcmp(name, "deflate") == 0) {
96*ddd4603cSYankun Li 		*algo = SPDK_ACCEL_COMP_ALGO_DEFLATE;
97*ddd4603cSYankun Li 	} else if (strcmp(name, "lz4") == 0) {
98*ddd4603cSYankun Li 		*algo = SPDK_ACCEL_COMP_ALGO_LZ4;
99*ddd4603cSYankun Li 	} else {
100*ddd4603cSYankun Li 		rc = -EINVAL;
101*ddd4603cSYankun Li 	}
102*ddd4603cSYankun Li 
103*ddd4603cSYankun Li 	free(name);
104*ddd4603cSYankun Li 
105*ddd4603cSYankun Li 	return rc;
106*ddd4603cSYankun Li }
107*ddd4603cSYankun Li 
108f3cda926SYankun Li struct rpc_bdev_compress_create_ctx {
109f3cda926SYankun Li 	struct rpc_construct_compress req;
110f3cda926SYankun Li 	struct spdk_jsonrpc_request *request;
111f3cda926SYankun Li };
112f3cda926SYankun Li 
11307fe6a43SSeth Howell /* Free the allocated memory resource after the RPC handling. */
11407fe6a43SSeth Howell static void
115f3cda926SYankun Li free_rpc_construct_compress(struct rpc_bdev_compress_create_ctx *ctx)
11607fe6a43SSeth Howell {
117f3cda926SYankun Li 	struct rpc_construct_compress *req;
118f3cda926SYankun Li 
119f3cda926SYankun Li 	assert(ctx != NULL);
120f3cda926SYankun Li 
121f3cda926SYankun Li 	req = &ctx->req;
122f3cda926SYankun Li 
123f3cda926SYankun Li 	free(req->base_bdev_name);
124f3cda926SYankun Li 	free(req->pm_path);
125f3cda926SYankun Li 
126f3cda926SYankun Li 	free(ctx);
12707fe6a43SSeth Howell }
12807fe6a43SSeth Howell 
12907fe6a43SSeth Howell /* Structure to decode the input parameters for this RPC method. */
13007fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_construct_compress_decoders[] = {
13107fe6a43SSeth Howell 	{"base_bdev_name", offsetof(struct rpc_construct_compress, base_bdev_name), spdk_json_decode_string},
13207fe6a43SSeth Howell 	{"pm_path", offsetof(struct rpc_construct_compress, pm_path), spdk_json_decode_string},
1330e25e2a6SKonrad Sztyber 	{"lb_size", offsetof(struct rpc_construct_compress, lb_size), spdk_json_decode_uint32, true},
134*ddd4603cSYankun Li 	{"comp_algo", offsetof(struct rpc_construct_compress, comp_algo), rpc_decode_comp_algo, true},
135*ddd4603cSYankun Li 	{"comp_level", offsetof(struct rpc_construct_compress, comp_level), spdk_json_decode_uint32, true},
13607fe6a43SSeth Howell };
13707fe6a43SSeth Howell 
138f3cda926SYankun Li static void
139f3cda926SYankun Li rpc_bdev_compress_create_cb(void *_ctx, int status)
140f3cda926SYankun Li {
141f3cda926SYankun Li 	struct rpc_bdev_compress_create_ctx *ctx = _ctx;
142f3cda926SYankun Li 	struct rpc_construct_compress *req = &ctx->req;
143f3cda926SYankun Li 	struct spdk_jsonrpc_request *request = ctx->request;
144f3cda926SYankun Li 	struct spdk_json_write_ctx *w;
145f3cda926SYankun Li 	char *name;
146f3cda926SYankun Li 
147f3cda926SYankun Li 	if (status != 0) {
148f3cda926SYankun Li 		spdk_jsonrpc_send_error_response(request, status, spdk_strerror(-status));
149f3cda926SYankun Li 	} else {
150f3cda926SYankun Li 		w = spdk_jsonrpc_begin_result(request);
151f3cda926SYankun Li 		name = spdk_sprintf_alloc("COMP_%s", req->base_bdev_name);
152f3cda926SYankun Li 		spdk_json_write_string(w, name);
153f3cda926SYankun Li 		spdk_jsonrpc_end_result(request, w);
154f3cda926SYankun Li 		free(name);
155f3cda926SYankun Li 	}
156f3cda926SYankun Li 
157f3cda926SYankun Li 	free_rpc_construct_compress(ctx);
158f3cda926SYankun Li }
159f3cda926SYankun Li 
16007fe6a43SSeth Howell /* Decode the parameters for this RPC method and properly construct the compress
16107fe6a43SSeth Howell  * device. Error status returned in the failed cases.
16207fe6a43SSeth Howell  */
16307fe6a43SSeth Howell static void
164347499e7SSeth Howell rpc_bdev_compress_create(struct spdk_jsonrpc_request *request,
16507fe6a43SSeth Howell 			 const struct spdk_json_val *params)
16607fe6a43SSeth Howell {
167f3cda926SYankun Li 	struct rpc_bdev_compress_create_ctx *ctx;
168f3cda926SYankun Li 	struct rpc_construct_compress *req;
16907fe6a43SSeth Howell 	int rc;
17007fe6a43SSeth Howell 
171f3cda926SYankun Li 	ctx = calloc(1, sizeof(*ctx));
172f3cda926SYankun Li 	if (ctx == NULL) {
173f3cda926SYankun Li 		SPDK_ERRLOG("failed to alloc compress bdev creation contexts\n");
174f3cda926SYankun Li 		spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
175f3cda926SYankun Li 		return;
176f3cda926SYankun Li 	}
177f3cda926SYankun Li 
178f3cda926SYankun Li 	req = &ctx->req;
179*ddd4603cSYankun Li 	req->comp_algo = SPDK_ACCEL_COMP_ALGO_DEFLATE;
180*ddd4603cSYankun Li 	req->comp_level = 1;
18107fe6a43SSeth Howell 	if (spdk_json_decode_object(params, rpc_construct_compress_decoders,
18207fe6a43SSeth Howell 				    SPDK_COUNTOF(rpc_construct_compress_decoders),
183f3cda926SYankun Li 				    req)) {
1842172c432STomasz Zawadzki 		SPDK_DEBUGLOG(vbdev_compress, "spdk_json_decode_object failed\n");
18562b3b171Spaul luse 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
18607fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
18707fe6a43SSeth Howell 		goto cleanup;
18807fe6a43SSeth Howell 	}
18907fe6a43SSeth Howell 
190*ddd4603cSYankun Li 	rc = create_compress_bdev(req->base_bdev_name, req->pm_path, req->lb_size, req->comp_algo,
191*ddd4603cSYankun Li 				  req->comp_level, rpc_bdev_compress_create_cb, ctx);
19207fe6a43SSeth Howell 	if (rc != 0) {
19389ee5a13Spaul luse 		if (rc == -EBUSY) {
19489ee5a13Spaul luse 			spdk_jsonrpc_send_error_response(request, rc, "Base bdev already in use for compression.");
19589ee5a13Spaul luse 		} else {
19607fe6a43SSeth Howell 			spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
19789ee5a13Spaul luse 		}
19807fe6a43SSeth Howell 		goto cleanup;
19907fe6a43SSeth Howell 	}
20007fe6a43SSeth Howell 
201f3cda926SYankun Li 	ctx->request = request;
202f3cda926SYankun Li 	return;
20307fe6a43SSeth Howell 
20407fe6a43SSeth Howell cleanup:
205f3cda926SYankun Li 	free_rpc_construct_compress(ctx);
20607fe6a43SSeth Howell }
207347499e7SSeth Howell SPDK_RPC_REGISTER("bdev_compress_create", rpc_bdev_compress_create, SPDK_RPC_RUNTIME)
20807fe6a43SSeth Howell 
20907fe6a43SSeth Howell struct rpc_delete_compress {
21007fe6a43SSeth Howell 	char *name;
21107fe6a43SSeth Howell };
21207fe6a43SSeth Howell 
21307fe6a43SSeth Howell static void
21407fe6a43SSeth Howell free_rpc_delete_compress(struct rpc_delete_compress *req)
21507fe6a43SSeth Howell {
21607fe6a43SSeth Howell 	free(req->name);
21707fe6a43SSeth Howell }
21807fe6a43SSeth Howell 
21907fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_delete_compress_decoders[] = {
22007fe6a43SSeth Howell 	{"name", offsetof(struct rpc_delete_compress, name), spdk_json_decode_string},
22107fe6a43SSeth Howell };
22207fe6a43SSeth Howell 
22307fe6a43SSeth Howell static void
224347499e7SSeth Howell _rpc_bdev_compress_delete_cb(void *cb_arg, int bdeverrno)
22507fe6a43SSeth Howell {
22607fe6a43SSeth Howell 	struct spdk_jsonrpc_request *request = cb_arg;
22707fe6a43SSeth Howell 
228c77bc554SShuhei Matsumoto 	if (bdeverrno == 0) {
229c77bc554SShuhei Matsumoto 		spdk_jsonrpc_send_bool_response(request, true);
230c77bc554SShuhei Matsumoto 	} else {
231c77bc554SShuhei Matsumoto 		spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
232c77bc554SShuhei Matsumoto 	}
23307fe6a43SSeth Howell }
23407fe6a43SSeth Howell 
23507fe6a43SSeth Howell static void
236347499e7SSeth Howell rpc_bdev_compress_delete(struct spdk_jsonrpc_request *request,
23707fe6a43SSeth Howell 			 const struct spdk_json_val *params)
23807fe6a43SSeth Howell {
23907fe6a43SSeth Howell 	struct rpc_delete_compress req = {NULL};
24007fe6a43SSeth Howell 
24107fe6a43SSeth Howell 	if (spdk_json_decode_object(params, rpc_delete_compress_decoders,
24207fe6a43SSeth Howell 				    SPDK_COUNTOF(rpc_delete_compress_decoders),
24307fe6a43SSeth Howell 				    &req)) {
24407fe6a43SSeth Howell 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
24507fe6a43SSeth Howell 						 "spdk_json_decode_object failed");
24607fe6a43SSeth Howell 	} else {
247347499e7SSeth Howell 		bdev_compress_delete(req.name, _rpc_bdev_compress_delete_cb, request);
24807fe6a43SSeth Howell 	}
24907fe6a43SSeth Howell 
25007fe6a43SSeth Howell 	free_rpc_delete_compress(&req);
25107fe6a43SSeth Howell }
252347499e7SSeth Howell SPDK_RPC_REGISTER("bdev_compress_delete", rpc_bdev_compress_delete, SPDK_RPC_RUNTIME)
253