1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "bdev_aio.h" 7 #include "spdk/rpc.h" 8 #include "spdk/util.h" 9 #include "spdk/string.h" 10 #include "spdk/log.h" 11 12 struct rpc_construct_aio { 13 char *name; 14 char *filename; 15 uint32_t block_size; 16 }; 17 18 struct rpc_construct_aio_ctx { 19 struct rpc_construct_aio req; 20 struct spdk_jsonrpc_request *request; 21 }; 22 23 static void 24 free_rpc_construct_aio(struct rpc_construct_aio_ctx *ctx) 25 { 26 free(ctx->req.name); 27 free(ctx->req.filename); 28 free(ctx); 29 } 30 31 static const struct spdk_json_object_decoder rpc_construct_aio_decoders[] = { 32 {"name", offsetof(struct rpc_construct_aio, name), spdk_json_decode_string}, 33 {"filename", offsetof(struct rpc_construct_aio, filename), spdk_json_decode_string}, 34 {"block_size", offsetof(struct rpc_construct_aio, block_size), spdk_json_decode_uint32, true}, 35 }; 36 37 static void 38 rpc_bdev_aio_create_cb(void *cb_arg) 39 { 40 struct rpc_construct_aio_ctx *ctx = cb_arg; 41 struct spdk_jsonrpc_request *request = ctx->request; 42 struct spdk_json_write_ctx *w; 43 44 w = spdk_jsonrpc_begin_result(request); 45 spdk_json_write_string(w, ctx->req.name); 46 spdk_jsonrpc_end_result(request, w); 47 free_rpc_construct_aio(ctx); 48 } 49 50 static void 51 rpc_bdev_aio_create(struct spdk_jsonrpc_request *request, 52 const struct spdk_json_val *params) 53 { 54 struct rpc_construct_aio_ctx *ctx; 55 int rc; 56 57 ctx = calloc(1, sizeof(*ctx)); 58 if (!ctx) { 59 spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); 60 return; 61 } 62 63 if (spdk_json_decode_object(params, rpc_construct_aio_decoders, 64 SPDK_COUNTOF(rpc_construct_aio_decoders), 65 &ctx->req)) { 66 SPDK_ERRLOG("spdk_json_decode_object failed\n"); 67 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 68 "spdk_json_decode_object failed"); 69 free_rpc_construct_aio(ctx); 70 return; 71 } 72 73 ctx->request = request; 74 rc = create_aio_bdev(ctx->req.name, ctx->req.filename, ctx->req.block_size); 75 if (rc) { 76 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 77 free_rpc_construct_aio(ctx); 78 return; 79 } 80 81 spdk_bdev_wait_for_examine(rpc_bdev_aio_create_cb, ctx); 82 } 83 SPDK_RPC_REGISTER("bdev_aio_create", rpc_bdev_aio_create, SPDK_RPC_RUNTIME) 84 85 struct rpc_rescan_aio { 86 char *name; 87 }; 88 89 static const struct spdk_json_object_decoder rpc_rescan_aio_decoders[] = { 90 {"name", offsetof(struct rpc_rescan_aio, name), spdk_json_decode_string}, 91 }; 92 93 static void 94 rpc_bdev_aio_rescan(struct spdk_jsonrpc_request *request, 95 const struct spdk_json_val *params) 96 { 97 struct rpc_rescan_aio req = {NULL}; 98 int bdeverrno; 99 100 if (spdk_json_decode_object(params, rpc_rescan_aio_decoders, 101 SPDK_COUNTOF(rpc_rescan_aio_decoders), 102 &req)) { 103 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 104 "spdk_json_decode_object failed"); 105 goto cleanup; 106 } 107 108 bdeverrno = bdev_aio_rescan(req.name); 109 if (bdeverrno) { 110 spdk_jsonrpc_send_error_response(request, bdeverrno, 111 spdk_strerror(-bdeverrno)); 112 goto cleanup; 113 } 114 115 spdk_jsonrpc_send_bool_response(request, true); 116 cleanup: 117 free(req.name); 118 } 119 SPDK_RPC_REGISTER("bdev_aio_rescan", rpc_bdev_aio_rescan, SPDK_RPC_RUNTIME) 120 121 struct rpc_delete_aio { 122 char *name; 123 }; 124 125 static void 126 free_rpc_delete_aio(struct rpc_delete_aio *r) 127 { 128 free(r->name); 129 } 130 131 static const struct spdk_json_object_decoder rpc_delete_aio_decoders[] = { 132 {"name", offsetof(struct rpc_delete_aio, name), spdk_json_decode_string}, 133 }; 134 135 static void 136 _rpc_bdev_aio_delete_cb(void *cb_arg, int bdeverrno) 137 { 138 struct spdk_jsonrpc_request *request = cb_arg; 139 140 if (bdeverrno == 0) { 141 spdk_jsonrpc_send_bool_response(request, true); 142 } else { 143 spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno)); 144 } 145 } 146 147 static void 148 rpc_bdev_aio_delete(struct spdk_jsonrpc_request *request, 149 const struct spdk_json_val *params) 150 { 151 struct rpc_delete_aio req = {NULL}; 152 153 if (spdk_json_decode_object(params, rpc_delete_aio_decoders, 154 SPDK_COUNTOF(rpc_delete_aio_decoders), 155 &req)) { 156 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 157 "spdk_json_decode_object failed"); 158 goto cleanup; 159 } 160 161 bdev_aio_delete(req.name, _rpc_bdev_aio_delete_cb, request); 162 163 cleanup: 164 free_rpc_delete_aio(&req); 165 } 166 SPDK_RPC_REGISTER("bdev_aio_delete", rpc_bdev_aio_delete, SPDK_RPC_RUNTIME) 167