1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2017 Intel Corporation. 307fe6a43SSeth Howell * All rights reserved. 4a67e0eb3SMike Gerdts * Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 507fe6a43SSeth Howell */ 607fe6a43SSeth Howell 707fe6a43SSeth Howell #include "spdk/rpc.h" 807fe6a43SSeth Howell #include "spdk/bdev.h" 907fe6a43SSeth Howell #include "spdk/util.h" 1007fe6a43SSeth Howell #include "vbdev_lvol.h" 1107fe6a43SSeth Howell #include "spdk/string.h" 124e8e97c8STomasz Zawadzki #include "spdk/log.h" 1307fe6a43SSeth Howell 142172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(lvol_rpc) 1507fe6a43SSeth Howell 169b3554b5SDamiano Cipriani struct rpc_shallow_copy_status { 179b3554b5SDamiano Cipriani uint32_t operation_id; 189b3554b5SDamiano Cipriani /* 199b3554b5SDamiano Cipriani * 0 means ongoing or successfully completed operation 209b3554b5SDamiano Cipriani * a negative value is the -errno of an aborted operation 219b3554b5SDamiano Cipriani */ 229b3554b5SDamiano Cipriani int result; 239b3554b5SDamiano Cipriani uint64_t copied_clusters; 249b3554b5SDamiano Cipriani uint64_t total_clusters; 259b3554b5SDamiano Cipriani LIST_ENTRY(rpc_shallow_copy_status) link; 269b3554b5SDamiano Cipriani }; 279b3554b5SDamiano Cipriani 289b3554b5SDamiano Cipriani static uint32_t g_shallow_copy_count = 0; 299b3554b5SDamiano Cipriani static LIST_HEAD(, rpc_shallow_copy_status) g_shallow_copy_status_list = LIST_HEAD_INITIALIZER( 309b3554b5SDamiano Cipriani &g_shallow_copy_status_list); 319b3554b5SDamiano Cipriani 32de756853SMaciej Wawryk struct rpc_bdev_lvol_create_lvstore { 3307fe6a43SSeth Howell char *lvs_name; 3407fe6a43SSeth Howell char *bdev_name; 3507fe6a43SSeth Howell uint32_t cluster_sz; 3607fe6a43SSeth Howell char *clear_method; 3788833020Syupeng uint32_t num_md_pages_per_cluster_ratio; 38*e0d7428bSAtul Malakar uint32_t md_page_size; 3907fe6a43SSeth Howell }; 4007fe6a43SSeth Howell 4107fe6a43SSeth Howell static int 4207fe6a43SSeth Howell vbdev_get_lvol_store_by_uuid_xor_name(const char *uuid, const char *lvs_name, 4307fe6a43SSeth Howell struct spdk_lvol_store **lvs) 4407fe6a43SSeth Howell { 4507fe6a43SSeth Howell if ((uuid == NULL && lvs_name == NULL)) { 462172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "lvs UUID nor lvs name specified\n"); 4707fe6a43SSeth Howell return -EINVAL; 4807fe6a43SSeth Howell } else if ((uuid && lvs_name)) { 492172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "both lvs UUID '%s' and lvs name '%s' specified\n", uuid, 5007fe6a43SSeth Howell lvs_name); 5107fe6a43SSeth Howell return -EINVAL; 5207fe6a43SSeth Howell } else if (uuid) { 5307fe6a43SSeth Howell *lvs = vbdev_get_lvol_store_by_uuid(uuid); 5407fe6a43SSeth Howell 5507fe6a43SSeth Howell if (*lvs == NULL) { 562172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "blobstore with UUID '%s' not found\n", uuid); 5707fe6a43SSeth Howell return -ENODEV; 5807fe6a43SSeth Howell } 5907fe6a43SSeth Howell } else if (lvs_name) { 6007fe6a43SSeth Howell 6107fe6a43SSeth Howell *lvs = vbdev_get_lvol_store_by_name(lvs_name); 6207fe6a43SSeth Howell 6307fe6a43SSeth Howell if (*lvs == NULL) { 642172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "blobstore with name '%s' not found\n", lvs_name); 6507fe6a43SSeth Howell return -ENODEV; 6607fe6a43SSeth Howell } 6707fe6a43SSeth Howell } 6807fe6a43SSeth Howell return 0; 6907fe6a43SSeth Howell } 7007fe6a43SSeth Howell 7107fe6a43SSeth Howell static void 72de756853SMaciej Wawryk free_rpc_bdev_lvol_create_lvstore(struct rpc_bdev_lvol_create_lvstore *req) 7307fe6a43SSeth Howell { 7407fe6a43SSeth Howell free(req->bdev_name); 7507fe6a43SSeth Howell free(req->lvs_name); 7607fe6a43SSeth Howell free(req->clear_method); 7707fe6a43SSeth Howell } 7807fe6a43SSeth Howell 79de756853SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_create_lvstore_decoders[] = { 80de756853SMaciej Wawryk {"bdev_name", offsetof(struct rpc_bdev_lvol_create_lvstore, bdev_name), spdk_json_decode_string}, 81de756853SMaciej Wawryk {"cluster_sz", offsetof(struct rpc_bdev_lvol_create_lvstore, cluster_sz), spdk_json_decode_uint32, true}, 82de756853SMaciej Wawryk {"lvs_name", offsetof(struct rpc_bdev_lvol_create_lvstore, lvs_name), spdk_json_decode_string}, 83de756853SMaciej Wawryk {"clear_method", offsetof(struct rpc_bdev_lvol_create_lvstore, clear_method), spdk_json_decode_string, true}, 8488833020Syupeng {"num_md_pages_per_cluster_ratio", offsetof(struct rpc_bdev_lvol_create_lvstore, num_md_pages_per_cluster_ratio), spdk_json_decode_uint32, true}, 85*e0d7428bSAtul Malakar {"md_page_size", offsetof(struct rpc_bdev_lvol_create_lvstore, md_page_size), spdk_json_decode_uint32, true}, 8607fe6a43SSeth Howell }; 8707fe6a43SSeth Howell 8807fe6a43SSeth Howell static void 89c93e560fSSeth Howell rpc_lvol_store_construct_cb(void *cb_arg, struct spdk_lvol_store *lvol_store, int lvserrno) 9007fe6a43SSeth Howell { 9107fe6a43SSeth Howell struct spdk_json_write_ctx *w; 9207fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 9307fe6a43SSeth Howell 9407fe6a43SSeth Howell if (lvserrno != 0) { 9507fe6a43SSeth Howell goto invalid; 9607fe6a43SSeth Howell } 9707fe6a43SSeth Howell 9807fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request); 998cffbe01SKonrad Sztyber spdk_json_write_uuid(w, &lvol_store->uuid); 10007fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w); 10107fe6a43SSeth Howell return; 10207fe6a43SSeth Howell 10307fe6a43SSeth Howell invalid: 10407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 10507fe6a43SSeth Howell spdk_strerror(-lvserrno)); 10607fe6a43SSeth Howell } 10707fe6a43SSeth Howell 10807fe6a43SSeth Howell static void 109c93e560fSSeth Howell rpc_bdev_lvol_create_lvstore(struct spdk_jsonrpc_request *request, 11007fe6a43SSeth Howell const struct spdk_json_val *params) 11107fe6a43SSeth Howell { 112de756853SMaciej Wawryk struct rpc_bdev_lvol_create_lvstore req = {}; 11307fe6a43SSeth Howell int rc = 0; 11407fe6a43SSeth Howell enum lvs_clear_method clear_method; 11507fe6a43SSeth Howell 116de756853SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_create_lvstore_decoders, 117de756853SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_create_lvstore_decoders), 11807fe6a43SSeth Howell &req)) { 1192172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 12007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 12107fe6a43SSeth Howell "spdk_json_decode_object failed"); 12207fe6a43SSeth Howell goto cleanup; 12307fe6a43SSeth Howell } 12407fe6a43SSeth Howell 12507fe6a43SSeth Howell if (req.clear_method != NULL) { 12607fe6a43SSeth Howell if (!strcasecmp(req.clear_method, "none")) { 12707fe6a43SSeth Howell clear_method = LVS_CLEAR_WITH_NONE; 12807fe6a43SSeth Howell } else if (!strcasecmp(req.clear_method, "unmap")) { 12907fe6a43SSeth Howell clear_method = LVS_CLEAR_WITH_UNMAP; 13007fe6a43SSeth Howell } else if (!strcasecmp(req.clear_method, "write_zeroes")) { 13107fe6a43SSeth Howell clear_method = LVS_CLEAR_WITH_WRITE_ZEROES; 13207fe6a43SSeth Howell } else { 13307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clear_method parameter"); 13407fe6a43SSeth Howell goto cleanup; 13507fe6a43SSeth Howell } 13607fe6a43SSeth Howell } else { 13707fe6a43SSeth Howell clear_method = LVS_CLEAR_WITH_UNMAP; 13807fe6a43SSeth Howell } 13907fe6a43SSeth Howell 140*e0d7428bSAtul Malakar rc = vbdev_lvs_create_ext(req.bdev_name, req.lvs_name, req.cluster_sz, clear_method, 141*e0d7428bSAtul Malakar req.num_md_pages_per_cluster_ratio, req.md_page_size, 142*e0d7428bSAtul Malakar rpc_lvol_store_construct_cb, request); 14307fe6a43SSeth Howell if (rc < 0) { 144669069daSNathan Claudel spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 14507fe6a43SSeth Howell goto cleanup; 14607fe6a43SSeth Howell } 147de756853SMaciej Wawryk free_rpc_bdev_lvol_create_lvstore(&req); 14807fe6a43SSeth Howell 14907fe6a43SSeth Howell return; 15007fe6a43SSeth Howell 15107fe6a43SSeth Howell cleanup: 152de756853SMaciej Wawryk free_rpc_bdev_lvol_create_lvstore(&req); 15307fe6a43SSeth Howell } 154c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_create_lvstore", rpc_bdev_lvol_create_lvstore, SPDK_RPC_RUNTIME) 15507fe6a43SSeth Howell 15690e4ae5dSMaciej Wawryk struct rpc_bdev_lvol_rename_lvstore { 15707fe6a43SSeth Howell char *old_name; 15807fe6a43SSeth Howell char *new_name; 15907fe6a43SSeth Howell }; 16007fe6a43SSeth Howell 16107fe6a43SSeth Howell static void 16290e4ae5dSMaciej Wawryk free_rpc_bdev_lvol_rename_lvstore(struct rpc_bdev_lvol_rename_lvstore *req) 16307fe6a43SSeth Howell { 16407fe6a43SSeth Howell free(req->old_name); 16507fe6a43SSeth Howell free(req->new_name); 16607fe6a43SSeth Howell } 16707fe6a43SSeth Howell 16890e4ae5dSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_lvstore_decoders[] = { 16990e4ae5dSMaciej Wawryk {"old_name", offsetof(struct rpc_bdev_lvol_rename_lvstore, old_name), spdk_json_decode_string}, 17090e4ae5dSMaciej Wawryk {"new_name", offsetof(struct rpc_bdev_lvol_rename_lvstore, new_name), spdk_json_decode_string}, 17107fe6a43SSeth Howell }; 17207fe6a43SSeth Howell 17307fe6a43SSeth Howell static void 174c93e560fSSeth Howell rpc_bdev_lvol_rename_lvstore_cb(void *cb_arg, int lvserrno) 17507fe6a43SSeth Howell { 17607fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 17707fe6a43SSeth Howell 17807fe6a43SSeth Howell if (lvserrno != 0) { 17907fe6a43SSeth Howell goto invalid; 18007fe6a43SSeth Howell } 18107fe6a43SSeth Howell 182d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 18307fe6a43SSeth Howell return; 18407fe6a43SSeth Howell 18507fe6a43SSeth Howell invalid: 18607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 18707fe6a43SSeth Howell spdk_strerror(-lvserrno)); 18807fe6a43SSeth Howell } 18907fe6a43SSeth Howell 19007fe6a43SSeth Howell static void 191c93e560fSSeth Howell rpc_bdev_lvol_rename_lvstore(struct spdk_jsonrpc_request *request, 19207fe6a43SSeth Howell const struct spdk_json_val *params) 19307fe6a43SSeth Howell { 19490e4ae5dSMaciej Wawryk struct rpc_bdev_lvol_rename_lvstore req = {}; 19507fe6a43SSeth Howell struct spdk_lvol_store *lvs; 19607fe6a43SSeth Howell 19790e4ae5dSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_lvstore_decoders, 19890e4ae5dSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_rename_lvstore_decoders), 19907fe6a43SSeth Howell &req)) { 2002172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 20107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 20207fe6a43SSeth Howell "spdk_json_decode_object failed"); 20307fe6a43SSeth Howell goto cleanup; 20407fe6a43SSeth Howell } 20507fe6a43SSeth Howell 20607fe6a43SSeth Howell lvs = vbdev_get_lvol_store_by_name(req.old_name); 20707fe6a43SSeth Howell if (lvs == NULL) { 2082172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "no lvs existing for given name\n"); 20907fe6a43SSeth Howell spdk_jsonrpc_send_error_response_fmt(request, -ENOENT, "Lvol store %s not found", req.old_name); 21007fe6a43SSeth Howell goto cleanup; 21107fe6a43SSeth Howell } 21207fe6a43SSeth Howell 213c93e560fSSeth Howell vbdev_lvs_rename(lvs, req.new_name, rpc_bdev_lvol_rename_lvstore_cb, request); 21407fe6a43SSeth Howell 21507fe6a43SSeth Howell cleanup: 21690e4ae5dSMaciej Wawryk free_rpc_bdev_lvol_rename_lvstore(&req); 21707fe6a43SSeth Howell } 218c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_rename_lvstore", rpc_bdev_lvol_rename_lvstore, SPDK_RPC_RUNTIME) 21907fe6a43SSeth Howell 2204c049618SMaciej Wawryk struct rpc_bdev_lvol_delete_lvstore { 22107fe6a43SSeth Howell char *uuid; 22207fe6a43SSeth Howell char *lvs_name; 22307fe6a43SSeth Howell }; 22407fe6a43SSeth Howell 22507fe6a43SSeth Howell static void 2264c049618SMaciej Wawryk free_rpc_bdev_lvol_delete_lvstore(struct rpc_bdev_lvol_delete_lvstore *req) 22707fe6a43SSeth Howell { 22807fe6a43SSeth Howell free(req->uuid); 22907fe6a43SSeth Howell free(req->lvs_name); 23007fe6a43SSeth Howell } 23107fe6a43SSeth Howell 2324c049618SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_delete_lvstore_decoders[] = { 2334c049618SMaciej Wawryk {"uuid", offsetof(struct rpc_bdev_lvol_delete_lvstore, uuid), spdk_json_decode_string, true}, 2344c049618SMaciej Wawryk {"lvs_name", offsetof(struct rpc_bdev_lvol_delete_lvstore, lvs_name), spdk_json_decode_string, true}, 23507fe6a43SSeth Howell }; 23607fe6a43SSeth Howell 23707fe6a43SSeth Howell static void 238c93e560fSSeth Howell rpc_lvol_store_destroy_cb(void *cb_arg, int lvserrno) 23907fe6a43SSeth Howell { 24007fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 24107fe6a43SSeth Howell 24207fe6a43SSeth Howell if (lvserrno != 0) { 24307fe6a43SSeth Howell goto invalid; 24407fe6a43SSeth Howell } 24507fe6a43SSeth Howell 246d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 24707fe6a43SSeth Howell return; 24807fe6a43SSeth Howell 24907fe6a43SSeth Howell invalid: 25007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 25107fe6a43SSeth Howell spdk_strerror(-lvserrno)); 25207fe6a43SSeth Howell } 25307fe6a43SSeth Howell 25407fe6a43SSeth Howell static void 255c93e560fSSeth Howell rpc_bdev_lvol_delete_lvstore(struct spdk_jsonrpc_request *request, 25607fe6a43SSeth Howell const struct spdk_json_val *params) 25707fe6a43SSeth Howell { 2584c049618SMaciej Wawryk struct rpc_bdev_lvol_delete_lvstore req = {}; 25907fe6a43SSeth Howell struct spdk_lvol_store *lvs = NULL; 26007fe6a43SSeth Howell int rc; 26107fe6a43SSeth Howell 2624c049618SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_delete_lvstore_decoders, 2634c049618SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_delete_lvstore_decoders), 26407fe6a43SSeth Howell &req)) { 2652172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 26607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 26707fe6a43SSeth Howell "spdk_json_decode_object failed"); 26807fe6a43SSeth Howell goto cleanup; 26907fe6a43SSeth Howell } 27007fe6a43SSeth Howell 27107fe6a43SSeth Howell rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 27207fe6a43SSeth Howell if (rc != 0) { 27307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 27407fe6a43SSeth Howell goto cleanup; 27507fe6a43SSeth Howell } 27607fe6a43SSeth Howell 277c93e560fSSeth Howell vbdev_lvs_destruct(lvs, rpc_lvol_store_destroy_cb, request); 27807fe6a43SSeth Howell 27907fe6a43SSeth Howell cleanup: 2804c049618SMaciej Wawryk free_rpc_bdev_lvol_delete_lvstore(&req); 28107fe6a43SSeth Howell } 282c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_delete_lvstore", rpc_bdev_lvol_delete_lvstore, SPDK_RPC_RUNTIME) 28307fe6a43SSeth Howell 284c57cd922SMaciej Wawryk struct rpc_bdev_lvol_create { 28507fe6a43SSeth Howell char *uuid; 28607fe6a43SSeth Howell char *lvs_name; 28707fe6a43SSeth Howell char *lvol_name; 2882d590e74SSebastian Brzezinka uint64_t size_in_mib; 28907fe6a43SSeth Howell bool thin_provision; 29007fe6a43SSeth Howell char *clear_method; 29107fe6a43SSeth Howell }; 29207fe6a43SSeth Howell 29307fe6a43SSeth Howell static void 294c57cd922SMaciej Wawryk free_rpc_bdev_lvol_create(struct rpc_bdev_lvol_create *req) 29507fe6a43SSeth Howell { 29607fe6a43SSeth Howell free(req->uuid); 29707fe6a43SSeth Howell free(req->lvs_name); 29807fe6a43SSeth Howell free(req->lvol_name); 29907fe6a43SSeth Howell free(req->clear_method); 30007fe6a43SSeth Howell } 30107fe6a43SSeth Howell 302c57cd922SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_create_decoders[] = { 303c57cd922SMaciej Wawryk {"uuid", offsetof(struct rpc_bdev_lvol_create, uuid), spdk_json_decode_string, true}, 304c57cd922SMaciej Wawryk {"lvs_name", offsetof(struct rpc_bdev_lvol_create, lvs_name), spdk_json_decode_string, true}, 305c57cd922SMaciej Wawryk {"lvol_name", offsetof(struct rpc_bdev_lvol_create, lvol_name), spdk_json_decode_string}, 306ba31ad82SKonrad Sztyber {"size_in_mib", offsetof(struct rpc_bdev_lvol_create, size_in_mib), spdk_json_decode_uint64}, 307c57cd922SMaciej Wawryk {"thin_provision", offsetof(struct rpc_bdev_lvol_create, thin_provision), spdk_json_decode_bool, true}, 308c57cd922SMaciej Wawryk {"clear_method", offsetof(struct rpc_bdev_lvol_create, clear_method), spdk_json_decode_string, true}, 30907fe6a43SSeth Howell }; 31007fe6a43SSeth Howell 31107fe6a43SSeth Howell static void 312c93e560fSSeth Howell rpc_bdev_lvol_create_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 31307fe6a43SSeth Howell { 31407fe6a43SSeth Howell struct spdk_json_write_ctx *w; 31507fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 31607fe6a43SSeth Howell 31707fe6a43SSeth Howell if (lvolerrno != 0) { 31807fe6a43SSeth Howell goto invalid; 31907fe6a43SSeth Howell } 32007fe6a43SSeth Howell 32107fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request); 32207fe6a43SSeth Howell spdk_json_write_string(w, lvol->unique_id); 32307fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w); 32407fe6a43SSeth Howell return; 32507fe6a43SSeth Howell 32607fe6a43SSeth Howell invalid: 32707fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 32807fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 32907fe6a43SSeth Howell } 33007fe6a43SSeth Howell 33107fe6a43SSeth Howell static void 332c93e560fSSeth Howell rpc_bdev_lvol_create(struct spdk_jsonrpc_request *request, 33307fe6a43SSeth Howell const struct spdk_json_val *params) 33407fe6a43SSeth Howell { 335c57cd922SMaciej Wawryk struct rpc_bdev_lvol_create req = {}; 33607fe6a43SSeth Howell enum lvol_clear_method clear_method; 33707fe6a43SSeth Howell int rc = 0; 33807fe6a43SSeth Howell struct spdk_lvol_store *lvs = NULL; 33907fe6a43SSeth Howell 3402172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Creating blob\n"); 34107fe6a43SSeth Howell 342c57cd922SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_create_decoders, 343c57cd922SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_create_decoders), 34407fe6a43SSeth Howell &req)) { 3452172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 34607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 34707fe6a43SSeth Howell "spdk_json_decode_object failed"); 34807fe6a43SSeth Howell goto cleanup; 34907fe6a43SSeth Howell } 35007fe6a43SSeth Howell 35107fe6a43SSeth Howell rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 35207fe6a43SSeth Howell if (rc != 0) { 35307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 35407fe6a43SSeth Howell goto cleanup; 35507fe6a43SSeth Howell } 35607fe6a43SSeth Howell 35707fe6a43SSeth Howell if (req.clear_method != NULL) { 35807fe6a43SSeth Howell if (!strcasecmp(req.clear_method, "none")) { 35907fe6a43SSeth Howell clear_method = LVOL_CLEAR_WITH_NONE; 36007fe6a43SSeth Howell } else if (!strcasecmp(req.clear_method, "unmap")) { 36107fe6a43SSeth Howell clear_method = LVOL_CLEAR_WITH_UNMAP; 36207fe6a43SSeth Howell } else if (!strcasecmp(req.clear_method, "write_zeroes")) { 36307fe6a43SSeth Howell clear_method = LVOL_CLEAR_WITH_WRITE_ZEROES; 36407fe6a43SSeth Howell } else { 36507fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clean_method option"); 36607fe6a43SSeth Howell goto cleanup; 36707fe6a43SSeth Howell } 36807fe6a43SSeth Howell } else { 36907fe6a43SSeth Howell clear_method = LVOL_CLEAR_WITH_DEFAULT; 37007fe6a43SSeth Howell } 37107fe6a43SSeth Howell 372ba31ad82SKonrad Sztyber rc = vbdev_lvol_create(lvs, req.lvol_name, req.size_in_mib * 1024 * 1024, 373ba31ad82SKonrad Sztyber req.thin_provision, clear_method, rpc_bdev_lvol_create_cb, request); 37407fe6a43SSeth Howell if (rc < 0) { 37507fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 37607fe6a43SSeth Howell goto cleanup; 37707fe6a43SSeth Howell } 37807fe6a43SSeth Howell 37907fe6a43SSeth Howell cleanup: 380c57cd922SMaciej Wawryk free_rpc_bdev_lvol_create(&req); 38107fe6a43SSeth Howell } 38207fe6a43SSeth Howell 383c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_create", rpc_bdev_lvol_create, SPDK_RPC_RUNTIME) 38407fe6a43SSeth Howell 385f5cf8ea1SMaciej Wawryk struct rpc_bdev_lvol_snapshot { 38607fe6a43SSeth Howell char *lvol_name; 38707fe6a43SSeth Howell char *snapshot_name; 38807fe6a43SSeth Howell }; 38907fe6a43SSeth Howell 39007fe6a43SSeth Howell static void 391f5cf8ea1SMaciej Wawryk free_rpc_bdev_lvol_snapshot(struct rpc_bdev_lvol_snapshot *req) 39207fe6a43SSeth Howell { 39307fe6a43SSeth Howell free(req->lvol_name); 39407fe6a43SSeth Howell free(req->snapshot_name); 39507fe6a43SSeth Howell } 39607fe6a43SSeth Howell 397f5cf8ea1SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_snapshot_decoders[] = { 398f5cf8ea1SMaciej Wawryk {"lvol_name", offsetof(struct rpc_bdev_lvol_snapshot, lvol_name), spdk_json_decode_string}, 399f5cf8ea1SMaciej Wawryk {"snapshot_name", offsetof(struct rpc_bdev_lvol_snapshot, snapshot_name), spdk_json_decode_string}, 40007fe6a43SSeth Howell }; 40107fe6a43SSeth Howell 40207fe6a43SSeth Howell static void 403c93e560fSSeth Howell rpc_bdev_lvol_snapshot_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 40407fe6a43SSeth Howell { 40507fe6a43SSeth Howell struct spdk_json_write_ctx *w; 40607fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 40707fe6a43SSeth Howell 40807fe6a43SSeth Howell if (lvolerrno != 0) { 40907fe6a43SSeth Howell goto invalid; 41007fe6a43SSeth Howell } 41107fe6a43SSeth Howell 41207fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request); 41307fe6a43SSeth Howell spdk_json_write_string(w, lvol->unique_id); 41407fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w); 41507fe6a43SSeth Howell return; 41607fe6a43SSeth Howell 41707fe6a43SSeth Howell invalid: 41807fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 41907fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 42007fe6a43SSeth Howell } 42107fe6a43SSeth Howell 42207fe6a43SSeth Howell static void 423c93e560fSSeth Howell rpc_bdev_lvol_snapshot(struct spdk_jsonrpc_request *request, 42407fe6a43SSeth Howell const struct spdk_json_val *params) 42507fe6a43SSeth Howell { 426f5cf8ea1SMaciej Wawryk struct rpc_bdev_lvol_snapshot req = {}; 42707fe6a43SSeth Howell struct spdk_bdev *bdev; 42807fe6a43SSeth Howell struct spdk_lvol *lvol; 42907fe6a43SSeth Howell 4302172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Snapshotting blob\n"); 43107fe6a43SSeth Howell 432f5cf8ea1SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_snapshot_decoders, 433f5cf8ea1SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_snapshot_decoders), 43407fe6a43SSeth Howell &req)) { 4352172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 43607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 43707fe6a43SSeth Howell "spdk_json_decode_object failed"); 43807fe6a43SSeth Howell goto cleanup; 43907fe6a43SSeth Howell } 44007fe6a43SSeth Howell 44107fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.lvol_name); 44207fe6a43SSeth Howell if (bdev == NULL) { 4432172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.lvol_name); 44407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 44507fe6a43SSeth Howell goto cleanup; 44607fe6a43SSeth Howell } 44707fe6a43SSeth Howell 44807fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 44907fe6a43SSeth Howell if (lvol == NULL) { 45007fe6a43SSeth Howell SPDK_ERRLOG("lvol does not exist\n"); 45107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 45207fe6a43SSeth Howell goto cleanup; 45307fe6a43SSeth Howell } 45407fe6a43SSeth Howell 455c93e560fSSeth Howell vbdev_lvol_create_snapshot(lvol, req.snapshot_name, rpc_bdev_lvol_snapshot_cb, request); 45607fe6a43SSeth Howell 45707fe6a43SSeth Howell cleanup: 458f5cf8ea1SMaciej Wawryk free_rpc_bdev_lvol_snapshot(&req); 45907fe6a43SSeth Howell } 46007fe6a43SSeth Howell 461c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_snapshot", rpc_bdev_lvol_snapshot, SPDK_RPC_RUNTIME) 46207fe6a43SSeth Howell 463827b2667SMaciej Wawryk struct rpc_bdev_lvol_clone { 46407fe6a43SSeth Howell char *snapshot_name; 46507fe6a43SSeth Howell char *clone_name; 46607fe6a43SSeth Howell }; 46707fe6a43SSeth Howell 46807fe6a43SSeth Howell static void 469827b2667SMaciej Wawryk free_rpc_bdev_lvol_clone(struct rpc_bdev_lvol_clone *req) 47007fe6a43SSeth Howell { 47107fe6a43SSeth Howell free(req->snapshot_name); 47207fe6a43SSeth Howell free(req->clone_name); 47307fe6a43SSeth Howell } 47407fe6a43SSeth Howell 475827b2667SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_decoders[] = { 476827b2667SMaciej Wawryk {"snapshot_name", offsetof(struct rpc_bdev_lvol_clone, snapshot_name), spdk_json_decode_string}, 477827b2667SMaciej Wawryk {"clone_name", offsetof(struct rpc_bdev_lvol_clone, clone_name), spdk_json_decode_string, true}, 47807fe6a43SSeth Howell }; 47907fe6a43SSeth Howell 48007fe6a43SSeth Howell static void 481c93e560fSSeth Howell rpc_bdev_lvol_clone_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno) 48207fe6a43SSeth Howell { 48307fe6a43SSeth Howell struct spdk_json_write_ctx *w; 48407fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 48507fe6a43SSeth Howell 48607fe6a43SSeth Howell if (lvolerrno != 0) { 48707fe6a43SSeth Howell goto invalid; 48807fe6a43SSeth Howell } 48907fe6a43SSeth Howell 49007fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request); 49107fe6a43SSeth Howell spdk_json_write_string(w, lvol->unique_id); 49207fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w); 49307fe6a43SSeth Howell return; 49407fe6a43SSeth Howell 49507fe6a43SSeth Howell invalid: 49607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 49707fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 49807fe6a43SSeth Howell } 49907fe6a43SSeth Howell 50007fe6a43SSeth Howell static void 501c93e560fSSeth Howell rpc_bdev_lvol_clone(struct spdk_jsonrpc_request *request, 50207fe6a43SSeth Howell const struct spdk_json_val *params) 50307fe6a43SSeth Howell { 504827b2667SMaciej Wawryk struct rpc_bdev_lvol_clone req = {}; 50507fe6a43SSeth Howell struct spdk_bdev *bdev; 50607fe6a43SSeth Howell struct spdk_lvol *lvol; 50707fe6a43SSeth Howell 5082172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Cloning blob\n"); 50907fe6a43SSeth Howell 510827b2667SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_decoders, 511827b2667SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_clone_decoders), 51207fe6a43SSeth Howell &req)) { 5132172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 51407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 51507fe6a43SSeth Howell "spdk_json_decode_object failed"); 51607fe6a43SSeth Howell goto cleanup; 51707fe6a43SSeth Howell } 51807fe6a43SSeth Howell 51907fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.snapshot_name); 52007fe6a43SSeth Howell if (bdev == NULL) { 5212172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.snapshot_name); 52207fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 52307fe6a43SSeth Howell goto cleanup; 52407fe6a43SSeth Howell } 52507fe6a43SSeth Howell 52607fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 52707fe6a43SSeth Howell if (lvol == NULL) { 52807fe6a43SSeth Howell SPDK_ERRLOG("lvol does not exist\n"); 52907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 53007fe6a43SSeth Howell goto cleanup; 53107fe6a43SSeth Howell } 53207fe6a43SSeth Howell 533c93e560fSSeth Howell vbdev_lvol_create_clone(lvol, req.clone_name, rpc_bdev_lvol_clone_cb, request); 53407fe6a43SSeth Howell 53507fe6a43SSeth Howell cleanup: 536827b2667SMaciej Wawryk free_rpc_bdev_lvol_clone(&req); 53707fe6a43SSeth Howell } 53807fe6a43SSeth Howell 539c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_clone", rpc_bdev_lvol_clone, SPDK_RPC_RUNTIME) 54007fe6a43SSeth Howell 541a67e0eb3SMike Gerdts struct rpc_bdev_lvol_clone_bdev { 542a67e0eb3SMike Gerdts /* name or UUID. Whichever is used, the UUID will be stored in the lvol's metadata. */ 543a67e0eb3SMike Gerdts char *bdev_name; 544a67e0eb3SMike Gerdts char *lvs_name; 545a67e0eb3SMike Gerdts char *clone_name; 546a67e0eb3SMike Gerdts }; 547a67e0eb3SMike Gerdts 548a67e0eb3SMike Gerdts static void 549a67e0eb3SMike Gerdts free_rpc_bdev_lvol_clone_bdev(struct rpc_bdev_lvol_clone_bdev *req) 550a67e0eb3SMike Gerdts { 551a67e0eb3SMike Gerdts free(req->bdev_name); 552a67e0eb3SMike Gerdts free(req->lvs_name); 553a67e0eb3SMike Gerdts free(req->clone_name); 554a67e0eb3SMike Gerdts } 555a67e0eb3SMike Gerdts 556a67e0eb3SMike Gerdts static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_bdev_decoders[] = { 557a67e0eb3SMike Gerdts { 558a67e0eb3SMike Gerdts "bdev", offsetof(struct rpc_bdev_lvol_clone_bdev, bdev_name), 559a67e0eb3SMike Gerdts spdk_json_decode_string, false 560a67e0eb3SMike Gerdts }, 561a67e0eb3SMike Gerdts { 562a67e0eb3SMike Gerdts "lvs_name", offsetof(struct rpc_bdev_lvol_clone_bdev, lvs_name), 563a67e0eb3SMike Gerdts spdk_json_decode_string, false 564a67e0eb3SMike Gerdts }, 565a67e0eb3SMike Gerdts { 566a67e0eb3SMike Gerdts "clone_name", offsetof(struct rpc_bdev_lvol_clone_bdev, clone_name), 567a67e0eb3SMike Gerdts spdk_json_decode_string, false 568a67e0eb3SMike Gerdts }, 569a67e0eb3SMike Gerdts }; 570a67e0eb3SMike Gerdts 571a67e0eb3SMike Gerdts static void 572a67e0eb3SMike Gerdts rpc_bdev_lvol_clone_bdev(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) 573a67e0eb3SMike Gerdts { 574a67e0eb3SMike Gerdts struct rpc_bdev_lvol_clone_bdev req = {}; 575a67e0eb3SMike Gerdts struct spdk_bdev *bdev; 576a67e0eb3SMike Gerdts struct spdk_lvol_store *lvs = NULL; 577a67e0eb3SMike Gerdts struct spdk_lvol *lvol; 578a67e0eb3SMike Gerdts int rc; 579a67e0eb3SMike Gerdts 580a67e0eb3SMike Gerdts SPDK_INFOLOG(lvol_rpc, "Cloning bdev\n"); 581a67e0eb3SMike Gerdts 582a67e0eb3SMike Gerdts if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_bdev_decoders, 583a67e0eb3SMike Gerdts SPDK_COUNTOF(rpc_bdev_lvol_clone_bdev_decoders), &req)) { 584a67e0eb3SMike Gerdts SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 585a67e0eb3SMike Gerdts spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 586a67e0eb3SMike Gerdts "spdk_json_decode_object failed"); 587a67e0eb3SMike Gerdts goto cleanup; 588a67e0eb3SMike Gerdts } 589a67e0eb3SMike Gerdts 590a67e0eb3SMike Gerdts rc = vbdev_get_lvol_store_by_uuid_xor_name(NULL, req.lvs_name, &lvs); 591a67e0eb3SMike Gerdts if (rc != 0) { 592a67e0eb3SMike Gerdts SPDK_INFOLOG(lvol_rpc, "lvs_name '%s' not found\n", req.lvs_name); 593a67e0eb3SMike Gerdts spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 594a67e0eb3SMike Gerdts "lvs does not exist"); 595a67e0eb3SMike Gerdts goto cleanup; 596a67e0eb3SMike Gerdts } 597a67e0eb3SMike Gerdts 598a67e0eb3SMike Gerdts bdev = spdk_bdev_get_by_name(req.bdev_name); 599a67e0eb3SMike Gerdts if (bdev == NULL) { 600a67e0eb3SMike Gerdts SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.bdev_name); 601a67e0eb3SMike Gerdts spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 602a67e0eb3SMike Gerdts "bdev does not exist"); 603a67e0eb3SMike Gerdts goto cleanup; 604a67e0eb3SMike Gerdts } 605a67e0eb3SMike Gerdts 606a67e0eb3SMike Gerdts lvol = vbdev_lvol_get_from_bdev(bdev); 607a67e0eb3SMike Gerdts if (lvol != NULL && lvol->lvol_store == lvs) { 608a67e0eb3SMike Gerdts SPDK_INFOLOG(lvol_rpc, "bdev '%s' is an lvol in lvstore '%s\n", req.bdev_name, 609a67e0eb3SMike Gerdts req.lvs_name); 610a67e0eb3SMike Gerdts spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 611a67e0eb3SMike Gerdts "bdev is an lvol in same lvs as clone; " 612a67e0eb3SMike Gerdts "use bdev_lvol_clone instead"); 613a67e0eb3SMike Gerdts goto cleanup; 614a67e0eb3SMike Gerdts } 615a67e0eb3SMike Gerdts 616a67e0eb3SMike Gerdts vbdev_lvol_create_bdev_clone(req.bdev_name, lvs, req.clone_name, 617a67e0eb3SMike Gerdts rpc_bdev_lvol_clone_cb, request); 618a67e0eb3SMike Gerdts cleanup: 619a67e0eb3SMike Gerdts free_rpc_bdev_lvol_clone_bdev(&req); 620a67e0eb3SMike Gerdts } 621a67e0eb3SMike Gerdts 622a67e0eb3SMike Gerdts SPDK_RPC_REGISTER("bdev_lvol_clone_bdev", rpc_bdev_lvol_clone_bdev, SPDK_RPC_RUNTIME) 623a67e0eb3SMike Gerdts 6240ce883ceSMaciej Wawryk struct rpc_bdev_lvol_rename { 62507fe6a43SSeth Howell char *old_name; 62607fe6a43SSeth Howell char *new_name; 62707fe6a43SSeth Howell }; 62807fe6a43SSeth Howell 62907fe6a43SSeth Howell static void 6300ce883ceSMaciej Wawryk free_rpc_bdev_lvol_rename(struct rpc_bdev_lvol_rename *req) 63107fe6a43SSeth Howell { 63207fe6a43SSeth Howell free(req->old_name); 63307fe6a43SSeth Howell free(req->new_name); 63407fe6a43SSeth Howell } 63507fe6a43SSeth Howell 6360ce883ceSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_decoders[] = { 6370ce883ceSMaciej Wawryk {"old_name", offsetof(struct rpc_bdev_lvol_rename, old_name), spdk_json_decode_string}, 6380ce883ceSMaciej Wawryk {"new_name", offsetof(struct rpc_bdev_lvol_rename, new_name), spdk_json_decode_string}, 63907fe6a43SSeth Howell }; 64007fe6a43SSeth Howell 64107fe6a43SSeth Howell static void 642c93e560fSSeth Howell rpc_bdev_lvol_rename_cb(void *cb_arg, int lvolerrno) 64307fe6a43SSeth Howell { 64407fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 64507fe6a43SSeth Howell 64607fe6a43SSeth Howell if (lvolerrno != 0) { 64707fe6a43SSeth Howell goto invalid; 64807fe6a43SSeth Howell } 64907fe6a43SSeth Howell 650d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 65107fe6a43SSeth Howell return; 65207fe6a43SSeth Howell 65307fe6a43SSeth Howell invalid: 65407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 65507fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 65607fe6a43SSeth Howell } 65707fe6a43SSeth Howell 65807fe6a43SSeth Howell static void 659c93e560fSSeth Howell rpc_bdev_lvol_rename(struct spdk_jsonrpc_request *request, 66007fe6a43SSeth Howell const struct spdk_json_val *params) 66107fe6a43SSeth Howell { 6620ce883ceSMaciej Wawryk struct rpc_bdev_lvol_rename req = {}; 66307fe6a43SSeth Howell struct spdk_bdev *bdev; 66407fe6a43SSeth Howell struct spdk_lvol *lvol; 66507fe6a43SSeth Howell 6662172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Renaming lvol\n"); 66707fe6a43SSeth Howell 6680ce883ceSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_decoders, 6690ce883ceSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_rename_decoders), 67007fe6a43SSeth Howell &req)) { 6712172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 67207fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 67307fe6a43SSeth Howell "spdk_json_decode_object failed"); 67407fe6a43SSeth Howell goto cleanup; 67507fe6a43SSeth Howell } 67607fe6a43SSeth Howell 67707fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.old_name); 67807fe6a43SSeth Howell if (bdev == NULL) { 67907fe6a43SSeth Howell SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name); 68007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 68107fe6a43SSeth Howell goto cleanup; 68207fe6a43SSeth Howell } 68307fe6a43SSeth Howell 68407fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 68507fe6a43SSeth Howell if (lvol == NULL) { 68607fe6a43SSeth Howell SPDK_ERRLOG("lvol does not exist\n"); 68707fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 68807fe6a43SSeth Howell goto cleanup; 68907fe6a43SSeth Howell } 69007fe6a43SSeth Howell 691c93e560fSSeth Howell vbdev_lvol_rename(lvol, req.new_name, rpc_bdev_lvol_rename_cb, request); 69207fe6a43SSeth Howell 69307fe6a43SSeth Howell cleanup: 6940ce883ceSMaciej Wawryk free_rpc_bdev_lvol_rename(&req); 69507fe6a43SSeth Howell } 69607fe6a43SSeth Howell 697c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_rename", rpc_bdev_lvol_rename, SPDK_RPC_RUNTIME) 69807fe6a43SSeth Howell 6997a294f4cSMaciej Wawryk struct rpc_bdev_lvol_inflate { 70007fe6a43SSeth Howell char *name; 70107fe6a43SSeth Howell }; 70207fe6a43SSeth Howell 70307fe6a43SSeth Howell static void 7047a294f4cSMaciej Wawryk free_rpc_bdev_lvol_inflate(struct rpc_bdev_lvol_inflate *req) 70507fe6a43SSeth Howell { 70607fe6a43SSeth Howell free(req->name); 70707fe6a43SSeth Howell } 70807fe6a43SSeth Howell 7097a294f4cSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_inflate_decoders[] = { 7107a294f4cSMaciej Wawryk {"name", offsetof(struct rpc_bdev_lvol_inflate, name), spdk_json_decode_string}, 71107fe6a43SSeth Howell }; 71207fe6a43SSeth Howell 71307fe6a43SSeth Howell static void 714c93e560fSSeth Howell rpc_bdev_lvol_inflate_cb(void *cb_arg, int lvolerrno) 71507fe6a43SSeth Howell { 71607fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 71707fe6a43SSeth Howell 71807fe6a43SSeth Howell if (lvolerrno != 0) { 71907fe6a43SSeth Howell goto invalid; 72007fe6a43SSeth Howell } 72107fe6a43SSeth Howell 722d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 72307fe6a43SSeth Howell return; 72407fe6a43SSeth Howell 72507fe6a43SSeth Howell invalid: 72607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 72707fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 72807fe6a43SSeth Howell } 72907fe6a43SSeth Howell 73007fe6a43SSeth Howell static void 731c93e560fSSeth Howell rpc_bdev_lvol_inflate(struct spdk_jsonrpc_request *request, 73207fe6a43SSeth Howell const struct spdk_json_val *params) 73307fe6a43SSeth Howell { 7347a294f4cSMaciej Wawryk struct rpc_bdev_lvol_inflate req = {}; 73507fe6a43SSeth Howell struct spdk_bdev *bdev; 73607fe6a43SSeth Howell struct spdk_lvol *lvol; 73707fe6a43SSeth Howell 7382172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Inflating lvol\n"); 73907fe6a43SSeth Howell 7407a294f4cSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders, 7417a294f4cSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders), 74207fe6a43SSeth Howell &req)) { 7432172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 74407fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 74507fe6a43SSeth Howell "spdk_json_decode_object failed"); 74607fe6a43SSeth Howell goto cleanup; 74707fe6a43SSeth Howell } 74807fe6a43SSeth Howell 74907fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.name); 75007fe6a43SSeth Howell if (bdev == NULL) { 75107fe6a43SSeth Howell SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 75207fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 75307fe6a43SSeth Howell goto cleanup; 75407fe6a43SSeth Howell } 75507fe6a43SSeth Howell 75607fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 75707fe6a43SSeth Howell if (lvol == NULL) { 75807fe6a43SSeth Howell SPDK_ERRLOG("lvol does not exist\n"); 75907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 76007fe6a43SSeth Howell goto cleanup; 76107fe6a43SSeth Howell } 76207fe6a43SSeth Howell 763c93e560fSSeth Howell spdk_lvol_inflate(lvol, rpc_bdev_lvol_inflate_cb, request); 76407fe6a43SSeth Howell 76507fe6a43SSeth Howell cleanup: 7667a294f4cSMaciej Wawryk free_rpc_bdev_lvol_inflate(&req); 76707fe6a43SSeth Howell } 76807fe6a43SSeth Howell 769c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_inflate", rpc_bdev_lvol_inflate, SPDK_RPC_RUNTIME) 77007fe6a43SSeth Howell 77107fe6a43SSeth Howell static void 772c93e560fSSeth Howell rpc_bdev_lvol_decouple_parent(struct spdk_jsonrpc_request *request, 77307fe6a43SSeth Howell const struct spdk_json_val *params) 77407fe6a43SSeth Howell { 7757a294f4cSMaciej Wawryk struct rpc_bdev_lvol_inflate req = {}; 77607fe6a43SSeth Howell struct spdk_bdev *bdev; 77707fe6a43SSeth Howell struct spdk_lvol *lvol; 77807fe6a43SSeth Howell 7792172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Decoupling parent of lvol\n"); 78007fe6a43SSeth Howell 7817a294f4cSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders, 7827a294f4cSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders), 78307fe6a43SSeth Howell &req)) { 7842172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 78507fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 78607fe6a43SSeth Howell "spdk_json_decode_object failed"); 78707fe6a43SSeth Howell goto cleanup; 78807fe6a43SSeth Howell } 78907fe6a43SSeth Howell 79007fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.name); 79107fe6a43SSeth Howell if (bdev == NULL) { 79207fe6a43SSeth Howell SPDK_ERRLOG("bdev '%s' does not exist\n", req.name); 79307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 79407fe6a43SSeth Howell goto cleanup; 79507fe6a43SSeth Howell } 79607fe6a43SSeth Howell 79707fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 79807fe6a43SSeth Howell if (lvol == NULL) { 79907fe6a43SSeth Howell SPDK_ERRLOG("lvol does not exist\n"); 80007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 80107fe6a43SSeth Howell goto cleanup; 80207fe6a43SSeth Howell } 80307fe6a43SSeth Howell 804c93e560fSSeth Howell spdk_lvol_decouple_parent(lvol, rpc_bdev_lvol_inflate_cb, request); 80507fe6a43SSeth Howell 80607fe6a43SSeth Howell cleanup: 8077a294f4cSMaciej Wawryk free_rpc_bdev_lvol_inflate(&req); 80807fe6a43SSeth Howell } 80907fe6a43SSeth Howell 810c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_decouple_parent", rpc_bdev_lvol_decouple_parent, SPDK_RPC_RUNTIME) 81107fe6a43SSeth Howell 812c2d85bb2SMaciej Wawryk struct rpc_bdev_lvol_resize { 81307fe6a43SSeth Howell char *name; 8142d590e74SSebastian Brzezinka uint64_t size_in_mib; 81507fe6a43SSeth Howell }; 81607fe6a43SSeth Howell 81707fe6a43SSeth Howell static void 818c2d85bb2SMaciej Wawryk free_rpc_bdev_lvol_resize(struct rpc_bdev_lvol_resize *req) 81907fe6a43SSeth Howell { 82007fe6a43SSeth Howell free(req->name); 82107fe6a43SSeth Howell } 82207fe6a43SSeth Howell 823c2d85bb2SMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_resize_decoders[] = { 824c2d85bb2SMaciej Wawryk {"name", offsetof(struct rpc_bdev_lvol_resize, name), spdk_json_decode_string}, 825ba31ad82SKonrad Sztyber {"size_in_mib", offsetof(struct rpc_bdev_lvol_resize, size_in_mib), spdk_json_decode_uint64}, 82607fe6a43SSeth Howell }; 82707fe6a43SSeth Howell 82807fe6a43SSeth Howell static void 829c93e560fSSeth Howell rpc_bdev_lvol_resize_cb(void *cb_arg, int lvolerrno) 83007fe6a43SSeth Howell { 83107fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 83207fe6a43SSeth Howell 83307fe6a43SSeth Howell if (lvolerrno != 0) { 83407fe6a43SSeth Howell goto invalid; 83507fe6a43SSeth Howell } 83607fe6a43SSeth Howell 837d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 83807fe6a43SSeth Howell return; 83907fe6a43SSeth Howell 84007fe6a43SSeth Howell invalid: 84107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 84207fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 84307fe6a43SSeth Howell } 84407fe6a43SSeth Howell 84507fe6a43SSeth Howell static void 846c93e560fSSeth Howell rpc_bdev_lvol_resize(struct spdk_jsonrpc_request *request, 84707fe6a43SSeth Howell const struct spdk_json_val *params) 84807fe6a43SSeth Howell { 849c2d85bb2SMaciej Wawryk struct rpc_bdev_lvol_resize req = {}; 85007fe6a43SSeth Howell struct spdk_bdev *bdev; 85107fe6a43SSeth Howell struct spdk_lvol *lvol; 85207fe6a43SSeth Howell 8532172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Resizing lvol\n"); 85407fe6a43SSeth Howell 855c2d85bb2SMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_resize_decoders, 856c2d85bb2SMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_resize_decoders), 85707fe6a43SSeth Howell &req)) { 8582172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 85907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 86007fe6a43SSeth Howell "spdk_json_decode_object failed"); 86107fe6a43SSeth Howell goto cleanup; 86207fe6a43SSeth Howell } 86307fe6a43SSeth Howell 86407fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.name); 86507fe6a43SSeth Howell if (bdev == NULL) { 86607fe6a43SSeth Howell SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 86707fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 86807fe6a43SSeth Howell goto cleanup; 86907fe6a43SSeth Howell } 87007fe6a43SSeth Howell 87107fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 87207fe6a43SSeth Howell if (lvol == NULL) { 87307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 87407fe6a43SSeth Howell goto cleanup; 87507fe6a43SSeth Howell } 87607fe6a43SSeth Howell 8772d590e74SSebastian Brzezinka 878ba31ad82SKonrad Sztyber vbdev_lvol_resize(lvol, req.size_in_mib * 1024 * 1024, rpc_bdev_lvol_resize_cb, request); 87907fe6a43SSeth Howell 88007fe6a43SSeth Howell cleanup: 881c2d85bb2SMaciej Wawryk free_rpc_bdev_lvol_resize(&req); 88207fe6a43SSeth Howell } 88307fe6a43SSeth Howell 884c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_resize", rpc_bdev_lvol_resize, SPDK_RPC_RUNTIME) 88507fe6a43SSeth Howell 88607fe6a43SSeth Howell struct rpc_set_ro_lvol_bdev { 88707fe6a43SSeth Howell char *name; 88807fe6a43SSeth Howell }; 88907fe6a43SSeth Howell 89007fe6a43SSeth Howell static void 89107fe6a43SSeth Howell free_rpc_set_ro_lvol_bdev(struct rpc_set_ro_lvol_bdev *req) 89207fe6a43SSeth Howell { 89307fe6a43SSeth Howell free(req->name); 89407fe6a43SSeth Howell } 89507fe6a43SSeth Howell 89607fe6a43SSeth Howell static const struct spdk_json_object_decoder rpc_set_ro_lvol_bdev_decoders[] = { 89707fe6a43SSeth Howell {"name", offsetof(struct rpc_set_ro_lvol_bdev, name), spdk_json_decode_string}, 89807fe6a43SSeth Howell }; 89907fe6a43SSeth Howell 90007fe6a43SSeth Howell static void 901c93e560fSSeth Howell rpc_set_ro_lvol_bdev_cb(void *cb_arg, int lvolerrno) 90207fe6a43SSeth Howell { 90307fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 90407fe6a43SSeth Howell 90507fe6a43SSeth Howell if (lvolerrno != 0) { 90607fe6a43SSeth Howell goto invalid; 90707fe6a43SSeth Howell } 90807fe6a43SSeth Howell 909d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 91007fe6a43SSeth Howell return; 91107fe6a43SSeth Howell 91207fe6a43SSeth Howell invalid: 91307fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 91407fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 91507fe6a43SSeth Howell } 91607fe6a43SSeth Howell 91707fe6a43SSeth Howell static void 918c93e560fSSeth Howell rpc_bdev_lvol_set_read_only(struct spdk_jsonrpc_request *request, 91907fe6a43SSeth Howell const struct spdk_json_val *params) 92007fe6a43SSeth Howell { 92107fe6a43SSeth Howell struct rpc_set_ro_lvol_bdev req = {}; 92207fe6a43SSeth Howell struct spdk_bdev *bdev; 92307fe6a43SSeth Howell struct spdk_lvol *lvol; 92407fe6a43SSeth Howell 9252172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "Setting lvol as read only\n"); 92607fe6a43SSeth Howell 92707fe6a43SSeth Howell if (spdk_json_decode_object(params, rpc_set_ro_lvol_bdev_decoders, 92807fe6a43SSeth Howell SPDK_COUNTOF(rpc_set_ro_lvol_bdev_decoders), 92907fe6a43SSeth Howell &req)) { 9302172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 93107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 93207fe6a43SSeth Howell "spdk_json_decode_object failed"); 93307fe6a43SSeth Howell goto cleanup; 93407fe6a43SSeth Howell } 93507fe6a43SSeth Howell 93607fe6a43SSeth Howell if (req.name == NULL) { 93707fe6a43SSeth Howell SPDK_ERRLOG("missing name param\n"); 93807fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -EINVAL, "Missing name parameter"); 93907fe6a43SSeth Howell goto cleanup; 94007fe6a43SSeth Howell } 94107fe6a43SSeth Howell 94207fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.name); 94307fe6a43SSeth Howell if (bdev == NULL) { 94407fe6a43SSeth Howell SPDK_ERRLOG("no bdev for provided name %s\n", req.name); 94507fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 94607fe6a43SSeth Howell goto cleanup; 94707fe6a43SSeth Howell } 94807fe6a43SSeth Howell 94907fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 95007fe6a43SSeth Howell if (lvol == NULL) { 95107fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 95207fe6a43SSeth Howell goto cleanup; 95307fe6a43SSeth Howell } 95407fe6a43SSeth Howell 955c93e560fSSeth Howell vbdev_lvol_set_read_only(lvol, rpc_set_ro_lvol_bdev_cb, request); 95607fe6a43SSeth Howell 95707fe6a43SSeth Howell cleanup: 95807fe6a43SSeth Howell free_rpc_set_ro_lvol_bdev(&req); 95907fe6a43SSeth Howell } 96007fe6a43SSeth Howell 961c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_set_read_only", rpc_bdev_lvol_set_read_only, SPDK_RPC_RUNTIME) 96207fe6a43SSeth Howell 963b5fdf4ecSMaciej Wawryk struct rpc_bdev_lvol_delete { 96407fe6a43SSeth Howell char *name; 96507fe6a43SSeth Howell }; 96607fe6a43SSeth Howell 96707fe6a43SSeth Howell static void 968b5fdf4ecSMaciej Wawryk free_rpc_bdev_lvol_delete(struct rpc_bdev_lvol_delete *req) 96907fe6a43SSeth Howell { 97007fe6a43SSeth Howell free(req->name); 97107fe6a43SSeth Howell } 97207fe6a43SSeth Howell 973b5fdf4ecSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_delete_decoders[] = { 974b5fdf4ecSMaciej Wawryk {"name", offsetof(struct rpc_bdev_lvol_delete, name), spdk_json_decode_string}, 97507fe6a43SSeth Howell }; 97607fe6a43SSeth Howell 97707fe6a43SSeth Howell static void 978c93e560fSSeth Howell rpc_bdev_lvol_delete_cb(void *cb_arg, int lvolerrno) 97907fe6a43SSeth Howell { 98007fe6a43SSeth Howell struct spdk_jsonrpc_request *request = cb_arg; 98107fe6a43SSeth Howell 98207fe6a43SSeth Howell if (lvolerrno != 0) { 98307fe6a43SSeth Howell goto invalid; 98407fe6a43SSeth Howell } 98507fe6a43SSeth Howell 986d73077b8Syidong0635 spdk_jsonrpc_send_bool_response(request, true); 98707fe6a43SSeth Howell return; 98807fe6a43SSeth Howell 98907fe6a43SSeth Howell invalid: 99007fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 99107fe6a43SSeth Howell spdk_strerror(-lvolerrno)); 99207fe6a43SSeth Howell } 99307fe6a43SSeth Howell 99407fe6a43SSeth Howell static void 995c93e560fSSeth Howell rpc_bdev_lvol_delete(struct spdk_jsonrpc_request *request, 99607fe6a43SSeth Howell const struct spdk_json_val *params) 99707fe6a43SSeth Howell { 998b5fdf4ecSMaciej Wawryk struct rpc_bdev_lvol_delete req = {}; 99907fe6a43SSeth Howell struct spdk_bdev *bdev; 100007fe6a43SSeth Howell struct spdk_lvol *lvol; 1001c0ea96cfSMike Gerdts struct spdk_uuid uuid; 1002c0ea96cfSMike Gerdts char *lvs_name, *lvol_name; 100307fe6a43SSeth Howell 1004b5fdf4ecSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_delete_decoders, 1005b5fdf4ecSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_delete_decoders), 100607fe6a43SSeth Howell &req)) { 10072172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 100807fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 100907fe6a43SSeth Howell "spdk_json_decode_object failed"); 101007fe6a43SSeth Howell goto cleanup; 101107fe6a43SSeth Howell } 101207fe6a43SSeth Howell 1013c0ea96cfSMike Gerdts /* lvol is not degraded, get lvol via bdev name or alias */ 101407fe6a43SSeth Howell bdev = spdk_bdev_get_by_name(req.name); 1015c0ea96cfSMike Gerdts if (bdev != NULL) { 101607fe6a43SSeth Howell lvol = vbdev_lvol_get_from_bdev(bdev); 1017c0ea96cfSMike Gerdts if (lvol != NULL) { 1018c0ea96cfSMike Gerdts goto done; 1019c0ea96cfSMike Gerdts } 102007fe6a43SSeth Howell } 102107fe6a43SSeth Howell 1022c0ea96cfSMike Gerdts /* lvol is degraded, get lvol via UUID */ 1023c0ea96cfSMike Gerdts if (spdk_uuid_parse(&uuid, req.name) == 0) { 1024c0ea96cfSMike Gerdts lvol = spdk_lvol_get_by_uuid(&uuid); 1025c0ea96cfSMike Gerdts if (lvol != NULL) { 1026c0ea96cfSMike Gerdts goto done; 1027c0ea96cfSMike Gerdts } 1028c0ea96cfSMike Gerdts } 1029c0ea96cfSMike Gerdts 1030c0ea96cfSMike Gerdts /* lvol is degraded, get lvol via lvs_name/lvol_name */ 1031c0ea96cfSMike Gerdts lvol_name = strchr(req.name, '/'); 1032c0ea96cfSMike Gerdts if (lvol_name != NULL) { 1033c0ea96cfSMike Gerdts *lvol_name = '\0'; 1034c0ea96cfSMike Gerdts lvol_name++; 1035c0ea96cfSMike Gerdts lvs_name = req.name; 1036c0ea96cfSMike Gerdts lvol = spdk_lvol_get_by_names(lvs_name, lvol_name); 1037c0ea96cfSMike Gerdts if (lvol != NULL) { 1038c0ea96cfSMike Gerdts goto done; 1039c0ea96cfSMike Gerdts } 1040c0ea96cfSMike Gerdts } 1041c0ea96cfSMike Gerdts 1042c0ea96cfSMike Gerdts /* Could not find lvol, degraded or not. */ 1043c0ea96cfSMike Gerdts spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 1044c0ea96cfSMike Gerdts goto cleanup; 1045c0ea96cfSMike Gerdts 1046c0ea96cfSMike Gerdts done: 1047c93e560fSSeth Howell vbdev_lvol_destroy(lvol, rpc_bdev_lvol_delete_cb, request); 104807fe6a43SSeth Howell 104907fe6a43SSeth Howell cleanup: 1050b5fdf4ecSMaciej Wawryk free_rpc_bdev_lvol_delete(&req); 105107fe6a43SSeth Howell } 105207fe6a43SSeth Howell 1053c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_delete", rpc_bdev_lvol_delete, SPDK_RPC_RUNTIME) 105407fe6a43SSeth Howell 10550b3f378fSMaciej Wawryk struct rpc_bdev_lvol_get_lvstores { 105607fe6a43SSeth Howell char *uuid; 105707fe6a43SSeth Howell char *lvs_name; 105807fe6a43SSeth Howell }; 105907fe6a43SSeth Howell 106007fe6a43SSeth Howell static void 10610b3f378fSMaciej Wawryk free_rpc_bdev_lvol_get_lvstores(struct rpc_bdev_lvol_get_lvstores *req) 106207fe6a43SSeth Howell { 106307fe6a43SSeth Howell free(req->uuid); 106407fe6a43SSeth Howell free(req->lvs_name); 106507fe6a43SSeth Howell } 106607fe6a43SSeth Howell 10670b3f378fSMaciej Wawryk static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvstores_decoders[] = { 10680b3f378fSMaciej Wawryk {"uuid", offsetof(struct rpc_bdev_lvol_get_lvstores, uuid), spdk_json_decode_string, true}, 10690b3f378fSMaciej Wawryk {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvstores, lvs_name), spdk_json_decode_string, true}, 107007fe6a43SSeth Howell }; 107107fe6a43SSeth Howell 107207fe6a43SSeth Howell static void 1073c93e560fSSeth Howell rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev) 107407fe6a43SSeth Howell { 107507fe6a43SSeth Howell struct spdk_blob_store *bs; 107678f44434STomasz Zawadzki uint64_t cluster_size; 107707fe6a43SSeth Howell 107807fe6a43SSeth Howell bs = lvs_bdev->lvs->blobstore; 107907fe6a43SSeth Howell cluster_size = spdk_bs_get_cluster_size(bs); 108007fe6a43SSeth Howell 108107fe6a43SSeth Howell spdk_json_write_object_begin(w); 108207fe6a43SSeth Howell 10838cffbe01SKonrad Sztyber spdk_json_write_named_uuid(w, "uuid", &lvs_bdev->lvs->uuid); 108407fe6a43SSeth Howell spdk_json_write_named_string(w, "name", lvs_bdev->lvs->name); 108507fe6a43SSeth Howell spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(lvs_bdev->bdev)); 108607fe6a43SSeth Howell spdk_json_write_named_uint64(w, "total_data_clusters", spdk_bs_total_data_cluster_count(bs)); 108707fe6a43SSeth Howell spdk_json_write_named_uint64(w, "free_clusters", spdk_bs_free_cluster_count(bs)); 108878f44434STomasz Zawadzki spdk_json_write_named_uint64(w, "block_size", spdk_bs_get_io_unit_size(bs)); 108907fe6a43SSeth Howell spdk_json_write_named_uint64(w, "cluster_size", cluster_size); 109007fe6a43SSeth Howell 109107fe6a43SSeth Howell spdk_json_write_object_end(w); 109207fe6a43SSeth Howell } 109307fe6a43SSeth Howell 109407fe6a43SSeth Howell static void 1095c93e560fSSeth Howell rpc_bdev_lvol_get_lvstores(struct spdk_jsonrpc_request *request, 109607fe6a43SSeth Howell const struct spdk_json_val *params) 109707fe6a43SSeth Howell { 10980b3f378fSMaciej Wawryk struct rpc_bdev_lvol_get_lvstores req = {}; 109907fe6a43SSeth Howell struct spdk_json_write_ctx *w; 110007fe6a43SSeth Howell struct lvol_store_bdev *lvs_bdev = NULL; 110107fe6a43SSeth Howell struct spdk_lvol_store *lvs = NULL; 110207fe6a43SSeth Howell int rc; 110307fe6a43SSeth Howell 110407fe6a43SSeth Howell if (params != NULL) { 11050b3f378fSMaciej Wawryk if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvstores_decoders, 11060b3f378fSMaciej Wawryk SPDK_COUNTOF(rpc_bdev_lvol_get_lvstores_decoders), 110707fe6a43SSeth Howell &req)) { 11082172c432STomasz Zawadzki SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 110907fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 111007fe6a43SSeth Howell "spdk_json_decode_object failed"); 111107fe6a43SSeth Howell goto cleanup; 111207fe6a43SSeth Howell } 111307fe6a43SSeth Howell 111407fe6a43SSeth Howell rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 111507fe6a43SSeth Howell if (rc != 0) { 111607fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 111707fe6a43SSeth Howell goto cleanup; 111807fe6a43SSeth Howell } 111907fe6a43SSeth Howell 112007fe6a43SSeth Howell lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); 112107fe6a43SSeth Howell if (lvs_bdev == NULL) { 112207fe6a43SSeth Howell spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV)); 112307fe6a43SSeth Howell goto cleanup; 112407fe6a43SSeth Howell } 112507fe6a43SSeth Howell } 112607fe6a43SSeth Howell 112707fe6a43SSeth Howell w = spdk_jsonrpc_begin_result(request); 112807fe6a43SSeth Howell spdk_json_write_array_begin(w); 112907fe6a43SSeth Howell 113007fe6a43SSeth Howell if (lvs_bdev != NULL) { 1131c93e560fSSeth Howell rpc_dump_lvol_store_info(w, lvs_bdev); 113207fe6a43SSeth Howell } else { 113307fe6a43SSeth Howell for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; 113407fe6a43SSeth Howell lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { 1135c93e560fSSeth Howell rpc_dump_lvol_store_info(w, lvs_bdev); 113607fe6a43SSeth Howell } 113707fe6a43SSeth Howell } 113807fe6a43SSeth Howell spdk_json_write_array_end(w); 113907fe6a43SSeth Howell 114007fe6a43SSeth Howell spdk_jsonrpc_end_result(request, w); 114107fe6a43SSeth Howell 114207fe6a43SSeth Howell cleanup: 11430b3f378fSMaciej Wawryk free_rpc_bdev_lvol_get_lvstores(&req); 114407fe6a43SSeth Howell } 114507fe6a43SSeth Howell 1146c93e560fSSeth Howell SPDK_RPC_REGISTER("bdev_lvol_get_lvstores", rpc_bdev_lvol_get_lvstores, SPDK_RPC_RUNTIME) 11471f0b8df7Syupeng SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_get_lvstores, get_lvol_stores) 11481f0b8df7Syupeng 1149f3c14b8dSMike Gerdts struct rpc_bdev_lvol_get_lvols { 1150f3c14b8dSMike Gerdts char *lvs_uuid; 1151f3c14b8dSMike Gerdts char *lvs_name; 1152f3c14b8dSMike Gerdts }; 1153f3c14b8dSMike Gerdts 1154f3c14b8dSMike Gerdts static void 1155f3c14b8dSMike Gerdts free_rpc_bdev_lvol_get_lvols(struct rpc_bdev_lvol_get_lvols *req) 1156f3c14b8dSMike Gerdts { 1157f3c14b8dSMike Gerdts free(req->lvs_uuid); 1158f3c14b8dSMike Gerdts free(req->lvs_name); 1159f3c14b8dSMike Gerdts } 1160f3c14b8dSMike Gerdts 1161f3c14b8dSMike Gerdts static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvols_decoders[] = { 1162f3c14b8dSMike Gerdts {"lvs_uuid", offsetof(struct rpc_bdev_lvol_get_lvols, lvs_uuid), spdk_json_decode_string, true}, 1163f3c14b8dSMike Gerdts {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvols, lvs_name), spdk_json_decode_string, true}, 1164f3c14b8dSMike Gerdts }; 1165f3c14b8dSMike Gerdts 1166f3c14b8dSMike Gerdts static void 1167f3c14b8dSMike Gerdts rpc_dump_lvol(struct spdk_json_write_ctx *w, struct spdk_lvol *lvol) 1168f3c14b8dSMike Gerdts { 1169f3c14b8dSMike Gerdts struct spdk_lvol_store *lvs = lvol->lvol_store; 1170f3c14b8dSMike Gerdts 1171f3c14b8dSMike Gerdts spdk_json_write_object_begin(w); 1172f3c14b8dSMike Gerdts 1173f3c14b8dSMike Gerdts spdk_json_write_named_string_fmt(w, "alias", "%s/%s", lvs->name, lvol->name); 1174f3c14b8dSMike Gerdts spdk_json_write_named_string(w, "uuid", lvol->uuid_str); 1175f3c14b8dSMike Gerdts spdk_json_write_named_string(w, "name", lvol->name); 1176f3c14b8dSMike Gerdts spdk_json_write_named_bool(w, "is_thin_provisioned", spdk_blob_is_thin_provisioned(lvol->blob)); 1177f3c14b8dSMike Gerdts spdk_json_write_named_bool(w, "is_snapshot", spdk_blob_is_snapshot(lvol->blob)); 1178f3c14b8dSMike Gerdts spdk_json_write_named_bool(w, "is_clone", spdk_blob_is_clone(lvol->blob)); 1179f3c14b8dSMike Gerdts spdk_json_write_named_bool(w, "is_esnap_clone", spdk_blob_is_esnap_clone(lvol->blob)); 1180f3c14b8dSMike Gerdts spdk_json_write_named_bool(w, "is_degraded", spdk_blob_is_degraded(lvol->blob)); 1181a70c3a90SYankun Li spdk_json_write_named_uint64(w, "num_allocated_clusters", 1182a70c3a90SYankun Li spdk_blob_get_num_allocated_clusters(lvol->blob)); 1183f3c14b8dSMike Gerdts 1184f3c14b8dSMike Gerdts spdk_json_write_named_object_begin(w, "lvs"); 1185f3c14b8dSMike Gerdts spdk_json_write_named_string(w, "name", lvs->name); 11868cffbe01SKonrad Sztyber spdk_json_write_named_uuid(w, "uuid", &lvs->uuid); 1187f3c14b8dSMike Gerdts spdk_json_write_object_end(w); 1188f3c14b8dSMike Gerdts 1189f3c14b8dSMike Gerdts spdk_json_write_object_end(w); 1190f3c14b8dSMike Gerdts } 1191f3c14b8dSMike Gerdts 1192f3c14b8dSMike Gerdts static void 1193f3c14b8dSMike Gerdts rpc_dump_lvols(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev) 1194f3c14b8dSMike Gerdts { 1195f3c14b8dSMike Gerdts struct spdk_lvol_store *lvs = lvs_bdev->lvs; 1196f3c14b8dSMike Gerdts struct spdk_lvol *lvol; 1197f3c14b8dSMike Gerdts 1198f3c14b8dSMike Gerdts TAILQ_FOREACH(lvol, &lvs->lvols, link) { 1199afcb180bSYalong Wang if (lvol->ref_count == 0) { 1200afcb180bSYalong Wang continue; 1201afcb180bSYalong Wang } 1202f3c14b8dSMike Gerdts rpc_dump_lvol(w, lvol); 1203f3c14b8dSMike Gerdts } 1204f3c14b8dSMike Gerdts } 1205f3c14b8dSMike Gerdts 1206f3c14b8dSMike Gerdts static void 1207f3c14b8dSMike Gerdts rpc_bdev_lvol_get_lvols(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params) 1208f3c14b8dSMike Gerdts { 1209f3c14b8dSMike Gerdts struct rpc_bdev_lvol_get_lvols req = {}; 1210f3c14b8dSMike Gerdts struct spdk_json_write_ctx *w; 1211f3c14b8dSMike Gerdts struct lvol_store_bdev *lvs_bdev = NULL; 1212f3c14b8dSMike Gerdts struct spdk_lvol_store *lvs = NULL; 1213f3c14b8dSMike Gerdts int rc; 1214f3c14b8dSMike Gerdts 1215f3c14b8dSMike Gerdts if (params != NULL) { 1216f3c14b8dSMike Gerdts if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvols_decoders, 1217f3c14b8dSMike Gerdts SPDK_COUNTOF(rpc_bdev_lvol_get_lvols_decoders), 1218f3c14b8dSMike Gerdts &req)) { 1219f3c14b8dSMike Gerdts SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 1220f3c14b8dSMike Gerdts spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1221f3c14b8dSMike Gerdts "spdk_json_decode_object failed"); 1222f3c14b8dSMike Gerdts goto cleanup; 1223f3c14b8dSMike Gerdts } 1224f3c14b8dSMike Gerdts 1225f3c14b8dSMike Gerdts rc = vbdev_get_lvol_store_by_uuid_xor_name(req.lvs_uuid, req.lvs_name, &lvs); 1226f3c14b8dSMike Gerdts if (rc != 0) { 1227f3c14b8dSMike Gerdts spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 1228f3c14b8dSMike Gerdts goto cleanup; 1229f3c14b8dSMike Gerdts } 1230f3c14b8dSMike Gerdts 1231f3c14b8dSMike Gerdts lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs); 1232f3c14b8dSMike Gerdts if (lvs_bdev == NULL) { 1233f3c14b8dSMike Gerdts spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV)); 1234f3c14b8dSMike Gerdts goto cleanup; 1235f3c14b8dSMike Gerdts } 1236f3c14b8dSMike Gerdts } 1237f3c14b8dSMike Gerdts 1238f3c14b8dSMike Gerdts w = spdk_jsonrpc_begin_result(request); 1239f3c14b8dSMike Gerdts spdk_json_write_array_begin(w); 1240f3c14b8dSMike Gerdts 1241f3c14b8dSMike Gerdts if (lvs_bdev != NULL) { 1242f3c14b8dSMike Gerdts rpc_dump_lvols(w, lvs_bdev); 1243f3c14b8dSMike Gerdts } else { 1244f3c14b8dSMike Gerdts for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL; 1245f3c14b8dSMike Gerdts lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) { 1246f3c14b8dSMike Gerdts rpc_dump_lvols(w, lvs_bdev); 1247f3c14b8dSMike Gerdts } 1248f3c14b8dSMike Gerdts } 1249f3c14b8dSMike Gerdts spdk_json_write_array_end(w); 1250f3c14b8dSMike Gerdts 1251f3c14b8dSMike Gerdts spdk_jsonrpc_end_result(request, w); 1252f3c14b8dSMike Gerdts 1253f3c14b8dSMike Gerdts cleanup: 1254f3c14b8dSMike Gerdts free_rpc_bdev_lvol_get_lvols(&req); 1255f3c14b8dSMike Gerdts } 1256f3c14b8dSMike Gerdts 1257f3c14b8dSMike Gerdts SPDK_RPC_REGISTER("bdev_lvol_get_lvols", rpc_bdev_lvol_get_lvols, SPDK_RPC_RUNTIME) 1258f3c14b8dSMike Gerdts 12591f0b8df7Syupeng struct rpc_bdev_lvol_grow_lvstore { 12601f0b8df7Syupeng char *uuid; 12611f0b8df7Syupeng char *lvs_name; 12621f0b8df7Syupeng }; 12631f0b8df7Syupeng 12641f0b8df7Syupeng static void 12651f0b8df7Syupeng free_rpc_bdev_lvol_grow_lvstore(struct rpc_bdev_lvol_grow_lvstore *req) 12661f0b8df7Syupeng { 12671f0b8df7Syupeng free(req->uuid); 12681f0b8df7Syupeng free(req->lvs_name); 12691f0b8df7Syupeng } 12701f0b8df7Syupeng 12711f0b8df7Syupeng static const struct spdk_json_object_decoder rpc_bdev_lvol_grow_lvstore_decoders[] = { 12721f0b8df7Syupeng {"uuid", offsetof(struct rpc_bdev_lvol_grow_lvstore, uuid), spdk_json_decode_string, true}, 12731f0b8df7Syupeng {"lvs_name", offsetof(struct rpc_bdev_lvol_grow_lvstore, lvs_name), spdk_json_decode_string, true}, 12741f0b8df7Syupeng }; 12751f0b8df7Syupeng 12761f0b8df7Syupeng static void 12771f0b8df7Syupeng rpc_bdev_lvol_grow_lvstore_cb(void *cb_arg, int lvserrno) 12781f0b8df7Syupeng { 12791f0b8df7Syupeng struct spdk_jsonrpc_request *request = cb_arg; 12801f0b8df7Syupeng 12811f0b8df7Syupeng if (lvserrno != 0) { 12821f0b8df7Syupeng goto invalid; 12831f0b8df7Syupeng } 12841f0b8df7Syupeng 12851f0b8df7Syupeng spdk_jsonrpc_send_bool_response(request, true); 12861f0b8df7Syupeng return; 12871f0b8df7Syupeng 12881f0b8df7Syupeng invalid: 12891f0b8df7Syupeng spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 12901f0b8df7Syupeng spdk_strerror(-lvserrno)); 12911f0b8df7Syupeng } 12921f0b8df7Syupeng 12931f0b8df7Syupeng static void 12941f0b8df7Syupeng rpc_bdev_lvol_grow_lvstore(struct spdk_jsonrpc_request *request, 12951f0b8df7Syupeng const struct spdk_json_val *params) 12961f0b8df7Syupeng { 12971f0b8df7Syupeng struct rpc_bdev_lvol_grow_lvstore req = {}; 12981f0b8df7Syupeng struct spdk_lvol_store *lvs = NULL; 12991f0b8df7Syupeng int rc; 13001f0b8df7Syupeng 13011f0b8df7Syupeng if (spdk_json_decode_object(params, rpc_bdev_lvol_grow_lvstore_decoders, 13021f0b8df7Syupeng SPDK_COUNTOF(rpc_bdev_lvol_grow_lvstore_decoders), 13031f0b8df7Syupeng &req)) { 13041f0b8df7Syupeng SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 13051f0b8df7Syupeng spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 13061f0b8df7Syupeng "spdk_json_decode_object failed"); 13071f0b8df7Syupeng goto cleanup; 13081f0b8df7Syupeng } 13091f0b8df7Syupeng 13101f0b8df7Syupeng rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs); 13111f0b8df7Syupeng if (rc != 0) { 13121f0b8df7Syupeng spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); 13131f0b8df7Syupeng goto cleanup; 13141f0b8df7Syupeng } 1315ad5fc351STomasz Zawadzki spdk_bdev_update_bs_blockcnt(lvs->bs_dev); 1316ad5fc351STomasz Zawadzki spdk_lvs_grow_live(lvs, rpc_bdev_lvol_grow_lvstore_cb, request); 13171f0b8df7Syupeng 13181f0b8df7Syupeng cleanup: 13191f0b8df7Syupeng free_rpc_bdev_lvol_grow_lvstore(&req); 13201f0b8df7Syupeng } 13211f0b8df7Syupeng SPDK_RPC_REGISTER("bdev_lvol_grow_lvstore", rpc_bdev_lvol_grow_lvstore, SPDK_RPC_RUNTIME) 13229b3554b5SDamiano Cipriani 13239b3554b5SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy { 13249b3554b5SDamiano Cipriani char *src_lvol_name; 13259b3554b5SDamiano Cipriani char *dst_bdev_name; 13269b3554b5SDamiano Cipriani }; 13279b3554b5SDamiano Cipriani 13289b3554b5SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy_ctx { 13299b3554b5SDamiano Cipriani struct spdk_jsonrpc_request *request; 13309b3554b5SDamiano Cipriani struct rpc_shallow_copy_status *status; 13319b3554b5SDamiano Cipriani }; 13329b3554b5SDamiano Cipriani 13339b3554b5SDamiano Cipriani static void 13349b3554b5SDamiano Cipriani free_rpc_bdev_lvol_shallow_copy(struct rpc_bdev_lvol_shallow_copy *req) 13359b3554b5SDamiano Cipriani { 13369b3554b5SDamiano Cipriani free(req->src_lvol_name); 13379b3554b5SDamiano Cipriani free(req->dst_bdev_name); 13389b3554b5SDamiano Cipriani } 13399b3554b5SDamiano Cipriani 13409b3554b5SDamiano Cipriani static const struct spdk_json_object_decoder rpc_bdev_lvol_shallow_copy_decoders[] = { 13419b3554b5SDamiano Cipriani {"src_lvol_name", offsetof(struct rpc_bdev_lvol_shallow_copy, src_lvol_name), spdk_json_decode_string}, 13429b3554b5SDamiano Cipriani {"dst_bdev_name", offsetof(struct rpc_bdev_lvol_shallow_copy, dst_bdev_name), spdk_json_decode_string}, 13439b3554b5SDamiano Cipriani }; 13449b3554b5SDamiano Cipriani 13459b3554b5SDamiano Cipriani static void 13469b3554b5SDamiano Cipriani rpc_bdev_lvol_shallow_copy_cb(void *cb_arg, int lvolerrno) 13479b3554b5SDamiano Cipriani { 13489b3554b5SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy_ctx *ctx = cb_arg; 13499b3554b5SDamiano Cipriani 13509b3554b5SDamiano Cipriani ctx->status->result = lvolerrno; 13519b3554b5SDamiano Cipriani 13529b3554b5SDamiano Cipriani free(ctx); 13539b3554b5SDamiano Cipriani } 13549b3554b5SDamiano Cipriani 13559b3554b5SDamiano Cipriani static void 13569b3554b5SDamiano Cipriani rpc_bdev_lvol_shallow_copy_status_cb(uint64_t copied_clusters, void *cb_arg) 13579b3554b5SDamiano Cipriani { 13589b3554b5SDamiano Cipriani struct rpc_shallow_copy_status *status = cb_arg; 13599b3554b5SDamiano Cipriani 13609b3554b5SDamiano Cipriani status->copied_clusters = copied_clusters; 13619b3554b5SDamiano Cipriani } 13629b3554b5SDamiano Cipriani 13639b3554b5SDamiano Cipriani static void 13649b3554b5SDamiano Cipriani rpc_bdev_lvol_start_shallow_copy(struct spdk_jsonrpc_request *request, 13659b3554b5SDamiano Cipriani const struct spdk_json_val *params) 13669b3554b5SDamiano Cipriani { 13679b3554b5SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy req = {}; 13689b3554b5SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy_ctx *ctx; 13699b3554b5SDamiano Cipriani struct spdk_lvol *src_lvol; 13709b3554b5SDamiano Cipriani struct spdk_bdev *src_lvol_bdev; 13719b3554b5SDamiano Cipriani struct rpc_shallow_copy_status *status; 13729b3554b5SDamiano Cipriani struct spdk_json_write_ctx *w; 13739b3554b5SDamiano Cipriani int rc; 13749b3554b5SDamiano Cipriani 13759b3554b5SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "Shallow copying lvol\n"); 13769b3554b5SDamiano Cipriani 13779b3554b5SDamiano Cipriani if (spdk_json_decode_object(params, rpc_bdev_lvol_shallow_copy_decoders, 13789b3554b5SDamiano Cipriani SPDK_COUNTOF(rpc_bdev_lvol_shallow_copy_decoders), 13799b3554b5SDamiano Cipriani &req)) { 13809b3554b5SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 13819b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 13829b3554b5SDamiano Cipriani "spdk_json_decode_object failed"); 13839b3554b5SDamiano Cipriani goto cleanup; 13849b3554b5SDamiano Cipriani } 13859b3554b5SDamiano Cipriani 13869b3554b5SDamiano Cipriani src_lvol_bdev = spdk_bdev_get_by_name(req.src_lvol_name); 13879b3554b5SDamiano Cipriani if (src_lvol_bdev == NULL) { 13889b3554b5SDamiano Cipriani SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.src_lvol_name); 13899b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 13909b3554b5SDamiano Cipriani goto cleanup; 13919b3554b5SDamiano Cipriani } 13929b3554b5SDamiano Cipriani 13939b3554b5SDamiano Cipriani src_lvol = vbdev_lvol_get_from_bdev(src_lvol_bdev); 13949b3554b5SDamiano Cipriani if (src_lvol == NULL) { 13959b3554b5SDamiano Cipriani SPDK_ERRLOG("lvol does not exist\n"); 13969b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 13979b3554b5SDamiano Cipriani goto cleanup; 13989b3554b5SDamiano Cipriani } 13999b3554b5SDamiano Cipriani 14009b3554b5SDamiano Cipriani status = calloc(1, sizeof(*status)); 14019b3554b5SDamiano Cipriani if (status == NULL) { 14029b3554b5SDamiano Cipriani SPDK_ERRLOG("Cannot allocate status entry for shallow copy of '%s'\n", req.src_lvol_name); 14039b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); 14049b3554b5SDamiano Cipriani goto cleanup; 14059b3554b5SDamiano Cipriani } 14069b3554b5SDamiano Cipriani 14079b3554b5SDamiano Cipriani status->operation_id = ++g_shallow_copy_count; 14089b3554b5SDamiano Cipriani status->total_clusters = spdk_blob_get_num_allocated_clusters(src_lvol->blob); 14099b3554b5SDamiano Cipriani 14109b3554b5SDamiano Cipriani ctx = calloc(1, sizeof(*ctx)); 14119b3554b5SDamiano Cipriani if (ctx == NULL) { 14129b3554b5SDamiano Cipriani SPDK_ERRLOG("Cannot allocate context for shallow copy of '%s'\n", req.src_lvol_name); 14139b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM)); 14149b3554b5SDamiano Cipriani free(status); 14159b3554b5SDamiano Cipriani goto cleanup; 14169b3554b5SDamiano Cipriani } 14179b3554b5SDamiano Cipriani ctx->request = request; 14189b3554b5SDamiano Cipriani ctx->status = status; 14199b3554b5SDamiano Cipriani 14209b3554b5SDamiano Cipriani LIST_INSERT_HEAD(&g_shallow_copy_status_list, status, link); 14219b3554b5SDamiano Cipriani rc = vbdev_lvol_shallow_copy(src_lvol, req.dst_bdev_name, 14229b3554b5SDamiano Cipriani rpc_bdev_lvol_shallow_copy_status_cb, status, 14239b3554b5SDamiano Cipriani rpc_bdev_lvol_shallow_copy_cb, ctx); 14249b3554b5SDamiano Cipriani 14259b3554b5SDamiano Cipriani if (rc < 0) { 14269b3554b5SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 14279b3554b5SDamiano Cipriani spdk_strerror(-rc)); 14289b3554b5SDamiano Cipriani LIST_REMOVE(status, link); 14299b3554b5SDamiano Cipriani free(ctx); 14309b3554b5SDamiano Cipriani free(status); 14319b3554b5SDamiano Cipriani } else { 14329b3554b5SDamiano Cipriani w = spdk_jsonrpc_begin_result(request); 14339b3554b5SDamiano Cipriani 14349b3554b5SDamiano Cipriani spdk_json_write_object_begin(w); 14359b3554b5SDamiano Cipriani spdk_json_write_named_uint32(w, "operation_id", status->operation_id); 14369b3554b5SDamiano Cipriani spdk_json_write_object_end(w); 14379b3554b5SDamiano Cipriani 14389b3554b5SDamiano Cipriani spdk_jsonrpc_end_result(request, w); 14399b3554b5SDamiano Cipriani } 14409b3554b5SDamiano Cipriani 14419b3554b5SDamiano Cipriani cleanup: 14429b3554b5SDamiano Cipriani free_rpc_bdev_lvol_shallow_copy(&req); 14439b3554b5SDamiano Cipriani } 14449b3554b5SDamiano Cipriani 14459b3554b5SDamiano Cipriani SPDK_RPC_REGISTER("bdev_lvol_start_shallow_copy", rpc_bdev_lvol_start_shallow_copy, 14469b3554b5SDamiano Cipriani SPDK_RPC_RUNTIME) 14478c41f0d3SDamiano Cipriani 14488c41f0d3SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy_status { 14498c41f0d3SDamiano Cipriani char *src_lvol_name; 14508c41f0d3SDamiano Cipriani uint32_t operation_id; 14518c41f0d3SDamiano Cipriani }; 14528c41f0d3SDamiano Cipriani 14538c41f0d3SDamiano Cipriani static void 14548c41f0d3SDamiano Cipriani free_rpc_bdev_lvol_shallow_copy_status(struct rpc_bdev_lvol_shallow_copy_status *req) 14558c41f0d3SDamiano Cipriani { 14568c41f0d3SDamiano Cipriani free(req->src_lvol_name); 14578c41f0d3SDamiano Cipriani } 14588c41f0d3SDamiano Cipriani 14598c41f0d3SDamiano Cipriani static const struct spdk_json_object_decoder rpc_bdev_lvol_shallow_copy_status_decoders[] = { 14608c41f0d3SDamiano Cipriani {"operation_id", offsetof(struct rpc_bdev_lvol_shallow_copy_status, operation_id), spdk_json_decode_uint32}, 14618c41f0d3SDamiano Cipriani }; 14628c41f0d3SDamiano Cipriani 14638c41f0d3SDamiano Cipriani static void 14648c41f0d3SDamiano Cipriani rpc_bdev_lvol_check_shallow_copy(struct spdk_jsonrpc_request *request, 14658c41f0d3SDamiano Cipriani const struct spdk_json_val *params) 14668c41f0d3SDamiano Cipriani { 14678c41f0d3SDamiano Cipriani struct rpc_bdev_lvol_shallow_copy_status req = {}; 14688c41f0d3SDamiano Cipriani struct rpc_shallow_copy_status *status; 14698c41f0d3SDamiano Cipriani struct spdk_json_write_ctx *w; 14708c41f0d3SDamiano Cipriani uint64_t copied_clusters, total_clusters; 14718c41f0d3SDamiano Cipriani int result; 14728c41f0d3SDamiano Cipriani 14738c41f0d3SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "Shallow copy check\n"); 14748c41f0d3SDamiano Cipriani 14758c41f0d3SDamiano Cipriani if (spdk_json_decode_object(params, rpc_bdev_lvol_shallow_copy_status_decoders, 14768c41f0d3SDamiano Cipriani SPDK_COUNTOF(rpc_bdev_lvol_shallow_copy_status_decoders), 14778c41f0d3SDamiano Cipriani &req)) { 14788c41f0d3SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 14798c41f0d3SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 14808c41f0d3SDamiano Cipriani "spdk_json_decode_object failed"); 14818c41f0d3SDamiano Cipriani goto cleanup; 14828c41f0d3SDamiano Cipriani } 14838c41f0d3SDamiano Cipriani 14848c41f0d3SDamiano Cipriani LIST_FOREACH(status, &g_shallow_copy_status_list, link) { 14858c41f0d3SDamiano Cipriani if (status->operation_id == req.operation_id) { 14868c41f0d3SDamiano Cipriani break; 14878c41f0d3SDamiano Cipriani } 14888c41f0d3SDamiano Cipriani } 14898c41f0d3SDamiano Cipriani 14908c41f0d3SDamiano Cipriani if (!status) { 14918c41f0d3SDamiano Cipriani SPDK_ERRLOG("operation id '%d' does not exist\n", req.operation_id); 14928c41f0d3SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 14938c41f0d3SDamiano Cipriani goto cleanup; 14948c41f0d3SDamiano Cipriani } 14958c41f0d3SDamiano Cipriani 14968c41f0d3SDamiano Cipriani copied_clusters = status->copied_clusters; 14978c41f0d3SDamiano Cipriani total_clusters = status->total_clusters; 14988c41f0d3SDamiano Cipriani result = status->result; 14998c41f0d3SDamiano Cipriani 15008c41f0d3SDamiano Cipriani w = spdk_jsonrpc_begin_result(request); 15018c41f0d3SDamiano Cipriani 15028c41f0d3SDamiano Cipriani spdk_json_write_object_begin(w); 15038c41f0d3SDamiano Cipriani 15048c41f0d3SDamiano Cipriani spdk_json_write_named_uint64(w, "copied_clusters", copied_clusters); 15058c41f0d3SDamiano Cipriani spdk_json_write_named_uint64(w, "total_clusters", total_clusters); 15068c41f0d3SDamiano Cipriani if (copied_clusters < total_clusters && result == 0) { 15078c41f0d3SDamiano Cipriani spdk_json_write_named_string(w, "state", "in progress"); 15088c41f0d3SDamiano Cipriani } else if (copied_clusters == total_clusters && result == 0) { 15098c41f0d3SDamiano Cipriani spdk_json_write_named_string(w, "state", "complete"); 15108c41f0d3SDamiano Cipriani LIST_REMOVE(status, link); 15118c41f0d3SDamiano Cipriani free(status); 15128c41f0d3SDamiano Cipriani } else { 15138c41f0d3SDamiano Cipriani spdk_json_write_named_string(w, "state", "error"); 15148c41f0d3SDamiano Cipriani spdk_json_write_named_string(w, "error", spdk_strerror(-result)); 15158c41f0d3SDamiano Cipriani LIST_REMOVE(status, link); 15168c41f0d3SDamiano Cipriani free(status); 15178c41f0d3SDamiano Cipriani } 15188c41f0d3SDamiano Cipriani 15198c41f0d3SDamiano Cipriani spdk_json_write_object_end(w); 15208c41f0d3SDamiano Cipriani 15218c41f0d3SDamiano Cipriani spdk_jsonrpc_end_result(request, w); 15228c41f0d3SDamiano Cipriani 15238c41f0d3SDamiano Cipriani cleanup: 15248c41f0d3SDamiano Cipriani free_rpc_bdev_lvol_shallow_copy_status(&req); 15258c41f0d3SDamiano Cipriani } 15268c41f0d3SDamiano Cipriani 15278c41f0d3SDamiano Cipriani SPDK_RPC_REGISTER("bdev_lvol_check_shallow_copy", rpc_bdev_lvol_check_shallow_copy, 15288c41f0d3SDamiano Cipriani SPDK_RPC_RUNTIME) 152999ffb3d9SDamiano Cipriani 153099ffb3d9SDamiano Cipriani struct rpc_bdev_lvol_set_parent { 153199ffb3d9SDamiano Cipriani char *lvol_name; 153299ffb3d9SDamiano Cipriani char *parent_name; 153399ffb3d9SDamiano Cipriani }; 153499ffb3d9SDamiano Cipriani 153599ffb3d9SDamiano Cipriani static void 153699ffb3d9SDamiano Cipriani free_rpc_bdev_lvol_set_parent(struct rpc_bdev_lvol_set_parent *req) 153799ffb3d9SDamiano Cipriani { 153899ffb3d9SDamiano Cipriani free(req->lvol_name); 153999ffb3d9SDamiano Cipriani free(req->parent_name); 154099ffb3d9SDamiano Cipriani } 154199ffb3d9SDamiano Cipriani 154299ffb3d9SDamiano Cipriani static const struct spdk_json_object_decoder rpc_bdev_lvol_set_parent_decoders[] = { 154399ffb3d9SDamiano Cipriani {"lvol_name", offsetof(struct rpc_bdev_lvol_set_parent, lvol_name), spdk_json_decode_string}, 154499ffb3d9SDamiano Cipriani {"parent_name", offsetof(struct rpc_bdev_lvol_set_parent, parent_name), spdk_json_decode_string}, 154599ffb3d9SDamiano Cipriani }; 154699ffb3d9SDamiano Cipriani 154799ffb3d9SDamiano Cipriani static void 154899ffb3d9SDamiano Cipriani rpc_bdev_lvol_set_parent_cb(void *cb_arg, int lvolerrno) 154999ffb3d9SDamiano Cipriani { 155099ffb3d9SDamiano Cipriani struct spdk_jsonrpc_request *request = cb_arg; 155199ffb3d9SDamiano Cipriani 155299ffb3d9SDamiano Cipriani if (lvolerrno != 0) { 155399ffb3d9SDamiano Cipriani goto invalid; 155499ffb3d9SDamiano Cipriani } 155599ffb3d9SDamiano Cipriani 155699ffb3d9SDamiano Cipriani spdk_jsonrpc_send_bool_response(request, true); 155799ffb3d9SDamiano Cipriani return; 155899ffb3d9SDamiano Cipriani 155999ffb3d9SDamiano Cipriani invalid: 156099ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, 156199ffb3d9SDamiano Cipriani spdk_strerror(-lvolerrno)); 156299ffb3d9SDamiano Cipriani } 156399ffb3d9SDamiano Cipriani 156499ffb3d9SDamiano Cipriani static void 156599ffb3d9SDamiano Cipriani rpc_bdev_lvol_set_parent(struct spdk_jsonrpc_request *request, 156699ffb3d9SDamiano Cipriani const struct spdk_json_val *params) 156799ffb3d9SDamiano Cipriani { 156899ffb3d9SDamiano Cipriani struct rpc_bdev_lvol_set_parent req = {}; 156999ffb3d9SDamiano Cipriani struct spdk_lvol *lvol, *snapshot; 157099ffb3d9SDamiano Cipriani struct spdk_bdev *lvol_bdev, *snapshot_bdev; 157199ffb3d9SDamiano Cipriani 157299ffb3d9SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "Set parent of lvol\n"); 157399ffb3d9SDamiano Cipriani 157499ffb3d9SDamiano Cipriani if (spdk_json_decode_object(params, rpc_bdev_lvol_set_parent_decoders, 157599ffb3d9SDamiano Cipriani SPDK_COUNTOF(rpc_bdev_lvol_set_parent_decoders), 157699ffb3d9SDamiano Cipriani &req)) { 157799ffb3d9SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 157899ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 157999ffb3d9SDamiano Cipriani "spdk_json_decode_object failed"); 158099ffb3d9SDamiano Cipriani goto cleanup; 158199ffb3d9SDamiano Cipriani } 158299ffb3d9SDamiano Cipriani 158399ffb3d9SDamiano Cipriani lvol_bdev = spdk_bdev_get_by_name(req.lvol_name); 158499ffb3d9SDamiano Cipriani if (lvol_bdev == NULL) { 158599ffb3d9SDamiano Cipriani SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.lvol_name); 158699ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 158799ffb3d9SDamiano Cipriani goto cleanup; 158899ffb3d9SDamiano Cipriani } 158999ffb3d9SDamiano Cipriani 159099ffb3d9SDamiano Cipriani lvol = vbdev_lvol_get_from_bdev(lvol_bdev); 159199ffb3d9SDamiano Cipriani if (lvol == NULL) { 159299ffb3d9SDamiano Cipriani SPDK_ERRLOG("lvol does not exist\n"); 159399ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 159499ffb3d9SDamiano Cipriani goto cleanup; 159599ffb3d9SDamiano Cipriani } 159699ffb3d9SDamiano Cipriani 159799ffb3d9SDamiano Cipriani snapshot_bdev = spdk_bdev_get_by_name(req.parent_name); 159899ffb3d9SDamiano Cipriani if (snapshot_bdev == NULL) { 159999ffb3d9SDamiano Cipriani SPDK_ERRLOG("snapshot bdev '%s' does not exist\n", req.parent_name); 160099ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 160199ffb3d9SDamiano Cipriani goto cleanup; 160299ffb3d9SDamiano Cipriani } 160399ffb3d9SDamiano Cipriani 160499ffb3d9SDamiano Cipriani snapshot = vbdev_lvol_get_from_bdev(snapshot_bdev); 160599ffb3d9SDamiano Cipriani if (snapshot == NULL) { 160699ffb3d9SDamiano Cipriani SPDK_ERRLOG("snapshot does not exist\n"); 160799ffb3d9SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 160899ffb3d9SDamiano Cipriani goto cleanup; 160999ffb3d9SDamiano Cipriani } 161099ffb3d9SDamiano Cipriani 161199ffb3d9SDamiano Cipriani spdk_lvol_set_parent(lvol, snapshot, rpc_bdev_lvol_set_parent_cb, request); 161299ffb3d9SDamiano Cipriani 161399ffb3d9SDamiano Cipriani cleanup: 161499ffb3d9SDamiano Cipriani free_rpc_bdev_lvol_set_parent(&req); 161599ffb3d9SDamiano Cipriani } 161699ffb3d9SDamiano Cipriani 161799ffb3d9SDamiano Cipriani SPDK_RPC_REGISTER("bdev_lvol_set_parent", rpc_bdev_lvol_set_parent, SPDK_RPC_RUNTIME) 1618672ba928SDamiano Cipriani 1619672ba928SDamiano Cipriani static void 1620672ba928SDamiano Cipriani rpc_bdev_lvol_set_parent_bdev(struct spdk_jsonrpc_request *request, 1621672ba928SDamiano Cipriani const struct spdk_json_val *params) 1622672ba928SDamiano Cipriani { 1623672ba928SDamiano Cipriani struct rpc_bdev_lvol_set_parent req = {}; 1624672ba928SDamiano Cipriani struct spdk_lvol *lvol; 1625672ba928SDamiano Cipriani struct spdk_bdev *lvol_bdev; 1626672ba928SDamiano Cipriani 1627672ba928SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "Set external parent of lvol\n"); 1628672ba928SDamiano Cipriani 1629672ba928SDamiano Cipriani if (spdk_json_decode_object(params, rpc_bdev_lvol_set_parent_decoders, 1630672ba928SDamiano Cipriani SPDK_COUNTOF(rpc_bdev_lvol_set_parent_decoders), 1631672ba928SDamiano Cipriani &req)) { 1632672ba928SDamiano Cipriani SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n"); 1633672ba928SDamiano Cipriani spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, 1634672ba928SDamiano Cipriani "spdk_json_decode_object failed"); 1635672ba928SDamiano Cipriani goto cleanup; 1636672ba928SDamiano Cipriani } 1637672ba928SDamiano Cipriani 1638672ba928SDamiano Cipriani lvol_bdev = spdk_bdev_get_by_name(req.lvol_name); 1639672ba928SDamiano Cipriani if (lvol_bdev == NULL) { 1640672ba928SDamiano Cipriani SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.lvol_name); 1641672ba928SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 1642672ba928SDamiano Cipriani goto cleanup; 1643672ba928SDamiano Cipriani } 1644672ba928SDamiano Cipriani 1645672ba928SDamiano Cipriani lvol = vbdev_lvol_get_from_bdev(lvol_bdev); 1646672ba928SDamiano Cipriani if (lvol == NULL) { 1647672ba928SDamiano Cipriani SPDK_ERRLOG("lvol does not exist\n"); 1648672ba928SDamiano Cipriani spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV)); 1649672ba928SDamiano Cipriani goto cleanup; 1650672ba928SDamiano Cipriani } 1651672ba928SDamiano Cipriani 1652672ba928SDamiano Cipriani vbdev_lvol_set_external_parent(lvol, req.parent_name, rpc_bdev_lvol_set_parent_cb, request); 1653672ba928SDamiano Cipriani 1654672ba928SDamiano Cipriani cleanup: 1655672ba928SDamiano Cipriani free_rpc_bdev_lvol_set_parent(&req); 1656672ba928SDamiano Cipriani } 1657672ba928SDamiano Cipriani 1658672ba928SDamiano Cipriani SPDK_RPC_REGISTER("bdev_lvol_set_parent_bdev", rpc_bdev_lvol_set_parent_bdev, 1659672ba928SDamiano Cipriani SPDK_RPC_RUNTIME) 1660