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