LCOV - code coverage report
Current view: top level - spdk/module/bdev/lvol - vbdev_lvol_rpc.c (source / functions) Hit Total Coverage
Test: Combined Lines: 592 825 71.8 %
Date: 2024-12-16 00:17:30 Functions: 79 79 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 190 1074 17.7 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2017 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  *   Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "spdk/rpc.h"
       8                 :            : #include "spdk/bdev.h"
       9                 :            : #include "spdk/util.h"
      10                 :            : #include "vbdev_lvol.h"
      11                 :            : #include "spdk/string.h"
      12                 :            : #include "spdk/log.h"
      13                 :            : 
      14                 :       2215 : SPDK_LOG_REGISTER_COMPONENT(lvol_rpc)
      15                 :            : 
      16                 :            : struct rpc_shallow_copy_status {
      17                 :            :         uint32_t                                operation_id;
      18                 :            :         /*
      19                 :            :          * 0 means ongoing or successfully completed operation
      20                 :            :          * a negative value is the -errno of an aborted operation
      21                 :            :          */
      22                 :            :         int                                     result;
      23                 :            :         uint64_t                                copied_clusters;
      24                 :            :         uint64_t                                total_clusters;
      25                 :            :         LIST_ENTRY(rpc_shallow_copy_status)     link;
      26                 :            : };
      27                 :            : 
      28                 :            : static uint32_t g_shallow_copy_count = 0;
      29                 :            : static LIST_HEAD(, rpc_shallow_copy_status) g_shallow_copy_status_list = LIST_HEAD_INITIALIZER(
      30                 :            :                         &g_shallow_copy_status_list);
      31                 :            : 
      32                 :            : struct rpc_bdev_lvol_create_lvstore {
      33                 :            :         char *lvs_name;
      34                 :            :         char *bdev_name;
      35                 :            :         uint32_t cluster_sz;
      36                 :            :         char *clear_method;
      37                 :            :         uint32_t num_md_pages_per_cluster_ratio;
      38                 :            :         uint32_t md_page_size;
      39                 :            : };
      40                 :            : 
      41                 :            : static int
      42                 :        740 : vbdev_get_lvol_store_by_uuid_xor_name(const char *uuid, const char *lvs_name,
      43                 :            :                                       struct spdk_lvol_store **lvs)
      44                 :            : {
      45   [ +  +  +  + ]:        740 :         if ((uuid == NULL && lvs_name == NULL)) {
      46   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "lvs UUID nor lvs name specified\n");
                   #  # ]
      47                 :          0 :                 return -EINVAL;
      48   [ +  +  -  + ]:        740 :         } else if ((uuid && lvs_name)) {
      49   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "both lvs UUID '%s' and lvs name '%s' specified\n", uuid,
                   #  # ]
      50                 :            :                              lvs_name);
      51                 :          0 :                 return -EINVAL;
      52         [ +  + ]:        740 :         } else if (uuid) {
      53         [ #  # ]:        563 :                 *lvs = vbdev_get_lvol_store_by_uuid(uuid);
      54                 :            : 
      55   [ +  +  #  # ]:        563 :                 if (*lvs == NULL) {
      56   [ -  +  -  +  :         45 :                         SPDK_INFOLOG(lvol_rpc, "blobstore with UUID '%s' not found\n", uuid);
                   #  # ]
      57                 :         45 :                         return -ENODEV;
      58                 :            :                 }
      59         [ +  + ]:        177 :         } else if (lvs_name) {
      60                 :            : 
      61         [ #  # ]:        177 :                 *lvs = vbdev_get_lvol_store_by_name(lvs_name);
      62                 :            : 
      63   [ +  +  #  # ]:        177 :                 if (*lvs == NULL) {
      64   [ -  +  -  +  :         11 :                         SPDK_INFOLOG(lvol_rpc, "blobstore with name '%s' not found\n", lvs_name);
                   #  # ]
      65                 :         11 :                         return -ENODEV;
      66                 :            :                 }
      67                 :          3 :         }
      68                 :        684 :         return 0;
      69                 :          3 : }
      70                 :            : 
      71                 :            : static void
      72                 :        206 : free_rpc_bdev_lvol_create_lvstore(struct rpc_bdev_lvol_create_lvstore *req)
      73                 :            : {
      74   [ #  #  #  # ]:        206 :         free(req->bdev_name);
      75   [ #  #  #  # ]:        206 :         free(req->lvs_name);
      76   [ #  #  #  # ]:        206 :         free(req->clear_method);
      77                 :        206 : }
      78                 :            : 
      79                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_create_lvstore_decoders[] = {
      80                 :            :         {"bdev_name", offsetof(struct rpc_bdev_lvol_create_lvstore, bdev_name), spdk_json_decode_string},
      81                 :            :         {"cluster_sz", offsetof(struct rpc_bdev_lvol_create_lvstore, cluster_sz), spdk_json_decode_uint32, true},
      82                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_create_lvstore, lvs_name), spdk_json_decode_string},
      83                 :            :         {"clear_method", offsetof(struct rpc_bdev_lvol_create_lvstore, clear_method), spdk_json_decode_string, true},
      84                 :            :         {"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                 :            :         {"md_page_size", offsetof(struct rpc_bdev_lvol_create_lvstore, md_page_size), spdk_json_decode_uint32, true},
      86                 :            : };
      87                 :            : 
      88                 :            : static void
      89                 :        199 : rpc_lvol_store_construct_cb(void *cb_arg, struct spdk_lvol_store *lvol_store, int lvserrno)
      90                 :            : {
      91                 :            :         struct spdk_json_write_ctx *w;
      92                 :        199 :         struct spdk_jsonrpc_request *request = cb_arg;
      93                 :            : 
      94         [ +  + ]:        199 :         if (lvserrno != 0) {
      95                 :          0 :                 goto invalid;
      96                 :            :         }
      97                 :            : 
      98                 :        199 :         w = spdk_jsonrpc_begin_result(request);
      99         [ #  # ]:        199 :         spdk_json_write_uuid(w, &lvol_store->uuid);
     100                 :        199 :         spdk_jsonrpc_end_result(request, w);
     101                 :        199 :         return;
     102                 :            : 
     103                 :          0 : invalid:
     104                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     105         [ #  # ]:          0 :                                          spdk_strerror(-lvserrno));
     106                 :          1 : }
     107                 :            : 
     108                 :            : static void
     109                 :        206 : rpc_bdev_lvol_create_lvstore(struct spdk_jsonrpc_request *request,
     110                 :            :                              const struct spdk_json_val *params)
     111                 :            : {
     112                 :        206 :         struct rpc_bdev_lvol_create_lvstore req = {};
     113                 :        206 :         int rc = 0;
     114                 :            :         enum lvs_clear_method clear_method;
     115                 :            : 
     116         [ +  + ]:        206 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_create_lvstore_decoders,
     117                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_create_lvstore_decoders),
     118                 :            :                                     &req)) {
     119   [ -  +  -  +  :          1 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     120                 :          1 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     121                 :            :                                                  "spdk_json_decode_object failed");
     122                 :          1 :                 goto cleanup;
     123                 :            :         }
     124                 :            : 
     125   [ +  +  #  # ]:        205 :         if (req.clear_method != NULL) {
     126   [ -  +  +  +  :         34 :                 if (!strcasecmp(req.clear_method, "none")) {
             #  #  #  # ]
     127                 :         30 :                         clear_method = LVS_CLEAR_WITH_NONE;
     128   [ -  +  +  +  :          4 :                 } else if (!strcasecmp(req.clear_method, "unmap")) {
             #  #  #  # ]
     129                 :          2 :                         clear_method = LVS_CLEAR_WITH_UNMAP;
     130   [ -  +  +  +  :          2 :                 } else if (!strcasecmp(req.clear_method, "write_zeroes")) {
             #  #  #  # ]
     131                 :          1 :                         clear_method = LVS_CLEAR_WITH_WRITE_ZEROES;
     132                 :          0 :                 } else {
     133                 :          1 :                         spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clear_method parameter");
     134                 :          1 :                         goto cleanup;
     135                 :            :                 }
     136                 :          0 :         } else {
     137                 :        171 :                 clear_method = LVS_CLEAR_WITH_UNMAP;
     138                 :            :         }
     139                 :            : 
     140   [ #  #  #  # ]:        205 :         rc = vbdev_lvs_create_ext(req.bdev_name, req.lvs_name, req.cluster_sz, clear_method,
     141   [ #  #  #  # ]:          1 :                                   req.num_md_pages_per_cluster_ratio, req.md_page_size,
     142                 :          1 :                                   rpc_lvol_store_construct_cb, request);
     143         [ +  + ]:        204 :         if (rc < 0) {
     144         [ #  # ]:          5 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     145                 :          5 :                 goto cleanup;
     146                 :            :         }
     147                 :        199 :         free_rpc_bdev_lvol_create_lvstore(&req);
     148                 :            : 
     149                 :        199 :         return;
     150                 :            : 
     151                 :          7 : cleanup:
     152                 :          7 :         free_rpc_bdev_lvol_create_lvstore(&req);
     153                 :          1 : }
     154                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_create_lvstore", rpc_bdev_lvol_create_lvstore, SPDK_RPC_RUNTIME)
     155                 :            : 
     156                 :            : struct rpc_bdev_lvol_rename_lvstore {
     157                 :            :         char *old_name;
     158                 :            :         char *new_name;
     159                 :            : };
     160                 :            : 
     161                 :            : static void
     162                 :          3 : free_rpc_bdev_lvol_rename_lvstore(struct rpc_bdev_lvol_rename_lvstore *req)
     163                 :            : {
     164   [ #  #  #  # ]:          3 :         free(req->old_name);
     165   [ #  #  #  # ]:          3 :         free(req->new_name);
     166                 :          3 : }
     167                 :            : 
     168                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_lvstore_decoders[] = {
     169                 :            :         {"old_name", offsetof(struct rpc_bdev_lvol_rename_lvstore, old_name), spdk_json_decode_string},
     170                 :            :         {"new_name", offsetof(struct rpc_bdev_lvol_rename_lvstore, new_name), spdk_json_decode_string},
     171                 :            : };
     172                 :            : 
     173                 :            : static void
     174                 :          2 : rpc_bdev_lvol_rename_lvstore_cb(void *cb_arg, int lvserrno)
     175                 :            : {
     176                 :          2 :         struct spdk_jsonrpc_request *request = cb_arg;
     177                 :            : 
     178         [ +  + ]:          2 :         if (lvserrno != 0) {
     179                 :          1 :                 goto invalid;
     180                 :            :         }
     181                 :            : 
     182                 :          1 :         spdk_jsonrpc_send_bool_response(request, true);
     183                 :          1 :         return;
     184                 :            : 
     185                 :          1 : invalid:
     186                 :          1 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     187         [ #  # ]:          0 :                                          spdk_strerror(-lvserrno));
     188                 :          0 : }
     189                 :            : 
     190                 :            : static void
     191                 :          3 : rpc_bdev_lvol_rename_lvstore(struct spdk_jsonrpc_request *request,
     192                 :            :                              const struct spdk_json_val *params)
     193                 :            : {
     194                 :          3 :         struct rpc_bdev_lvol_rename_lvstore req = {};
     195                 :            :         struct spdk_lvol_store *lvs;
     196                 :            : 
     197         [ -  + ]:          3 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_lvstore_decoders,
     198                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_rename_lvstore_decoders),
     199                 :            :                                     &req)) {
     200   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     201                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     202                 :            :                                                  "spdk_json_decode_object failed");
     203                 :          0 :                 goto cleanup;
     204                 :            :         }
     205                 :            : 
     206                 :          3 :         lvs = vbdev_get_lvol_store_by_name(req.old_name);
     207         [ +  + ]:          3 :         if (lvs == NULL) {
     208   [ -  +  -  +  :          1 :                 SPDK_INFOLOG(lvol_rpc, "no lvs existing for given name\n");
                   #  # ]
     209                 :          1 :                 spdk_jsonrpc_send_error_response_fmt(request, -ENOENT, "Lvol store %s not found", req.old_name);
     210                 :          1 :                 goto cleanup;
     211                 :            :         }
     212                 :            : 
     213         [ #  # ]:          2 :         vbdev_lvs_rename(lvs, req.new_name, rpc_bdev_lvol_rename_lvstore_cb, request);
     214                 :            : 
     215                 :          3 : cleanup:
     216                 :          3 :         free_rpc_bdev_lvol_rename_lvstore(&req);
     217                 :          3 : }
     218                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_rename_lvstore", rpc_bdev_lvol_rename_lvstore, SPDK_RPC_RUNTIME)
     219                 :            : 
     220                 :            : struct rpc_bdev_lvol_delete_lvstore {
     221                 :            :         char *uuid;
     222                 :            :         char *lvs_name;
     223                 :            : };
     224                 :            : 
     225                 :            : static void
     226                 :        144 : free_rpc_bdev_lvol_delete_lvstore(struct rpc_bdev_lvol_delete_lvstore *req)
     227                 :            : {
     228   [ #  #  #  # ]:        144 :         free(req->uuid);
     229   [ #  #  #  # ]:        144 :         free(req->lvs_name);
     230                 :        144 : }
     231                 :            : 
     232                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_delete_lvstore_decoders[] = {
     233                 :            :         {"uuid", offsetof(struct rpc_bdev_lvol_delete_lvstore, uuid), spdk_json_decode_string, true},
     234                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_delete_lvstore, lvs_name), spdk_json_decode_string, true},
     235                 :            : };
     236                 :            : 
     237                 :            : static void
     238                 :        139 : rpc_lvol_store_destroy_cb(void *cb_arg, int lvserrno)
     239                 :            : {
     240                 :        139 :         struct spdk_jsonrpc_request *request = cb_arg;
     241                 :            : 
     242         [ +  + ]:        139 :         if (lvserrno != 0) {
     243                 :          0 :                 goto invalid;
     244                 :            :         }
     245                 :            : 
     246                 :        139 :         spdk_jsonrpc_send_bool_response(request, true);
     247                 :        139 :         return;
     248                 :            : 
     249                 :          0 : invalid:
     250                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     251         [ #  # ]:          0 :                                          spdk_strerror(-lvserrno));
     252                 :          1 : }
     253                 :            : 
     254                 :            : static void
     255                 :        144 : rpc_bdev_lvol_delete_lvstore(struct spdk_jsonrpc_request *request,
     256                 :            :                              const struct spdk_json_val *params)
     257                 :            : {
     258                 :        144 :         struct rpc_bdev_lvol_delete_lvstore req = {};
     259                 :        144 :         struct spdk_lvol_store *lvs = NULL;
     260                 :            :         int rc;
     261                 :            : 
     262         [ -  + ]:        144 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_delete_lvstore_decoders,
     263                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_delete_lvstore_decoders),
     264                 :            :                                     &req)) {
     265   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     266                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     267                 :            :                                                  "spdk_json_decode_object failed");
     268                 :          0 :                 goto cleanup;
     269                 :            :         }
     270                 :            : 
     271         [ #  # ]:        144 :         rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
     272         [ +  + ]:        144 :         if (rc != 0) {
     273         [ #  # ]:          5 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     274                 :          5 :                 goto cleanup;
     275                 :            :         }
     276                 :            : 
     277                 :        139 :         vbdev_lvs_destruct(lvs, rpc_lvol_store_destroy_cb, request);
     278                 :            : 
     279                 :        143 : cleanup:
     280                 :        144 :         free_rpc_bdev_lvol_delete_lvstore(&req);
     281                 :        144 : }
     282                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_delete_lvstore", rpc_bdev_lvol_delete_lvstore, SPDK_RPC_RUNTIME)
     283                 :            : 
     284                 :            : struct rpc_bdev_lvol_create {
     285                 :            :         char *uuid;
     286                 :            :         char *lvs_name;
     287                 :            :         char *lvol_name;
     288                 :            :         uint64_t size_in_mib;
     289                 :            :         bool thin_provision;
     290                 :            :         char *clear_method;
     291                 :            : };
     292                 :            : 
     293                 :            : static void
     294                 :        481 : free_rpc_bdev_lvol_create(struct rpc_bdev_lvol_create *req)
     295                 :            : {
     296   [ #  #  #  # ]:        481 :         free(req->uuid);
     297   [ #  #  #  # ]:        481 :         free(req->lvs_name);
     298   [ #  #  #  # ]:        481 :         free(req->lvol_name);
     299   [ #  #  #  # ]:        481 :         free(req->clear_method);
     300                 :        481 : }
     301                 :            : 
     302                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_create_decoders[] = {
     303                 :            :         {"uuid", offsetof(struct rpc_bdev_lvol_create, uuid), spdk_json_decode_string, true},
     304                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_create, lvs_name), spdk_json_decode_string, true},
     305                 :            :         {"lvol_name", offsetof(struct rpc_bdev_lvol_create, lvol_name), spdk_json_decode_string},
     306                 :            :         {"size_in_mib", offsetof(struct rpc_bdev_lvol_create, size_in_mib), spdk_json_decode_uint64},
     307                 :            :         {"thin_provision", offsetof(struct rpc_bdev_lvol_create, thin_provision), spdk_json_decode_bool, true},
     308                 :            :         {"clear_method", offsetof(struct rpc_bdev_lvol_create, clear_method), spdk_json_decode_string, true},
     309                 :            : };
     310                 :            : 
     311                 :            : static void
     312                 :        479 : rpc_bdev_lvol_create_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
     313                 :            : {
     314                 :            :         struct spdk_json_write_ctx *w;
     315                 :        479 :         struct spdk_jsonrpc_request *request = cb_arg;
     316                 :            : 
     317         [ +  + ]:        479 :         if (lvolerrno != 0) {
     318                 :          2 :                 goto invalid;
     319                 :            :         }
     320                 :            : 
     321                 :        477 :         w = spdk_jsonrpc_begin_result(request);
     322         [ #  # ]:        477 :         spdk_json_write_string(w, lvol->unique_id);
     323                 :        477 :         spdk_jsonrpc_end_result(request, w);
     324                 :        477 :         return;
     325                 :            : 
     326                 :          2 : invalid:
     327                 :          2 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     328         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     329                 :          2 : }
     330                 :            : 
     331                 :            : static void
     332                 :        481 : rpc_bdev_lvol_create(struct spdk_jsonrpc_request *request,
     333                 :            :                      const struct spdk_json_val *params)
     334                 :            : {
     335                 :        481 :         struct rpc_bdev_lvol_create req = {};
     336                 :            :         enum lvol_clear_method clear_method;
     337                 :        481 :         int rc = 0;
     338                 :        481 :         struct spdk_lvol_store *lvs = NULL;
     339                 :            : 
     340   [ +  +  -  +  :        481 :         SPDK_INFOLOG(lvol_rpc, "Creating blob\n");
                   #  # ]
     341                 :            : 
     342         [ -  + ]:        481 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_create_decoders,
     343                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_create_decoders),
     344                 :            :                                     &req)) {
     345   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     346                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     347                 :            :                                                  "spdk_json_decode_object failed");
     348                 :          0 :                 goto cleanup;
     349                 :            :         }
     350                 :            : 
     351         [ #  # ]:        481 :         rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
     352         [ +  + ]:        481 :         if (rc != 0) {
     353         [ #  # ]:          1 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     354                 :          1 :                 goto cleanup;
     355                 :            :         }
     356                 :            : 
     357   [ +  +  #  # ]:        480 :         if (req.clear_method != NULL) {
     358   [ -  +  +  +  :          3 :                 if (!strcasecmp(req.clear_method, "none")) {
             #  #  #  # ]
     359                 :          1 :                         clear_method = LVOL_CLEAR_WITH_NONE;
     360   [ -  +  +  -  :          2 :                 } else if (!strcasecmp(req.clear_method, "unmap")) {
             #  #  #  # ]
     361                 :          2 :                         clear_method = LVOL_CLEAR_WITH_UNMAP;
     362   [ #  #  #  #  :          0 :                 } else if (!strcasecmp(req.clear_method, "write_zeroes")) {
             #  #  #  # ]
     363                 :          0 :                         clear_method = LVOL_CLEAR_WITH_WRITE_ZEROES;
     364                 :          0 :                 } else {
     365                 :          0 :                         spdk_jsonrpc_send_error_response(request, -EINVAL, "Invalid clean_method option");
     366                 :          0 :                         goto cleanup;
     367                 :            :                 }
     368                 :          0 :         } else {
     369                 :        477 :                 clear_method = LVOL_CLEAR_WITH_DEFAULT;
     370                 :            :         }
     371                 :            : 
     372   [ #  #  #  # ]:        482 :         rc = vbdev_lvol_create(lvs, req.lvol_name, req.size_in_mib * 1024 * 1024,
     373   [ -  +  #  # ]:        480 :                                req.thin_provision, clear_method, rpc_bdev_lvol_create_cb, request);
     374         [ +  + ]:        480 :         if (rc < 0) {
     375         [ #  # ]:          1 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     376                 :          1 :                 goto cleanup;
     377                 :            :         }
     378                 :            : 
     379                 :        479 : cleanup:
     380                 :        481 :         free_rpc_bdev_lvol_create(&req);
     381                 :        481 : }
     382                 :            : 
     383                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_create", rpc_bdev_lvol_create, SPDK_RPC_RUNTIME)
     384                 :            : 
     385                 :            : struct rpc_bdev_lvol_snapshot {
     386                 :            :         char *lvol_name;
     387                 :            :         char *snapshot_name;
     388                 :            : };
     389                 :            : 
     390                 :            : static void
     391                 :         39 : free_rpc_bdev_lvol_snapshot(struct rpc_bdev_lvol_snapshot *req)
     392                 :            : {
     393   [ #  #  #  # ]:         39 :         free(req->lvol_name);
     394   [ #  #  #  # ]:         39 :         free(req->snapshot_name);
     395                 :         39 : }
     396                 :            : 
     397                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_snapshot_decoders[] = {
     398                 :            :         {"lvol_name", offsetof(struct rpc_bdev_lvol_snapshot, lvol_name), spdk_json_decode_string},
     399                 :            :         {"snapshot_name", offsetof(struct rpc_bdev_lvol_snapshot, snapshot_name), spdk_json_decode_string},
     400                 :            : };
     401                 :            : 
     402                 :            : static void
     403                 :         39 : rpc_bdev_lvol_snapshot_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
     404                 :            : {
     405                 :            :         struct spdk_json_write_ctx *w;
     406                 :         39 :         struct spdk_jsonrpc_request *request = cb_arg;
     407                 :            : 
     408         [ +  + ]:         39 :         if (lvolerrno != 0) {
     409                 :          1 :                 goto invalid;
     410                 :            :         }
     411                 :            : 
     412                 :         38 :         w = spdk_jsonrpc_begin_result(request);
     413         [ #  # ]:         38 :         spdk_json_write_string(w, lvol->unique_id);
     414                 :         38 :         spdk_jsonrpc_end_result(request, w);
     415                 :         38 :         return;
     416                 :            : 
     417                 :          1 : invalid:
     418                 :          1 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     419         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     420                 :          1 : }
     421                 :            : 
     422                 :            : static void
     423                 :         39 : rpc_bdev_lvol_snapshot(struct spdk_jsonrpc_request *request,
     424                 :            :                        const struct spdk_json_val *params)
     425                 :            : {
     426                 :         39 :         struct rpc_bdev_lvol_snapshot req = {};
     427                 :            :         struct spdk_bdev *bdev;
     428                 :            :         struct spdk_lvol *lvol;
     429                 :            : 
     430   [ +  +  -  +  :         39 :         SPDK_INFOLOG(lvol_rpc, "Snapshotting blob\n");
                   #  # ]
     431                 :            : 
     432         [ -  + ]:         39 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_snapshot_decoders,
     433                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_snapshot_decoders),
     434                 :            :                                     &req)) {
     435   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     436                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     437                 :            :                                                  "spdk_json_decode_object failed");
     438                 :          0 :                 goto cleanup;
     439                 :            :         }
     440                 :            : 
     441                 :         39 :         bdev = spdk_bdev_get_by_name(req.lvol_name);
     442         [ +  + ]:         39 :         if (bdev == NULL) {
     443   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.lvol_name);
                   #  # ]
     444                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     445                 :          0 :                 goto cleanup;
     446                 :            :         }
     447                 :            : 
     448                 :         39 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     449         [ +  + ]:         39 :         if (lvol == NULL) {
     450                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
     451                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     452                 :          0 :                 goto cleanup;
     453                 :            :         }
     454                 :            : 
     455         [ #  # ]:         39 :         vbdev_lvol_create_snapshot(lvol, req.snapshot_name, rpc_bdev_lvol_snapshot_cb, request);
     456                 :            : 
     457                 :         38 : cleanup:
     458                 :         39 :         free_rpc_bdev_lvol_snapshot(&req);
     459                 :         39 : }
     460                 :            : 
     461                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_snapshot", rpc_bdev_lvol_snapshot, SPDK_RPC_RUNTIME)
     462                 :            : 
     463                 :            : struct rpc_bdev_lvol_clone {
     464                 :            :         char *snapshot_name;
     465                 :            :         char *clone_name;
     466                 :            : };
     467                 :            : 
     468                 :            : static void
     469                 :         25 : free_rpc_bdev_lvol_clone(struct rpc_bdev_lvol_clone *req)
     470                 :            : {
     471   [ #  #  #  # ]:         25 :         free(req->snapshot_name);
     472   [ #  #  #  # ]:         25 :         free(req->clone_name);
     473                 :         25 : }
     474                 :            : 
     475                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_decoders[] = {
     476                 :            :         {"snapshot_name", offsetof(struct rpc_bdev_lvol_clone, snapshot_name), spdk_json_decode_string},
     477                 :            :         {"clone_name", offsetof(struct rpc_bdev_lvol_clone, clone_name), spdk_json_decode_string, true},
     478                 :            : };
     479                 :            : 
     480                 :            : static void
     481                 :         32 : rpc_bdev_lvol_clone_cb(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
     482                 :            : {
     483                 :            :         struct spdk_json_write_ctx *w;
     484                 :         32 :         struct spdk_jsonrpc_request *request = cb_arg;
     485                 :            : 
     486         [ +  + ]:         32 :         if (lvolerrno != 0) {
     487                 :          2 :                 goto invalid;
     488                 :            :         }
     489                 :            : 
     490                 :         30 :         w = spdk_jsonrpc_begin_result(request);
     491         [ #  # ]:         30 :         spdk_json_write_string(w, lvol->unique_id);
     492                 :         30 :         spdk_jsonrpc_end_result(request, w);
     493                 :         30 :         return;
     494                 :            : 
     495                 :          2 : invalid:
     496                 :          2 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     497         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     498                 :          1 : }
     499                 :            : 
     500                 :            : static void
     501                 :         25 : rpc_bdev_lvol_clone(struct spdk_jsonrpc_request *request,
     502                 :            :                     const struct spdk_json_val *params)
     503                 :            : {
     504                 :         25 :         struct rpc_bdev_lvol_clone req = {};
     505                 :            :         struct spdk_bdev *bdev;
     506                 :            :         struct spdk_lvol *lvol;
     507                 :            : 
     508   [ +  +  -  +  :         25 :         SPDK_INFOLOG(lvol_rpc, "Cloning blob\n");
                   #  # ]
     509                 :            : 
     510         [ -  + ]:         25 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_decoders,
     511                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_clone_decoders),
     512                 :            :                                     &req)) {
     513   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     514                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     515                 :            :                                                  "spdk_json_decode_object failed");
     516                 :          0 :                 goto cleanup;
     517                 :            :         }
     518                 :            : 
     519                 :         25 :         bdev = spdk_bdev_get_by_name(req.snapshot_name);
     520         [ +  + ]:         25 :         if (bdev == NULL) {
     521   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.snapshot_name);
                   #  # ]
     522                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     523                 :          0 :                 goto cleanup;
     524                 :            :         }
     525                 :            : 
     526                 :         25 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     527         [ +  + ]:         25 :         if (lvol == NULL) {
     528                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
     529                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     530                 :          0 :                 goto cleanup;
     531                 :            :         }
     532                 :            : 
     533         [ #  # ]:         25 :         vbdev_lvol_create_clone(lvol, req.clone_name, rpc_bdev_lvol_clone_cb, request);
     534                 :            : 
     535                 :         24 : cleanup:
     536                 :         25 :         free_rpc_bdev_lvol_clone(&req);
     537                 :         25 : }
     538                 :            : 
     539                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_clone", rpc_bdev_lvol_clone, SPDK_RPC_RUNTIME)
     540                 :            : 
     541                 :            : struct rpc_bdev_lvol_clone_bdev {
     542                 :            :         /* name or UUID. Whichever is used, the UUID will be stored in the lvol's metadata. */
     543                 :            :         char *bdev_name;
     544                 :            :         char *lvs_name;
     545                 :            :         char *clone_name;
     546                 :            : };
     547                 :            : 
     548                 :            : static void
     549                 :          7 : free_rpc_bdev_lvol_clone_bdev(struct rpc_bdev_lvol_clone_bdev *req)
     550                 :            : {
     551   [ #  #  #  # ]:          7 :         free(req->bdev_name);
     552   [ #  #  #  # ]:          7 :         free(req->lvs_name);
     553   [ #  #  #  # ]:          7 :         free(req->clone_name);
     554                 :          7 : }
     555                 :            : 
     556                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_clone_bdev_decoders[] = {
     557                 :            :         {
     558                 :            :                 "bdev", offsetof(struct rpc_bdev_lvol_clone_bdev, bdev_name),
     559                 :            :                 spdk_json_decode_string, false
     560                 :            :         },
     561                 :            :         {
     562                 :            :                 "lvs_name", offsetof(struct rpc_bdev_lvol_clone_bdev, lvs_name),
     563                 :            :                 spdk_json_decode_string, false
     564                 :            :         },
     565                 :            :         {
     566                 :            :                 "clone_name", offsetof(struct rpc_bdev_lvol_clone_bdev, clone_name),
     567                 :            :                 spdk_json_decode_string, false
     568                 :            :         },
     569                 :            : };
     570                 :            : 
     571                 :            : static void
     572                 :          7 : rpc_bdev_lvol_clone_bdev(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
     573                 :            : {
     574                 :          7 :         struct rpc_bdev_lvol_clone_bdev req = {};
     575                 :            :         struct spdk_bdev *bdev;
     576                 :          7 :         struct spdk_lvol_store *lvs = NULL;
     577                 :            :         struct spdk_lvol *lvol;
     578                 :            :         int rc;
     579                 :            : 
     580   [ -  +  -  +  :          7 :         SPDK_INFOLOG(lvol_rpc, "Cloning bdev\n");
                   #  # ]
     581                 :            : 
     582         [ -  + ]:          7 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_clone_bdev_decoders,
     583                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_clone_bdev_decoders), &req)) {
     584   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     585                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     586                 :            :                                                  "spdk_json_decode_object failed");
     587                 :          0 :                 goto cleanup;
     588                 :            :         }
     589                 :            : 
     590         [ #  # ]:          7 :         rc = vbdev_get_lvol_store_by_uuid_xor_name(NULL, req.lvs_name, &lvs);
     591         [ -  + ]:          7 :         if (rc != 0) {
     592   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "lvs_name '%s' not found\n", req.lvs_name);
             #  #  #  # ]
     593                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     594                 :            :                                                  "lvs does not exist");
     595                 :          0 :                 goto cleanup;
     596                 :            :         }
     597                 :            : 
     598                 :          7 :         bdev = spdk_bdev_get_by_name(req.bdev_name);
     599         [ -  + ]:          7 :         if (bdev == NULL) {
     600   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "bdev '%s' does not exist\n", req.bdev_name);
                   #  # ]
     601                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     602                 :            :                                                  "bdev does not exist");
     603                 :          0 :                 goto cleanup;
     604                 :            :         }
     605                 :            : 
     606                 :          7 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     607   [ -  +  -  -  :          7 :         if (lvol != NULL && lvol->lvol_store == lvs) {
             #  #  #  # ]
     608   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "bdev '%s' is an lvol in lvstore '%s\n", req.bdev_name,
             #  #  #  # ]
     609                 :            :                              req.lvs_name);
     610                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     611                 :            :                                                  "bdev is an lvol in same lvs as clone; "
     612                 :            :                                                  "use bdev_lvol_clone instead");
     613                 :          0 :                 goto cleanup;
     614                 :            :         }
     615                 :            : 
     616         [ #  # ]:          7 :         vbdev_lvol_create_bdev_clone(req.bdev_name, lvs, req.clone_name,
     617                 :          0 :                                      rpc_bdev_lvol_clone_cb, request);
     618                 :          7 : cleanup:
     619                 :          7 :         free_rpc_bdev_lvol_clone_bdev(&req);
     620                 :          7 : }
     621                 :            : 
     622                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_clone_bdev", rpc_bdev_lvol_clone_bdev, SPDK_RPC_RUNTIME)
     623                 :            : 
     624                 :            : struct rpc_bdev_lvol_rename {
     625                 :            :         char *old_name;
     626                 :            :         char *new_name;
     627                 :            : };
     628                 :            : 
     629                 :            : static void
     630                 :          6 : free_rpc_bdev_lvol_rename(struct rpc_bdev_lvol_rename *req)
     631                 :            : {
     632   [ #  #  #  # ]:          6 :         free(req->old_name);
     633   [ #  #  #  # ]:          6 :         free(req->new_name);
     634                 :          6 : }
     635                 :            : 
     636                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_rename_decoders[] = {
     637                 :            :         {"old_name", offsetof(struct rpc_bdev_lvol_rename, old_name), spdk_json_decode_string},
     638                 :            :         {"new_name", offsetof(struct rpc_bdev_lvol_rename, new_name), spdk_json_decode_string},
     639                 :            : };
     640                 :            : 
     641                 :            : static void
     642                 :          4 : rpc_bdev_lvol_rename_cb(void *cb_arg, int lvolerrno)
     643                 :            : {
     644                 :          4 :         struct spdk_jsonrpc_request *request = cb_arg;
     645                 :            : 
     646         [ -  + ]:          4 :         if (lvolerrno != 0) {
     647                 :          0 :                 goto invalid;
     648                 :            :         }
     649                 :            : 
     650                 :          4 :         spdk_jsonrpc_send_bool_response(request, true);
     651                 :          4 :         return;
     652                 :            : 
     653                 :          0 : invalid:
     654                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     655         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     656                 :          0 : }
     657                 :            : 
     658                 :            : static void
     659                 :          6 : rpc_bdev_lvol_rename(struct spdk_jsonrpc_request *request,
     660                 :            :                      const struct spdk_json_val *params)
     661                 :            : {
     662                 :          6 :         struct rpc_bdev_lvol_rename req = {};
     663                 :            :         struct spdk_bdev *bdev;
     664                 :            :         struct spdk_lvol *lvol;
     665                 :            : 
     666   [ -  +  -  +  :          6 :         SPDK_INFOLOG(lvol_rpc, "Renaming lvol\n");
                   #  # ]
     667                 :            : 
     668         [ -  + ]:          6 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_rename_decoders,
     669                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_rename_decoders),
     670                 :            :                                     &req)) {
     671   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     672                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     673                 :            :                                                  "spdk_json_decode_object failed");
     674                 :          0 :                 goto cleanup;
     675                 :            :         }
     676                 :            : 
     677                 :          6 :         bdev = spdk_bdev_get_by_name(req.old_name);
     678         [ +  + ]:          6 :         if (bdev == NULL) {
     679                 :          2 :                 SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name);
     680                 :          2 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     681                 :          2 :                 goto cleanup;
     682                 :            :         }
     683                 :            : 
     684                 :          4 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     685         [ -  + ]:          4 :         if (lvol == NULL) {
     686                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
     687                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     688                 :          0 :                 goto cleanup;
     689                 :            :         }
     690                 :            : 
     691         [ #  # ]:          4 :         vbdev_lvol_rename(lvol, req.new_name, rpc_bdev_lvol_rename_cb, request);
     692                 :            : 
     693                 :          6 : cleanup:
     694                 :          6 :         free_rpc_bdev_lvol_rename(&req);
     695                 :          6 : }
     696                 :            : 
     697                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_rename", rpc_bdev_lvol_rename, SPDK_RPC_RUNTIME)
     698                 :            : 
     699                 :            : struct rpc_bdev_lvol_inflate {
     700                 :            :         char *name;
     701                 :            : };
     702                 :            : 
     703                 :            : static void
     704                 :         10 : free_rpc_bdev_lvol_inflate(struct rpc_bdev_lvol_inflate *req)
     705                 :            : {
     706   [ #  #  #  # ]:         10 :         free(req->name);
     707                 :         10 : }
     708                 :            : 
     709                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_inflate_decoders[] = {
     710                 :            :         {"name", offsetof(struct rpc_bdev_lvol_inflate, name), spdk_json_decode_string},
     711                 :            : };
     712                 :            : 
     713                 :            : static void
     714                 :         10 : rpc_bdev_lvol_inflate_cb(void *cb_arg, int lvolerrno)
     715                 :            : {
     716                 :         10 :         struct spdk_jsonrpc_request *request = cb_arg;
     717                 :            : 
     718         [ +  + ]:         10 :         if (lvolerrno != 0) {
     719                 :          1 :                 goto invalid;
     720                 :            :         }
     721                 :            : 
     722                 :          9 :         spdk_jsonrpc_send_bool_response(request, true);
     723                 :          9 :         return;
     724                 :            : 
     725                 :          1 : invalid:
     726                 :          1 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     727         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     728                 :          0 : }
     729                 :            : 
     730                 :            : static void
     731                 :          7 : rpc_bdev_lvol_inflate(struct spdk_jsonrpc_request *request,
     732                 :            :                       const struct spdk_json_val *params)
     733                 :            : {
     734                 :          7 :         struct rpc_bdev_lvol_inflate req = {};
     735                 :            :         struct spdk_bdev *bdev;
     736                 :            :         struct spdk_lvol *lvol;
     737                 :            : 
     738   [ -  +  -  +  :          7 :         SPDK_INFOLOG(lvol_rpc, "Inflating lvol\n");
                   #  # ]
     739                 :            : 
     740         [ -  + ]:          7 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders,
     741                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders),
     742                 :            :                                     &req)) {
     743   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     744                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     745                 :            :                                                  "spdk_json_decode_object failed");
     746                 :          0 :                 goto cleanup;
     747                 :            :         }
     748                 :            : 
     749                 :          7 :         bdev = spdk_bdev_get_by_name(req.name);
     750         [ -  + ]:          7 :         if (bdev == NULL) {
     751                 :          0 :                 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name);
     752                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     753                 :          0 :                 goto cleanup;
     754                 :            :         }
     755                 :            : 
     756                 :          7 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     757         [ -  + ]:          7 :         if (lvol == NULL) {
     758                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
     759                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     760                 :          0 :                 goto cleanup;
     761                 :            :         }
     762                 :            : 
     763                 :          7 :         spdk_lvol_inflate(lvol, rpc_bdev_lvol_inflate_cb, request);
     764                 :            : 
     765                 :          7 : cleanup:
     766                 :          7 :         free_rpc_bdev_lvol_inflate(&req);
     767                 :          7 : }
     768                 :            : 
     769                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_inflate", rpc_bdev_lvol_inflate, SPDK_RPC_RUNTIME)
     770                 :            : 
     771                 :            : static void
     772                 :          3 : rpc_bdev_lvol_decouple_parent(struct spdk_jsonrpc_request *request,
     773                 :            :                               const struct spdk_json_val *params)
     774                 :            : {
     775                 :          3 :         struct rpc_bdev_lvol_inflate req = {};
     776                 :            :         struct spdk_bdev *bdev;
     777                 :            :         struct spdk_lvol *lvol;
     778                 :            : 
     779   [ -  +  -  +  :          3 :         SPDK_INFOLOG(lvol_rpc, "Decoupling parent of lvol\n");
                   #  # ]
     780                 :            : 
     781         [ -  + ]:          3 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_inflate_decoders,
     782                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_inflate_decoders),
     783                 :            :                                     &req)) {
     784   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     785                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     786                 :            :                                                  "spdk_json_decode_object failed");
     787                 :          0 :                 goto cleanup;
     788                 :            :         }
     789                 :            : 
     790                 :          3 :         bdev = spdk_bdev_get_by_name(req.name);
     791         [ -  + ]:          3 :         if (bdev == NULL) {
     792                 :          0 :                 SPDK_ERRLOG("bdev '%s' does not exist\n", req.name);
     793                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     794                 :          0 :                 goto cleanup;
     795                 :            :         }
     796                 :            : 
     797                 :          3 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     798         [ -  + ]:          3 :         if (lvol == NULL) {
     799                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
     800                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     801                 :          0 :                 goto cleanup;
     802                 :            :         }
     803                 :            : 
     804                 :          3 :         spdk_lvol_decouple_parent(lvol, rpc_bdev_lvol_inflate_cb, request);
     805                 :            : 
     806                 :          3 : cleanup:
     807                 :          3 :         free_rpc_bdev_lvol_inflate(&req);
     808                 :          3 : }
     809                 :            : 
     810                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_decouple_parent", rpc_bdev_lvol_decouple_parent, SPDK_RPC_RUNTIME)
     811                 :            : 
     812                 :            : struct rpc_bdev_lvol_resize {
     813                 :            :         char *name;
     814                 :            :         uint64_t size_in_mib;
     815                 :            : };
     816                 :            : 
     817                 :            : static void
     818                 :         25 : free_rpc_bdev_lvol_resize(struct rpc_bdev_lvol_resize *req)
     819                 :            : {
     820   [ #  #  #  # ]:         25 :         free(req->name);
     821                 :         25 : }
     822                 :            : 
     823                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_resize_decoders[] = {
     824                 :            :         {"name", offsetof(struct rpc_bdev_lvol_resize, name), spdk_json_decode_string},
     825                 :            :         {"size_in_mib", offsetof(struct rpc_bdev_lvol_resize, size_in_mib), spdk_json_decode_uint64},
     826                 :            : };
     827                 :            : 
     828                 :            : static void
     829                 :         24 : rpc_bdev_lvol_resize_cb(void *cb_arg, int lvolerrno)
     830                 :            : {
     831                 :         24 :         struct spdk_jsonrpc_request *request = cb_arg;
     832                 :            : 
     833         [ +  + ]:         24 :         if (lvolerrno != 0) {
     834                 :          1 :                 goto invalid;
     835                 :            :         }
     836                 :            : 
     837                 :         23 :         spdk_jsonrpc_send_bool_response(request, true);
     838                 :         23 :         return;
     839                 :            : 
     840                 :          1 : invalid:
     841                 :          1 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     842         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     843                 :          0 : }
     844                 :            : 
     845                 :            : static void
     846                 :         25 : rpc_bdev_lvol_resize(struct spdk_jsonrpc_request *request,
     847                 :            :                      const struct spdk_json_val *params)
     848                 :            : {
     849                 :         25 :         struct rpc_bdev_lvol_resize req = {};
     850                 :            :         struct spdk_bdev *bdev;
     851                 :            :         struct spdk_lvol *lvol;
     852                 :            : 
     853   [ -  +  -  +  :         25 :         SPDK_INFOLOG(lvol_rpc, "Resizing lvol\n");
                   #  # ]
     854                 :            : 
     855         [ -  + ]:         25 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_resize_decoders,
     856                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_resize_decoders),
     857                 :            :                                     &req)) {
     858   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     859                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     860                 :            :                                                  "spdk_json_decode_object failed");
     861                 :          0 :                 goto cleanup;
     862                 :            :         }
     863                 :            : 
     864                 :         25 :         bdev = spdk_bdev_get_by_name(req.name);
     865         [ +  + ]:         25 :         if (bdev == NULL) {
     866                 :          1 :                 SPDK_ERRLOG("no bdev for provided name %s\n", req.name);
     867                 :          1 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     868                 :          1 :                 goto cleanup;
     869                 :            :         }
     870                 :            : 
     871                 :         24 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     872         [ -  + ]:         24 :         if (lvol == NULL) {
     873                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     874                 :          0 :                 goto cleanup;
     875                 :            :         }
     876                 :            : 
     877                 :            : 
     878         [ #  # ]:         24 :         vbdev_lvol_resize(lvol, req.size_in_mib * 1024 * 1024, rpc_bdev_lvol_resize_cb, request);
     879                 :            : 
     880                 :         25 : cleanup:
     881                 :         25 :         free_rpc_bdev_lvol_resize(&req);
     882                 :         25 : }
     883                 :            : 
     884                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_resize", rpc_bdev_lvol_resize, SPDK_RPC_RUNTIME)
     885                 :            : 
     886                 :            : struct rpc_set_ro_lvol_bdev {
     887                 :            :         char *name;
     888                 :            : };
     889                 :            : 
     890                 :            : static void
     891                 :          4 : free_rpc_set_ro_lvol_bdev(struct rpc_set_ro_lvol_bdev *req)
     892                 :            : {
     893   [ #  #  #  # ]:          4 :         free(req->name);
     894                 :          4 : }
     895                 :            : 
     896                 :            : static const struct spdk_json_object_decoder rpc_set_ro_lvol_bdev_decoders[] = {
     897                 :            :         {"name", offsetof(struct rpc_set_ro_lvol_bdev, name), spdk_json_decode_string},
     898                 :            : };
     899                 :            : 
     900                 :            : static void
     901                 :          4 : rpc_set_ro_lvol_bdev_cb(void *cb_arg, int lvolerrno)
     902                 :            : {
     903                 :          4 :         struct spdk_jsonrpc_request *request = cb_arg;
     904                 :            : 
     905         [ -  + ]:          4 :         if (lvolerrno != 0) {
     906                 :          0 :                 goto invalid;
     907                 :            :         }
     908                 :            : 
     909                 :          4 :         spdk_jsonrpc_send_bool_response(request, true);
     910                 :          4 :         return;
     911                 :            : 
     912                 :          0 : invalid:
     913                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     914         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     915                 :          0 : }
     916                 :            : 
     917                 :            : static void
     918                 :          4 : rpc_bdev_lvol_set_read_only(struct spdk_jsonrpc_request *request,
     919                 :            :                             const struct spdk_json_val *params)
     920                 :            : {
     921                 :          4 :         struct rpc_set_ro_lvol_bdev req = {};
     922                 :            :         struct spdk_bdev *bdev;
     923                 :            :         struct spdk_lvol *lvol;
     924                 :            : 
     925   [ -  +  -  +  :          4 :         SPDK_INFOLOG(lvol_rpc, "Setting lvol as read only\n");
                   #  # ]
     926                 :            : 
     927         [ -  + ]:          4 :         if (spdk_json_decode_object(params, rpc_set_ro_lvol_bdev_decoders,
     928                 :            :                                     SPDK_COUNTOF(rpc_set_ro_lvol_bdev_decoders),
     929                 :            :                                     &req)) {
     930   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
     931                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     932                 :            :                                                  "spdk_json_decode_object failed");
     933                 :          0 :                 goto cleanup;
     934                 :            :         }
     935                 :            : 
     936         [ -  + ]:          4 :         if (req.name == NULL) {
     937                 :          0 :                 SPDK_ERRLOG("missing name param\n");
     938                 :          0 :                 spdk_jsonrpc_send_error_response(request, -EINVAL, "Missing name parameter");
     939                 :          0 :                 goto cleanup;
     940                 :            :         }
     941                 :            : 
     942                 :          4 :         bdev = spdk_bdev_get_by_name(req.name);
     943         [ -  + ]:          4 :         if (bdev == NULL) {
     944                 :          0 :                 SPDK_ERRLOG("no bdev for provided name %s\n", req.name);
     945                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     946                 :          0 :                 goto cleanup;
     947                 :            :         }
     948                 :            : 
     949                 :          4 :         lvol = vbdev_lvol_get_from_bdev(bdev);
     950         [ -  + ]:          4 :         if (lvol == NULL) {
     951                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
     952                 :          0 :                 goto cleanup;
     953                 :            :         }
     954                 :            : 
     955                 :          4 :         vbdev_lvol_set_read_only(lvol, rpc_set_ro_lvol_bdev_cb, request);
     956                 :            : 
     957                 :          4 : cleanup:
     958                 :          4 :         free_rpc_set_ro_lvol_bdev(&req);
     959                 :          4 : }
     960                 :            : 
     961                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_set_read_only", rpc_bdev_lvol_set_read_only, SPDK_RPC_RUNTIME)
     962                 :            : 
     963                 :            : struct rpc_bdev_lvol_delete {
     964                 :            :         char *name;
     965                 :            : };
     966                 :            : 
     967                 :            : static void
     968                 :        230 : free_rpc_bdev_lvol_delete(struct rpc_bdev_lvol_delete *req)
     969                 :            : {
     970   [ #  #  #  # ]:        230 :         free(req->name);
     971                 :        230 : }
     972                 :            : 
     973                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_delete_decoders[] = {
     974                 :            :         {"name", offsetof(struct rpc_bdev_lvol_delete, name), spdk_json_decode_string},
     975                 :            : };
     976                 :            : 
     977                 :            : static void
     978                 :        230 : rpc_bdev_lvol_delete_cb(void *cb_arg, int lvolerrno)
     979                 :            : {
     980                 :        230 :         struct spdk_jsonrpc_request *request = cb_arg;
     981                 :            : 
     982         [ +  + ]:        230 :         if (lvolerrno != 0) {
     983                 :          3 :                 goto invalid;
     984                 :            :         }
     985                 :            : 
     986                 :        227 :         spdk_jsonrpc_send_bool_response(request, true);
     987                 :        227 :         return;
     988                 :            : 
     989                 :          3 : invalid:
     990                 :          3 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     991         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
     992                 :          3 : }
     993                 :            : 
     994                 :            : static void
     995                 :        230 : rpc_bdev_lvol_delete(struct spdk_jsonrpc_request *request,
     996                 :            :                      const struct spdk_json_val *params)
     997                 :            : {
     998                 :        230 :         struct rpc_bdev_lvol_delete req = {};
     999                 :            :         struct spdk_bdev *bdev;
    1000                 :            :         struct spdk_lvol *lvol;
    1001                 :        227 :         struct spdk_uuid uuid;
    1002                 :            :         char *lvs_name, *lvol_name;
    1003                 :            : 
    1004         [ -  + ]:        230 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_delete_decoders,
    1005                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_delete_decoders),
    1006                 :            :                                     &req)) {
    1007   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1008                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1009                 :            :                                                  "spdk_json_decode_object failed");
    1010                 :          0 :                 goto cleanup;
    1011                 :            :         }
    1012                 :            : 
    1013                 :            :         /* lvol is not degraded, get lvol via bdev name or alias */
    1014                 :        230 :         bdev = spdk_bdev_get_by_name(req.name);
    1015         [ +  + ]:        230 :         if (bdev != NULL) {
    1016                 :        228 :                 lvol = vbdev_lvol_get_from_bdev(bdev);
    1017         [ +  - ]:        228 :                 if (lvol != NULL) {
    1018                 :        228 :                         goto done;
    1019                 :            :                 }
    1020                 :          0 :         }
    1021                 :            : 
    1022                 :            :         /* lvol is degraded, get lvol via UUID */
    1023         [ +  - ]:          2 :         if (spdk_uuid_parse(&uuid, req.name) == 0) {
    1024                 :          2 :                 lvol = spdk_lvol_get_by_uuid(&uuid);
    1025         [ +  - ]:          2 :                 if (lvol != NULL) {
    1026                 :          2 :                         goto done;
    1027                 :            :                 }
    1028                 :          0 :         }
    1029                 :            : 
    1030                 :            :         /* lvol is degraded, get lvol via lvs_name/lvol_name */
    1031         [ #  # ]:          0 :         lvol_name = strchr(req.name, '/');
    1032         [ #  # ]:          0 :         if (lvol_name != NULL) {
    1033         [ #  # ]:          0 :                 *lvol_name = '\0';
    1034         [ #  # ]:          0 :                 lvol_name++;
    1035                 :          0 :                 lvs_name = req.name;
    1036                 :          0 :                 lvol = spdk_lvol_get_by_names(lvs_name, lvol_name);
    1037         [ #  # ]:          0 :                 if (lvol != NULL) {
    1038                 :          0 :                         goto done;
    1039                 :            :                 }
    1040                 :          0 :         }
    1041                 :            : 
    1042                 :            :         /* Could not find lvol, degraded or not. */
    1043                 :          0 :         spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1044                 :          0 :         goto cleanup;
    1045                 :            : 
    1046                 :        227 : done:
    1047                 :        230 :         vbdev_lvol_destroy(lvol, rpc_bdev_lvol_delete_cb, request);
    1048                 :            : 
    1049                 :        227 : cleanup:
    1050                 :        230 :         free_rpc_bdev_lvol_delete(&req);
    1051                 :        230 : }
    1052                 :            : 
    1053                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_delete", rpc_bdev_lvol_delete, SPDK_RPC_RUNTIME)
    1054                 :            : 
    1055                 :            : struct rpc_bdev_lvol_get_lvstores {
    1056                 :            :         char *uuid;
    1057                 :            :         char *lvs_name;
    1058                 :            : };
    1059                 :            : 
    1060                 :            : static void
    1061                 :        534 : free_rpc_bdev_lvol_get_lvstores(struct rpc_bdev_lvol_get_lvstores *req)
    1062                 :            : {
    1063   [ #  #  #  # ]:        534 :         free(req->uuid);
    1064   [ #  #  #  # ]:        534 :         free(req->lvs_name);
    1065                 :        534 : }
    1066                 :            : 
    1067                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvstores_decoders[] = {
    1068                 :            :         {"uuid", offsetof(struct rpc_bdev_lvol_get_lvstores, uuid), spdk_json_decode_string, true},
    1069                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvstores, lvs_name), spdk_json_decode_string, true},
    1070                 :            : };
    1071                 :            : 
    1072                 :            : static void
    1073                 :        212 : rpc_dump_lvol_store_info(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev)
    1074                 :            : {
    1075                 :            :         struct spdk_blob_store *bs;
    1076                 :            :         uint64_t cluster_size;
    1077                 :            : 
    1078   [ #  #  #  #  :        212 :         bs = lvs_bdev->lvs->blobstore;
             #  #  #  # ]
    1079                 :        212 :         cluster_size = spdk_bs_get_cluster_size(bs);
    1080                 :            : 
    1081                 :        212 :         spdk_json_write_object_begin(w);
    1082                 :            : 
    1083   [ #  #  #  #  :        212 :         spdk_json_write_named_uuid(w, "uuid", &lvs_bdev->lvs->uuid);
                   #  # ]
    1084   [ #  #  #  #  :        212 :         spdk_json_write_named_string(w, "name", lvs_bdev->lvs->name);
                   #  # ]
    1085   [ #  #  #  # ]:        212 :         spdk_json_write_named_string(w, "base_bdev", spdk_bdev_get_name(lvs_bdev->bdev));
    1086                 :        212 :         spdk_json_write_named_uint64(w, "total_data_clusters", spdk_bs_total_data_cluster_count(bs));
    1087                 :        212 :         spdk_json_write_named_uint64(w, "free_clusters", spdk_bs_free_cluster_count(bs));
    1088                 :        212 :         spdk_json_write_named_uint64(w, "block_size", spdk_bs_get_io_unit_size(bs));
    1089                 :        212 :         spdk_json_write_named_uint64(w, "cluster_size", cluster_size);
    1090                 :            : 
    1091                 :        212 :         spdk_json_write_object_end(w);
    1092                 :        212 : }
    1093                 :            : 
    1094                 :            : static void
    1095                 :        534 : rpc_bdev_lvol_get_lvstores(struct spdk_jsonrpc_request *request,
    1096                 :            :                            const struct spdk_json_val *params)
    1097                 :            : {
    1098                 :        534 :         struct rpc_bdev_lvol_get_lvstores req = {};
    1099                 :            :         struct spdk_json_write_ctx *w;
    1100                 :        534 :         struct lvol_store_bdev *lvs_bdev = NULL;
    1101                 :        534 :         struct spdk_lvol_store *lvs = NULL;
    1102                 :            :         int rc;
    1103                 :            : 
    1104         [ +  + ]:        534 :         if (params != NULL) {
    1105         [ -  + ]:        106 :                 if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvstores_decoders,
    1106                 :            :                                             SPDK_COUNTOF(rpc_bdev_lvol_get_lvstores_decoders),
    1107                 :            :                                             &req)) {
    1108   [ #  #  #  #  :          0 :                         SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1109                 :          0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1110                 :            :                                                          "spdk_json_decode_object failed");
    1111                 :          0 :                         goto cleanup;
    1112                 :            :                 }
    1113                 :            : 
    1114         [ #  # ]:        106 :                 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
    1115         [ +  + ]:        106 :                 if (rc != 0) {
    1116         [ #  # ]:         50 :                         spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
    1117                 :         50 :                         goto cleanup;
    1118                 :            :                 }
    1119                 :            : 
    1120                 :         56 :                 lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
    1121         [ -  + ]:         56 :                 if (lvs_bdev == NULL) {
    1122                 :          0 :                         spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV));
    1123                 :          0 :                         goto cleanup;
    1124                 :            :                 }
    1125                 :          0 :         }
    1126                 :            : 
    1127                 :        484 :         w = spdk_jsonrpc_begin_result(request);
    1128                 :        484 :         spdk_json_write_array_begin(w);
    1129                 :            : 
    1130         [ +  + ]:        484 :         if (lvs_bdev != NULL) {
    1131                 :         56 :                 rpc_dump_lvol_store_info(w, lvs_bdev);
    1132                 :          0 :         } else {
    1133         [ +  + ]:        584 :                 for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL;
    1134                 :        156 :                      lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) {
    1135                 :        156 :                         rpc_dump_lvol_store_info(w, lvs_bdev);
    1136                 :          0 :                 }
    1137                 :            :         }
    1138                 :        484 :         spdk_json_write_array_end(w);
    1139                 :            : 
    1140                 :        484 :         spdk_jsonrpc_end_result(request, w);
    1141                 :            : 
    1142                 :        534 : cleanup:
    1143                 :        534 :         free_rpc_bdev_lvol_get_lvstores(&req);
    1144                 :        534 : }
    1145                 :            : 
    1146                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_get_lvstores", rpc_bdev_lvol_get_lvstores, SPDK_RPC_RUNTIME)
    1147                 :       2215 : SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_lvol_get_lvstores, get_lvol_stores)
    1148                 :            : 
    1149                 :            : struct rpc_bdev_lvol_get_lvols {
    1150                 :            :         char *lvs_uuid;
    1151                 :            :         char *lvs_name;
    1152                 :            : };
    1153                 :            : 
    1154                 :            : static void
    1155                 :         13 : free_rpc_bdev_lvol_get_lvols(struct rpc_bdev_lvol_get_lvols *req)
    1156                 :            : {
    1157   [ #  #  #  # ]:         13 :         free(req->lvs_uuid);
    1158   [ #  #  #  # ]:         13 :         free(req->lvs_name);
    1159                 :         13 : }
    1160                 :            : 
    1161                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_get_lvols_decoders[] = {
    1162                 :            :         {"lvs_uuid", offsetof(struct rpc_bdev_lvol_get_lvols, lvs_uuid), spdk_json_decode_string, true},
    1163                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_get_lvols, lvs_name), spdk_json_decode_string, true},
    1164                 :            : };
    1165                 :            : 
    1166                 :            : static void
    1167                 :         18 : rpc_dump_lvol(struct spdk_json_write_ctx *w, struct spdk_lvol *lvol)
    1168                 :            : {
    1169   [ #  #  #  # ]:         18 :         struct spdk_lvol_store *lvs = lvol->lvol_store;
    1170                 :            : 
    1171                 :         18 :         spdk_json_write_object_begin(w);
    1172                 :            : 
    1173   [ #  #  #  # ]:         18 :         spdk_json_write_named_string_fmt(w, "alias", "%s/%s", lvs->name, lvol->name);
    1174         [ #  # ]:         18 :         spdk_json_write_named_string(w, "uuid", lvol->uuid_str);
    1175         [ #  # ]:         18 :         spdk_json_write_named_string(w, "name", lvol->name);
    1176   [ #  #  #  # ]:         18 :         spdk_json_write_named_bool(w, "is_thin_provisioned", spdk_blob_is_thin_provisioned(lvol->blob));
    1177   [ #  #  #  # ]:         18 :         spdk_json_write_named_bool(w, "is_snapshot", spdk_blob_is_snapshot(lvol->blob));
    1178   [ #  #  #  # ]:         18 :         spdk_json_write_named_bool(w, "is_clone", spdk_blob_is_clone(lvol->blob));
    1179   [ #  #  #  # ]:         18 :         spdk_json_write_named_bool(w, "is_esnap_clone", spdk_blob_is_esnap_clone(lvol->blob));
    1180   [ #  #  #  # ]:         18 :         spdk_json_write_named_bool(w, "is_degraded", spdk_blob_is_degraded(lvol->blob));
    1181                 :         18 :         spdk_json_write_named_uint64(w, "num_allocated_clusters",
    1182   [ #  #  #  # ]:          0 :                                      spdk_blob_get_num_allocated_clusters(lvol->blob));
    1183                 :            : 
    1184                 :         18 :         spdk_json_write_named_object_begin(w, "lvs");
    1185         [ #  # ]:         18 :         spdk_json_write_named_string(w, "name", lvs->name);
    1186         [ #  # ]:         18 :         spdk_json_write_named_uuid(w, "uuid", &lvs->uuid);
    1187                 :         18 :         spdk_json_write_object_end(w);
    1188                 :            : 
    1189                 :         18 :         spdk_json_write_object_end(w);
    1190                 :         18 : }
    1191                 :            : 
    1192                 :            : static void
    1193                 :         13 : rpc_dump_lvols(struct spdk_json_write_ctx *w, struct lvol_store_bdev *lvs_bdev)
    1194                 :            : {
    1195   [ #  #  #  # ]:         13 :         struct spdk_lvol_store *lvs = lvs_bdev->lvs;
    1196                 :            :         struct spdk_lvol *lvol;
    1197                 :            : 
    1198   [ +  +  #  #  :         31 :         TAILQ_FOREACH(lvol, &lvs->lvols, link) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1199   [ -  +  #  #  :         18 :                 if (lvol->ref_count == 0) {
                   #  # ]
    1200                 :          0 :                         continue;
    1201                 :            :                 }
    1202                 :         18 :                 rpc_dump_lvol(w, lvol);
    1203                 :          0 :         }
    1204                 :         13 : }
    1205                 :            : 
    1206                 :            : static void
    1207                 :         13 : rpc_bdev_lvol_get_lvols(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
    1208                 :            : {
    1209                 :         13 :         struct rpc_bdev_lvol_get_lvols req = {};
    1210                 :            :         struct spdk_json_write_ctx *w;
    1211                 :         13 :         struct lvol_store_bdev *lvs_bdev = NULL;
    1212                 :         13 :         struct spdk_lvol_store *lvs = NULL;
    1213                 :            :         int rc;
    1214                 :            : 
    1215         [ -  + ]:         13 :         if (params != NULL) {
    1216         [ #  # ]:          0 :                 if (spdk_json_decode_object(params, rpc_bdev_lvol_get_lvols_decoders,
    1217                 :            :                                             SPDK_COUNTOF(rpc_bdev_lvol_get_lvols_decoders),
    1218                 :            :                                             &req)) {
    1219   [ #  #  #  #  :          0 :                         SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1220                 :          0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1221                 :            :                                                          "spdk_json_decode_object failed");
    1222                 :          0 :                         goto cleanup;
    1223                 :            :                 }
    1224                 :            : 
    1225         [ #  # ]:          0 :                 rc = vbdev_get_lvol_store_by_uuid_xor_name(req.lvs_uuid, req.lvs_name, &lvs);
    1226         [ #  # ]:          0 :                 if (rc != 0) {
    1227         [ #  # ]:          0 :                         spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
    1228                 :          0 :                         goto cleanup;
    1229                 :            :                 }
    1230                 :            : 
    1231                 :          0 :                 lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
    1232         [ #  # ]:          0 :                 if (lvs_bdev == NULL) {
    1233                 :          0 :                         spdk_jsonrpc_send_error_response(request, ENODEV, spdk_strerror(-ENODEV));
    1234                 :          0 :                         goto cleanup;
    1235                 :            :                 }
    1236                 :          0 :         }
    1237                 :            : 
    1238                 :         13 :         w = spdk_jsonrpc_begin_result(request);
    1239                 :         13 :         spdk_json_write_array_begin(w);
    1240                 :            : 
    1241         [ -  + ]:         13 :         if (lvs_bdev != NULL) {
    1242                 :          0 :                 rpc_dump_lvols(w, lvs_bdev);
    1243                 :          0 :         } else {
    1244         [ +  + ]:         26 :                 for (lvs_bdev = vbdev_lvol_store_first(); lvs_bdev != NULL;
    1245                 :         13 :                      lvs_bdev = vbdev_lvol_store_next(lvs_bdev)) {
    1246                 :         13 :                         rpc_dump_lvols(w, lvs_bdev);
    1247                 :          0 :                 }
    1248                 :            :         }
    1249                 :         13 :         spdk_json_write_array_end(w);
    1250                 :            : 
    1251                 :         13 :         spdk_jsonrpc_end_result(request, w);
    1252                 :            : 
    1253                 :         13 : cleanup:
    1254                 :         13 :         free_rpc_bdev_lvol_get_lvols(&req);
    1255                 :         13 : }
    1256                 :            : 
    1257                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_get_lvols", rpc_bdev_lvol_get_lvols, SPDK_RPC_RUNTIME)
    1258                 :            : 
    1259                 :            : struct rpc_bdev_lvol_grow_lvstore {
    1260                 :            :         char *uuid;
    1261                 :            :         char *lvs_name;
    1262                 :            : };
    1263                 :            : 
    1264                 :            : static void
    1265                 :          2 : free_rpc_bdev_lvol_grow_lvstore(struct rpc_bdev_lvol_grow_lvstore *req)
    1266                 :            : {
    1267   [ #  #  #  # ]:          2 :         free(req->uuid);
    1268   [ #  #  #  # ]:          2 :         free(req->lvs_name);
    1269                 :          2 : }
    1270                 :            : 
    1271                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_grow_lvstore_decoders[] = {
    1272                 :            :         {"uuid", offsetof(struct rpc_bdev_lvol_grow_lvstore, uuid), spdk_json_decode_string, true},
    1273                 :            :         {"lvs_name", offsetof(struct rpc_bdev_lvol_grow_lvstore, lvs_name), spdk_json_decode_string, true},
    1274                 :            : };
    1275                 :            : 
    1276                 :            : static void
    1277                 :          2 : rpc_bdev_lvol_grow_lvstore_cb(void *cb_arg, int lvserrno)
    1278                 :            : {
    1279                 :          2 :         struct spdk_jsonrpc_request *request = cb_arg;
    1280                 :            : 
    1281         [ -  + ]:          2 :         if (lvserrno != 0) {
    1282                 :          0 :                 goto invalid;
    1283                 :            :         }
    1284                 :            : 
    1285                 :          2 :         spdk_jsonrpc_send_bool_response(request, true);
    1286                 :          2 :         return;
    1287                 :            : 
    1288                 :          0 : invalid:
    1289                 :          0 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
    1290         [ #  # ]:          0 :                                          spdk_strerror(-lvserrno));
    1291                 :          0 : }
    1292                 :            : 
    1293                 :            : static void
    1294                 :          2 : rpc_bdev_lvol_grow_lvstore(struct spdk_jsonrpc_request *request,
    1295                 :            :                            const struct spdk_json_val *params)
    1296                 :            : {
    1297                 :          2 :         struct rpc_bdev_lvol_grow_lvstore req = {};
    1298                 :          2 :         struct spdk_lvol_store *lvs = NULL;
    1299                 :            :         int rc;
    1300                 :            : 
    1301         [ -  + ]:          2 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_grow_lvstore_decoders,
    1302                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_grow_lvstore_decoders),
    1303                 :            :                                     &req)) {
    1304   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1305                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1306                 :            :                                                  "spdk_json_decode_object failed");
    1307                 :          0 :                 goto cleanup;
    1308                 :            :         }
    1309                 :            : 
    1310         [ #  # ]:          2 :         rc = vbdev_get_lvol_store_by_uuid_xor_name(req.uuid, req.lvs_name, &lvs);
    1311         [ -  + ]:          2 :         if (rc != 0) {
    1312         [ #  # ]:          0 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
    1313                 :          0 :                 goto cleanup;
    1314                 :            :         }
    1315   [ #  #  #  # ]:          2 :         spdk_bdev_update_bs_blockcnt(lvs->bs_dev);
    1316                 :          2 :         spdk_lvs_grow_live(lvs, rpc_bdev_lvol_grow_lvstore_cb, request);
    1317                 :            : 
    1318                 :          2 : cleanup:
    1319                 :          2 :         free_rpc_bdev_lvol_grow_lvstore(&req);
    1320                 :          2 : }
    1321                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_grow_lvstore", rpc_bdev_lvol_grow_lvstore, SPDK_RPC_RUNTIME)
    1322                 :            : 
    1323                 :            : struct rpc_bdev_lvol_shallow_copy {
    1324                 :            :         char *src_lvol_name;
    1325                 :            :         char *dst_bdev_name;
    1326                 :            : };
    1327                 :            : 
    1328                 :            : struct rpc_bdev_lvol_shallow_copy_ctx {
    1329                 :            :         struct spdk_jsonrpc_request *request;
    1330                 :            :         struct rpc_shallow_copy_status *status;
    1331                 :            : };
    1332                 :            : 
    1333                 :            : static void
    1334                 :          1 : free_rpc_bdev_lvol_shallow_copy(struct rpc_bdev_lvol_shallow_copy *req)
    1335                 :            : {
    1336   [ #  #  #  # ]:          1 :         free(req->src_lvol_name);
    1337   [ #  #  #  # ]:          1 :         free(req->dst_bdev_name);
    1338                 :          1 : }
    1339                 :            : 
    1340                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_shallow_copy_decoders[] = {
    1341                 :            :         {"src_lvol_name", offsetof(struct rpc_bdev_lvol_shallow_copy, src_lvol_name), spdk_json_decode_string},
    1342                 :            :         {"dst_bdev_name", offsetof(struct rpc_bdev_lvol_shallow_copy, dst_bdev_name), spdk_json_decode_string},
    1343                 :            : };
    1344                 :            : 
    1345                 :            : static void
    1346                 :          1 : rpc_bdev_lvol_shallow_copy_cb(void *cb_arg, int lvolerrno)
    1347                 :            : {
    1348                 :          1 :         struct rpc_bdev_lvol_shallow_copy_ctx *ctx = cb_arg;
    1349                 :            : 
    1350   [ #  #  #  #  :          1 :         ctx->status->result = lvolerrno;
             #  #  #  # ]
    1351                 :            : 
    1352                 :          1 :         free(ctx);
    1353                 :          1 : }
    1354                 :            : 
    1355                 :            : static void
    1356                 :          2 : rpc_bdev_lvol_shallow_copy_status_cb(uint64_t copied_clusters, void *cb_arg)
    1357                 :            : {
    1358                 :          2 :         struct rpc_shallow_copy_status *status = cb_arg;
    1359                 :            : 
    1360   [ #  #  #  # ]:          2 :         status->copied_clusters = copied_clusters;
    1361                 :          2 : }
    1362                 :            : 
    1363                 :            : static void
    1364                 :          1 : rpc_bdev_lvol_start_shallow_copy(struct spdk_jsonrpc_request *request,
    1365                 :            :                                  const struct spdk_json_val *params)
    1366                 :            : {
    1367                 :          1 :         struct rpc_bdev_lvol_shallow_copy req = {};
    1368                 :            :         struct rpc_bdev_lvol_shallow_copy_ctx *ctx;
    1369                 :            :         struct spdk_lvol *src_lvol;
    1370                 :            :         struct spdk_bdev *src_lvol_bdev;
    1371                 :            :         struct rpc_shallow_copy_status *status;
    1372                 :            :         struct spdk_json_write_ctx *w;
    1373                 :            :         int rc;
    1374                 :            : 
    1375   [ -  +  -  +  :          1 :         SPDK_INFOLOG(lvol_rpc, "Shallow copying lvol\n");
                   #  # ]
    1376                 :            : 
    1377         [ -  + ]:          1 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_shallow_copy_decoders,
    1378                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_shallow_copy_decoders),
    1379                 :            :                                     &req)) {
    1380   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1381                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1382                 :            :                                                  "spdk_json_decode_object failed");
    1383                 :          0 :                 goto cleanup;
    1384                 :            :         }
    1385                 :            : 
    1386                 :          1 :         src_lvol_bdev = spdk_bdev_get_by_name(req.src_lvol_name);
    1387         [ -  + ]:          1 :         if (src_lvol_bdev == NULL) {
    1388                 :          0 :                 SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.src_lvol_name);
    1389                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1390                 :          0 :                 goto cleanup;
    1391                 :            :         }
    1392                 :            : 
    1393                 :          1 :         src_lvol = vbdev_lvol_get_from_bdev(src_lvol_bdev);
    1394         [ -  + ]:          1 :         if (src_lvol == NULL) {
    1395                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
    1396                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1397                 :          0 :                 goto cleanup;
    1398                 :            :         }
    1399                 :            : 
    1400                 :          1 :         status = calloc(1, sizeof(*status));
    1401         [ -  + ]:          1 :         if (status == NULL) {
    1402                 :          0 :                 SPDK_ERRLOG("Cannot allocate status entry for shallow copy of '%s'\n", req.src_lvol_name);
    1403                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
    1404                 :          0 :                 goto cleanup;
    1405                 :            :         }
    1406                 :            : 
    1407   [ #  #  #  # ]:          1 :         status->operation_id = ++g_shallow_copy_count;
    1408   [ #  #  #  #  :          1 :         status->total_clusters = spdk_blob_get_num_allocated_clusters(src_lvol->blob);
             #  #  #  # ]
    1409                 :            : 
    1410                 :          1 :         ctx = calloc(1, sizeof(*ctx));
    1411         [ -  + ]:          1 :         if (ctx == NULL) {
    1412                 :          0 :                 SPDK_ERRLOG("Cannot allocate context for shallow copy of '%s'\n", req.src_lvol_name);
    1413                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENOMEM, spdk_strerror(ENOMEM));
    1414                 :          0 :                 free(status);
    1415                 :          0 :                 goto cleanup;
    1416                 :            :         }
    1417   [ #  #  #  # ]:          1 :         ctx->request = request;
    1418   [ #  #  #  # ]:          1 :         ctx->status = status;
    1419                 :            : 
    1420   [ -  +  #  #  :          1 :         LIST_INSERT_HEAD(&g_shallow_copy_status_list, status, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1421         [ #  # ]:          1 :         rc = vbdev_lvol_shallow_copy(src_lvol, req.dst_bdev_name,
    1422                 :          0 :                                      rpc_bdev_lvol_shallow_copy_status_cb, status,
    1423                 :          0 :                                      rpc_bdev_lvol_shallow_copy_cb, ctx);
    1424                 :            : 
    1425         [ -  + ]:          1 :         if (rc < 0) {
    1426                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
    1427         [ #  # ]:          0 :                                                  spdk_strerror(-rc));
    1428   [ #  #  #  #  :          0 :                 LIST_REMOVE(status, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1429                 :          0 :                 free(ctx);
    1430                 :          0 :                 free(status);
    1431                 :          0 :         } else {
    1432                 :          1 :                 w = spdk_jsonrpc_begin_result(request);
    1433                 :            : 
    1434                 :          1 :                 spdk_json_write_object_begin(w);
    1435   [ #  #  #  # ]:          1 :                 spdk_json_write_named_uint32(w, "operation_id", status->operation_id);
    1436                 :          1 :                 spdk_json_write_object_end(w);
    1437                 :            : 
    1438                 :          1 :                 spdk_jsonrpc_end_result(request, w);
    1439                 :            :         }
    1440                 :            : 
    1441                 :          1 : cleanup:
    1442                 :          1 :         free_rpc_bdev_lvol_shallow_copy(&req);
    1443                 :          1 : }
    1444                 :            : 
    1445                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_start_shallow_copy", rpc_bdev_lvol_start_shallow_copy,
    1446                 :            :                   SPDK_RPC_RUNTIME)
    1447                 :            : 
    1448                 :            : struct rpc_bdev_lvol_shallow_copy_status {
    1449                 :            :         char            *src_lvol_name;
    1450                 :            :         uint32_t        operation_id;
    1451                 :            : };
    1452                 :            : 
    1453                 :            : static void
    1454                 :          1 : free_rpc_bdev_lvol_shallow_copy_status(struct rpc_bdev_lvol_shallow_copy_status *req)
    1455                 :            : {
    1456   [ #  #  #  # ]:          1 :         free(req->src_lvol_name);
    1457                 :          1 : }
    1458                 :            : 
    1459                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_shallow_copy_status_decoders[] = {
    1460                 :            :         {"operation_id", offsetof(struct rpc_bdev_lvol_shallow_copy_status, operation_id), spdk_json_decode_uint32},
    1461                 :            : };
    1462                 :            : 
    1463                 :            : static void
    1464                 :          1 : rpc_bdev_lvol_check_shallow_copy(struct spdk_jsonrpc_request *request,
    1465                 :            :                                  const struct spdk_json_val *params)
    1466                 :            : {
    1467                 :          1 :         struct rpc_bdev_lvol_shallow_copy_status req = {};
    1468                 :            :         struct rpc_shallow_copy_status *status;
    1469                 :            :         struct spdk_json_write_ctx *w;
    1470                 :            :         uint64_t copied_clusters, total_clusters;
    1471                 :            :         int result;
    1472                 :            : 
    1473   [ -  +  -  +  :          1 :         SPDK_INFOLOG(lvol_rpc, "Shallow copy check\n");
                   #  # ]
    1474                 :            : 
    1475         [ -  + ]:          1 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_shallow_copy_status_decoders,
    1476                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_shallow_copy_status_decoders),
    1477                 :            :                                     &req)) {
    1478   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1479                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1480                 :            :                                                  "spdk_json_decode_object failed");
    1481                 :          0 :                 goto cleanup;
    1482                 :            :         }
    1483                 :            : 
    1484   [ +  -  #  #  :          1 :         LIST_FOREACH(status, &g_shallow_copy_status_list, link) {
             #  #  #  # ]
    1485   [ +  -  #  #  :          1 :                 if (status->operation_id == req.operation_id) {
             #  #  #  # ]
    1486                 :          1 :                         break;
    1487                 :            :                 }
    1488                 :          0 :         }
    1489                 :            : 
    1490         [ -  + ]:          1 :         if (!status) {
    1491         [ #  # ]:          0 :                 SPDK_ERRLOG("operation id '%d' does not exist\n", req.operation_id);
    1492                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1493                 :          0 :                 goto cleanup;
    1494                 :            :         }
    1495                 :            : 
    1496   [ #  #  #  # ]:          1 :         copied_clusters = status->copied_clusters;
    1497   [ #  #  #  # ]:          1 :         total_clusters = status->total_clusters;
    1498   [ #  #  #  # ]:          1 :         result = status->result;
    1499                 :            : 
    1500                 :          1 :         w = spdk_jsonrpc_begin_result(request);
    1501                 :            : 
    1502                 :          1 :         spdk_json_write_object_begin(w);
    1503                 :            : 
    1504                 :          1 :         spdk_json_write_named_uint64(w, "copied_clusters", copied_clusters);
    1505                 :          1 :         spdk_json_write_named_uint64(w, "total_clusters", total_clusters);
    1506   [ -  +  -  - ]:          1 :         if (copied_clusters < total_clusters && result == 0) {
    1507                 :          0 :                 spdk_json_write_named_string(w, "state", "in progress");
    1508   [ +  -  +  - ]:          1 :         } else if (copied_clusters == total_clusters && result == 0) {
    1509                 :          1 :                 spdk_json_write_named_string(w, "state", "complete");
    1510   [ -  +  #  #  :          1 :                 LIST_REMOVE(status, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1511                 :          1 :                 free(status);
    1512                 :          0 :         } else {
    1513                 :          0 :                 spdk_json_write_named_string(w, "state", "error");
    1514         [ #  # ]:          0 :                 spdk_json_write_named_string(w, "error", spdk_strerror(-result));
    1515   [ #  #  #  #  :          0 :                 LIST_REMOVE(status, link);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1516                 :          0 :                 free(status);
    1517                 :            :         }
    1518                 :            : 
    1519                 :          1 :         spdk_json_write_object_end(w);
    1520                 :            : 
    1521                 :          1 :         spdk_jsonrpc_end_result(request, w);
    1522                 :            : 
    1523                 :          1 : cleanup:
    1524                 :          1 :         free_rpc_bdev_lvol_shallow_copy_status(&req);
    1525                 :          1 : }
    1526                 :            : 
    1527                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_check_shallow_copy", rpc_bdev_lvol_check_shallow_copy,
    1528                 :            :                   SPDK_RPC_RUNTIME)
    1529                 :            : 
    1530                 :            : struct rpc_bdev_lvol_set_parent {
    1531                 :            :         char *lvol_name;
    1532                 :            :         char *parent_name;
    1533                 :            : };
    1534                 :            : 
    1535                 :            : static void
    1536                 :         14 : free_rpc_bdev_lvol_set_parent(struct rpc_bdev_lvol_set_parent *req)
    1537                 :            : {
    1538   [ #  #  #  # ]:         14 :         free(req->lvol_name);
    1539   [ #  #  #  # ]:         14 :         free(req->parent_name);
    1540                 :         14 : }
    1541                 :            : 
    1542                 :            : static const struct spdk_json_object_decoder rpc_bdev_lvol_set_parent_decoders[] = {
    1543                 :            :         {"lvol_name", offsetof(struct rpc_bdev_lvol_set_parent, lvol_name), spdk_json_decode_string},
    1544                 :            :         {"parent_name", offsetof(struct rpc_bdev_lvol_set_parent, parent_name), spdk_json_decode_string},
    1545                 :            : };
    1546                 :            : 
    1547                 :            : static void
    1548                 :         13 : rpc_bdev_lvol_set_parent_cb(void *cb_arg, int lvolerrno)
    1549                 :            : {
    1550                 :         13 :         struct spdk_jsonrpc_request *request = cb_arg;
    1551                 :            : 
    1552         [ +  + ]:         13 :         if (lvolerrno != 0) {
    1553                 :          7 :                 goto invalid;
    1554                 :            :         }
    1555                 :            : 
    1556                 :          6 :         spdk_jsonrpc_send_bool_response(request, true);
    1557                 :          6 :         return;
    1558                 :            : 
    1559                 :          7 : invalid:
    1560                 :          7 :         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
    1561         [ #  # ]:          0 :                                          spdk_strerror(-lvolerrno));
    1562                 :          0 : }
    1563                 :            : 
    1564                 :            : static void
    1565                 :          8 : rpc_bdev_lvol_set_parent(struct spdk_jsonrpc_request *request,
    1566                 :            :                          const struct spdk_json_val *params)
    1567                 :            : {
    1568                 :          8 :         struct rpc_bdev_lvol_set_parent req = {};
    1569                 :            :         struct spdk_lvol *lvol, *snapshot;
    1570                 :            :         struct spdk_bdev *lvol_bdev, *snapshot_bdev;
    1571                 :            : 
    1572   [ -  +  -  +  :          8 :         SPDK_INFOLOG(lvol_rpc, "Set parent of lvol\n");
                   #  # ]
    1573                 :            : 
    1574         [ -  + ]:          8 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_set_parent_decoders,
    1575                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_set_parent_decoders),
    1576                 :            :                                     &req)) {
    1577   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1578                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1579                 :            :                                                  "spdk_json_decode_object failed");
    1580                 :          0 :                 goto cleanup;
    1581                 :            :         }
    1582                 :            : 
    1583                 :          8 :         lvol_bdev = spdk_bdev_get_by_name(req.lvol_name);
    1584         [ -  + ]:          8 :         if (lvol_bdev == NULL) {
    1585                 :          0 :                 SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.lvol_name);
    1586                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1587                 :          0 :                 goto cleanup;
    1588                 :            :         }
    1589                 :            : 
    1590                 :          8 :         lvol = vbdev_lvol_get_from_bdev(lvol_bdev);
    1591         [ -  + ]:          8 :         if (lvol == NULL) {
    1592                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
    1593                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1594                 :          0 :                 goto cleanup;
    1595                 :            :         }
    1596                 :            : 
    1597         [ #  # ]:          8 :         snapshot_bdev = spdk_bdev_get_by_name(req.parent_name);
    1598         [ -  + ]:          8 :         if (snapshot_bdev == NULL) {
    1599         [ #  # ]:          0 :                 SPDK_ERRLOG("snapshot bdev '%s' does not exist\n", req.parent_name);
    1600                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1601                 :          0 :                 goto cleanup;
    1602                 :            :         }
    1603                 :            : 
    1604                 :          8 :         snapshot = vbdev_lvol_get_from_bdev(snapshot_bdev);
    1605         [ +  + ]:          8 :         if (snapshot == NULL) {
    1606                 :          1 :                 SPDK_ERRLOG("snapshot does not exist\n");
    1607                 :          1 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1608                 :          1 :                 goto cleanup;
    1609                 :            :         }
    1610                 :            : 
    1611                 :          7 :         spdk_lvol_set_parent(lvol, snapshot, rpc_bdev_lvol_set_parent_cb, request);
    1612                 :            : 
    1613                 :          8 : cleanup:
    1614                 :          8 :         free_rpc_bdev_lvol_set_parent(&req);
    1615                 :          8 : }
    1616                 :            : 
    1617                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_set_parent", rpc_bdev_lvol_set_parent, SPDK_RPC_RUNTIME)
    1618                 :            : 
    1619                 :            : static void
    1620                 :          6 : rpc_bdev_lvol_set_parent_bdev(struct spdk_jsonrpc_request *request,
    1621                 :            :                               const struct spdk_json_val *params)
    1622                 :            : {
    1623                 :          6 :         struct rpc_bdev_lvol_set_parent req = {};
    1624                 :            :         struct spdk_lvol *lvol;
    1625                 :            :         struct spdk_bdev *lvol_bdev;
    1626                 :            : 
    1627   [ -  +  -  +  :          6 :         SPDK_INFOLOG(lvol_rpc, "Set external parent of lvol\n");
                   #  # ]
    1628                 :            : 
    1629         [ -  + ]:          6 :         if (spdk_json_decode_object(params, rpc_bdev_lvol_set_parent_decoders,
    1630                 :            :                                     SPDK_COUNTOF(rpc_bdev_lvol_set_parent_decoders),
    1631                 :            :                                     &req)) {
    1632   [ #  #  #  #  :          0 :                 SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
                   #  # ]
    1633                 :          0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
    1634                 :            :                                                  "spdk_json_decode_object failed");
    1635                 :          0 :                 goto cleanup;
    1636                 :            :         }
    1637                 :            : 
    1638                 :          6 :         lvol_bdev = spdk_bdev_get_by_name(req.lvol_name);
    1639         [ -  + ]:          6 :         if (lvol_bdev == NULL) {
    1640                 :          0 :                 SPDK_ERRLOG("lvol bdev '%s' does not exist\n", req.lvol_name);
    1641                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1642                 :          0 :                 goto cleanup;
    1643                 :            :         }
    1644                 :            : 
    1645                 :          6 :         lvol = vbdev_lvol_get_from_bdev(lvol_bdev);
    1646         [ -  + ]:          6 :         if (lvol == NULL) {
    1647                 :          0 :                 SPDK_ERRLOG("lvol does not exist\n");
    1648                 :          0 :                 spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
    1649                 :          0 :                 goto cleanup;
    1650                 :            :         }
    1651                 :            : 
    1652         [ #  # ]:          6 :         vbdev_lvol_set_external_parent(lvol, req.parent_name, rpc_bdev_lvol_set_parent_cb, request);
    1653                 :            : 
    1654                 :          6 : cleanup:
    1655                 :          6 :         free_rpc_bdev_lvol_set_parent(&req);
    1656                 :          6 : }
    1657                 :            : 
    1658                 :       2215 : SPDK_RPC_REGISTER("bdev_lvol_set_parent_bdev", rpc_bdev_lvol_set_parent_bdev,
    1659                 :            :                   SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.15