xref: /spdk/module/blobfs/bdev/blobfs_bdev_rpc.c (revision 877573897ad52be4fa8989f7617bd655b87e05c4)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2019 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 #include "spdk/blobfs.h"
8 #include "spdk/bdev.h"
9 #include "spdk/event.h"
10 #include "spdk/blob_bdev.h"
11 #include "spdk/blobfs_bdev.h"
12 #include "spdk/log.h"
13 #include "spdk/string.h"
14 #include "spdk/rpc.h"
15 #include "spdk/util.h"
16 
17 #ifndef PAGE_SIZE
18 #define PAGE_SIZE 4096
19 #endif
20 
21 #define MIN_CLUSTER_SZ (1024 * 1024)
22 
23 struct rpc_blobfs_set_cache_size {
24 	uint64_t size_in_mb;
25 };
26 
27 static const struct spdk_json_object_decoder rpc_blobfs_set_cache_size_decoders[] = {
28 	{"size_in_mb", offsetof(struct rpc_blobfs_set_cache_size, size_in_mb), spdk_json_decode_uint64},
29 };
30 
31 static void
32 rpc_blobfs_set_cache_size(struct spdk_jsonrpc_request *request,
33 			  const struct spdk_json_val *params)
34 {
35 	struct rpc_blobfs_set_cache_size req;
36 	int rc;
37 
38 	if (spdk_json_decode_object(params, rpc_blobfs_set_cache_size_decoders,
39 				    SPDK_COUNTOF(rpc_blobfs_set_cache_size_decoders),
40 				    &req)) {
41 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
42 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
43 						 "spdk_json_decode_object failed");
44 
45 		return;
46 	}
47 
48 	if (req.size_in_mb == 0) {
49 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
50 						 "spdk_json_decode_object failed");
51 
52 		return;
53 	}
54 
55 	rc = spdk_fs_set_cache_size(req.size_in_mb);
56 
57 	spdk_jsonrpc_send_bool_response(request, rc == 0);
58 }
59 
60 SPDK_RPC_REGISTER("blobfs_set_cache_size", rpc_blobfs_set_cache_size,
61 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
62 
63 struct rpc_blobfs_detect {
64 	char *bdev_name;
65 
66 	struct spdk_jsonrpc_request *request;
67 };
68 
69 static void
70 free_rpc_blobfs_detect(struct rpc_blobfs_detect *req)
71 {
72 	free(req->bdev_name);
73 	free(req);
74 }
75 
76 static const struct spdk_json_object_decoder rpc_blobfs_detect_decoders[] = {
77 	{"bdev_name", offsetof(struct rpc_blobfs_detect, bdev_name), spdk_json_decode_string},
78 };
79 
80 static void
81 _rpc_blobfs_detect_done(void *cb_arg, int fserrno)
82 {
83 	struct rpc_blobfs_detect *req = cb_arg;
84 	bool existed = true;
85 
86 	if (fserrno == -EILSEQ) {
87 		/* There is no blobfs existing on bdev */
88 		existed = false;
89 	} else if (fserrno != 0) {
90 		spdk_jsonrpc_send_error_response(req->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
91 						 spdk_strerror(-fserrno));
92 
93 		return;
94 	}
95 
96 	spdk_jsonrpc_send_bool_response(req->request, existed);
97 
98 	free_rpc_blobfs_detect(req);
99 }
100 
101 static void
102 rpc_blobfs_detect(struct spdk_jsonrpc_request *request,
103 		  const struct spdk_json_val *params)
104 {
105 	struct rpc_blobfs_detect *req;
106 
107 	req = calloc(1, sizeof(*req));
108 	if (req == NULL) {
109 		SPDK_ERRLOG("could not allocate rpc_blobfs_detect request.\n");
110 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
111 		return;
112 	}
113 
114 	if (spdk_json_decode_object(params, rpc_blobfs_detect_decoders,
115 				    SPDK_COUNTOF(rpc_blobfs_detect_decoders),
116 				    req)) {
117 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
118 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
119 						 "spdk_json_decode_object failed");
120 
121 		free_rpc_blobfs_detect(req);
122 
123 		return;
124 	}
125 
126 	req->request = request;
127 	spdk_blobfs_bdev_detect(req->bdev_name, _rpc_blobfs_detect_done, req);
128 }
129 
130 SPDK_RPC_REGISTER("blobfs_detect", rpc_blobfs_detect, SPDK_RPC_RUNTIME)
131 
132 struct rpc_blobfs_create {
133 	char *bdev_name;
134 	uint64_t cluster_sz;
135 
136 	struct spdk_jsonrpc_request *request;
137 };
138 
139 static void
140 free_rpc_blobfs_create(struct rpc_blobfs_create *req)
141 {
142 	free(req->bdev_name);
143 	free(req);
144 }
145 
146 static int
147 rpc_decode_cluster_sz(const struct spdk_json_val *val, void *out)
148 {
149 	uint64_t *cluster_sz = out;
150 	char *sz_str = NULL;
151 	bool has_prefix;
152 	int rc;
153 
154 	rc = spdk_json_decode_string(val, &sz_str);
155 	if (rc) {
156 		SPDK_NOTICELOG("Invalid parameter value: cluster_sz\n");
157 		return -EINVAL;
158 	}
159 
160 	rc = spdk_parse_capacity(sz_str, cluster_sz, &has_prefix);
161 	free(sz_str);
162 
163 	if (rc || *cluster_sz % PAGE_SIZE != 0 || *cluster_sz < MIN_CLUSTER_SZ) {
164 		SPDK_NOTICELOG("Invalid parameter value: cluster_sz\n");
165 		return -EINVAL;
166 	}
167 
168 	SPDK_DEBUGLOG(blobfs_bdev_rpc, "cluster_sz of blobfs: %" PRId64 "\n", *cluster_sz);
169 	return 0;
170 }
171 
172 static const struct spdk_json_object_decoder rpc_blobfs_create_decoders[] = {
173 	{"bdev_name", offsetof(struct rpc_blobfs_create, bdev_name), spdk_json_decode_string},
174 	{"cluster_sz", offsetof(struct rpc_blobfs_create, cluster_sz), rpc_decode_cluster_sz, true},
175 };
176 
177 static void
178 _rpc_blobfs_create_done(void *cb_arg, int fserrno)
179 {
180 	struct rpc_blobfs_create *req = cb_arg;
181 
182 	if (fserrno != 0) {
183 		spdk_jsonrpc_send_error_response(req->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
184 						 spdk_strerror(-fserrno));
185 
186 		return;
187 	}
188 
189 	spdk_jsonrpc_send_bool_response(req->request, true);
190 
191 	free_rpc_blobfs_create(req);
192 }
193 
194 static void
195 rpc_blobfs_create(struct spdk_jsonrpc_request *request,
196 		  const struct spdk_json_val *params)
197 {
198 	struct rpc_blobfs_create *req;
199 
200 	req = calloc(1, sizeof(*req));
201 	if (req == NULL) {
202 		SPDK_ERRLOG("could not allocate rpc_blobfs_create request.\n");
203 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
204 		return;
205 	}
206 
207 	if (spdk_json_decode_object(params, rpc_blobfs_create_decoders,
208 				    SPDK_COUNTOF(rpc_blobfs_create_decoders),
209 				    req)) {
210 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
211 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
212 						 "spdk_json_decode_object failed");
213 
214 		free_rpc_blobfs_create(req);
215 
216 		return;
217 	}
218 
219 	req->request = request;
220 	spdk_blobfs_bdev_create(req->bdev_name, req->cluster_sz, _rpc_blobfs_create_done, req);
221 }
222 
223 SPDK_RPC_REGISTER("blobfs_create", rpc_blobfs_create, SPDK_RPC_RUNTIME)
224 
225 SPDK_LOG_REGISTER_COMPONENT(blobfs_bdev_rpc)
226 #ifdef SPDK_CONFIG_FUSE
227 
228 struct rpc_blobfs_mount {
229 	char *bdev_name;
230 	char *mountpoint;
231 
232 	struct spdk_jsonrpc_request *request;
233 };
234 
235 static void
236 free_rpc_blobfs_mount(struct rpc_blobfs_mount *req)
237 {
238 	free(req->bdev_name);
239 	free(req->mountpoint);
240 	free(req);
241 }
242 
243 static const struct spdk_json_object_decoder rpc_blobfs_mount_decoders[] = {
244 	{"bdev_name", offsetof(struct rpc_blobfs_mount, bdev_name), spdk_json_decode_string},
245 	{"mountpoint", offsetof(struct rpc_blobfs_mount, mountpoint), spdk_json_decode_string},
246 };
247 
248 static void
249 _rpc_blobfs_mount_done(void *cb_arg, int fserrno)
250 {
251 	struct rpc_blobfs_mount *req = cb_arg;
252 
253 	if (fserrno == -EILSEQ) {
254 		/* There is no blobfs existing on bdev */
255 		spdk_jsonrpc_send_error_response(req->request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
256 						 "No blobfs detected on given bdev");
257 
258 		return;
259 	} else if (fserrno != 0) {
260 		spdk_jsonrpc_send_error_response(req->request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
261 						 spdk_strerror(-fserrno));
262 
263 		return;
264 	}
265 
266 	spdk_jsonrpc_send_bool_response(req->request, true);
267 
268 	free_rpc_blobfs_mount(req);
269 }
270 
271 static void
272 rpc_blobfs_mount(struct spdk_jsonrpc_request *request,
273 		 const struct spdk_json_val *params)
274 {
275 	struct rpc_blobfs_mount *req;
276 
277 	req = calloc(1, sizeof(*req));
278 	if (req == NULL) {
279 		SPDK_ERRLOG("could not allocate rpc_blobfs_mount request.\n");
280 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Out of memory");
281 		return;
282 	}
283 
284 	if (spdk_json_decode_object(params, rpc_blobfs_mount_decoders,
285 				    SPDK_COUNTOF(rpc_blobfs_mount_decoders),
286 				    req)) {
287 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
288 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
289 						 "spdk_json_decode_object failed");
290 
291 		free_rpc_blobfs_mount(req);
292 
293 		return;
294 	}
295 
296 	req->request = request;
297 	spdk_blobfs_bdev_mount(req->bdev_name, req->mountpoint, _rpc_blobfs_mount_done, req);
298 }
299 
300 SPDK_RPC_REGISTER("blobfs_mount", rpc_blobfs_mount, SPDK_RPC_RUNTIME)
301 
302 #endif
303