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