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