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