LCOV - code coverage report
Current view: top level - spdk/lib/nvme - nvme_ns_cmd.c (source / functions) Hit Total Coverage
Test: Combined Lines: 614 739 83.1 %
Date: 2024-11-20 16:06:25 Functions: 46 46 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 304 1414 21.5 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2015 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  *   Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
       5                 :            :  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       6                 :            :  *   Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "nvme_internal.h"
      10                 :            : 
      11                 :            : static inline struct nvme_request *_nvme_ns_cmd_rw(struct spdk_nvme_ns *ns,
      12                 :            :                 struct spdk_nvme_qpair *qpair,
      13                 :            :                 const struct nvme_payload *payload, uint32_t payload_offset, uint32_t md_offset,
      14                 :            :                 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn,
      15                 :            :                 void *cb_arg, uint32_t opc, uint32_t io_flags,
      16                 :            :                 uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13, bool check_sgl,
      17                 :            :                 void *accel_sequence, int *rc);
      18                 :            : 
      19                 :            : static bool
      20                 :     168788 : nvme_ns_check_request_length(uint32_t lba_count, uint32_t sectors_per_max_io,
      21                 :            :                              uint32_t sectors_per_stripe, uint32_t qdepth)
      22                 :            : {
      23                 :     168788 :         uint32_t child_per_io = UINT32_MAX;
      24                 :            : 
      25                 :            :         /* After a namespace is destroyed(e.g. hotplug), all the fields associated with the
      26                 :            :          * namespace will be cleared to zero, the function will return TRUE for this case,
      27                 :            :          * and -EINVAL will be returned to caller.
      28                 :            :          */
      29         [ -  + ]:     168788 :         if (sectors_per_stripe > 0) {
      30         [ #  # ]:          0 :                 child_per_io = (lba_count + sectors_per_stripe - 1) / sectors_per_stripe;
      31         [ +  + ]:     168788 :         } else if (sectors_per_max_io > 0) {
      32         [ -  + ]:     110975 :                 child_per_io = (lba_count + sectors_per_max_io - 1) / sectors_per_max_io;
      33                 :          1 :         }
      34                 :            : 
      35   [ +  +  -  +  :     168788 :         SPDK_DEBUGLOG(nvme, "checking maximum i/o length %d\n", child_per_io);
                   #  # ]
      36                 :            : 
      37                 :     168788 :         return child_per_io >= qdepth;
      38                 :            : }
      39                 :            : 
      40                 :            : static inline int
      41                 :     168796 : nvme_ns_map_failure_rc(uint32_t lba_count, uint32_t sectors_per_max_io,
      42                 :            :                        uint32_t sectors_per_stripe, uint32_t qdepth, int rc)
      43                 :            : {
      44   [ +  +  #  # ]:     168796 :         assert(rc);
      45   [ +  +  +  + ]:     337583 :         if (rc == -ENOMEM &&
      46                 :     168788 :             nvme_ns_check_request_length(lba_count, sectors_per_max_io, sectors_per_stripe, qdepth)) {
      47                 :      57817 :                 return -EINVAL;
      48                 :            :         }
      49                 :     110979 :         return rc;
      50                 :          3 : }
      51                 :            : 
      52                 :            : static inline bool
      53                 :  141890877 : _nvme_md_excluded_from_xfer(struct spdk_nvme_ns *ns, uint32_t io_flags)
      54                 :            : {
      55   [ +  +  -  + ]:  141891017 :         return (io_flags & SPDK_NVME_IO_FLAGS_PRACT) &&
      56   [ +  +  #  #  :        140 :                (ns->flags & SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED) &&
                   #  # ]
      57   [ +  +  +  -  :  139370256 :                (ns->flags & SPDK_NVME_NS_DPS_PI_SUPPORTED) &&
                   #  # ]
      58   [ +  -  #  # ]:         24 :                (ns->md_size == 8);
      59                 :            : }
      60                 :            : 
      61                 :            : static inline uint32_t
      62                 :   71448635 : _nvme_get_host_buffer_sector_size(struct spdk_nvme_ns *ns, uint32_t io_flags)
      63                 :            : {
      64         [ +  + ]:   71535240 :         return _nvme_md_excluded_from_xfer(ns, io_flags) ?
      65   [ +  +  #  #  :   71448635 :                ns->sector_size : ns->extended_lba_size;
             +  -  +  - ]
      66                 :            : }
      67                 :            : 
      68                 :            : static inline uint32_t
      69                 :   70442718 : _nvme_get_sectors_per_max_io(struct spdk_nvme_ns *ns, uint32_t io_flags)
      70                 :            : {
      71         [ +  + ]:   70529323 :         return _nvme_md_excluded_from_xfer(ns, io_flags) ?
      72   [ +  +  #  #  :   70442718 :                ns->sectors_per_max_io_no_md : ns->sectors_per_max_io;
             +  -  +  - ]
      73                 :            : }
      74                 :            : 
      75                 :            : static struct nvme_request *
      76                 :   31523504 : _nvme_add_child_request(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
      77                 :            :                         const struct nvme_payload *payload,
      78                 :            :                         uint32_t payload_offset, uint32_t md_offset,
      79                 :            :                         uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
      80                 :            :                         uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13,
      81                 :            :                         struct nvme_request *parent, bool check_sgl, int *rc)
      82                 :            : {
      83                 :            :         struct nvme_request     *child;
      84                 :            : 
      85                 :   31523577 :         child = _nvme_ns_cmd_rw(ns, qpair, payload, payload_offset, md_offset, lba, lba_count, cb_fn,
      86         [ #  # ]:         73 :                                 cb_arg, opc, io_flags, apptag_mask, apptag, cdw13, check_sgl, NULL, rc);
      87         [ +  + ]:   31523504 :         if (child == NULL) {
      88                 :      57988 :                 nvme_request_free_children(parent);
      89                 :      57988 :                 nvme_free_request(parent);
      90                 :      57988 :                 return NULL;
      91                 :            :         }
      92                 :            : 
      93                 :   31465516 :         nvme_request_add_child(parent, child);
      94                 :   31465516 :         return child;
      95                 :         73 : }
      96                 :            : 
      97                 :            : static struct nvme_request *
      98                 :     789476 : _nvme_ns_cmd_split_request(struct spdk_nvme_ns *ns,
      99                 :            :                            struct spdk_nvme_qpair *qpair,
     100                 :            :                            const struct nvme_payload *payload,
     101                 :            :                            uint32_t payload_offset, uint32_t md_offset,
     102                 :            :                            uint64_t lba, uint32_t lba_count,
     103                 :            :                            spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
     104                 :            :                            uint32_t io_flags, struct nvme_request *req,
     105                 :            :                            uint32_t sectors_per_max_io, uint32_t sector_mask,
     106                 :            :                            uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13,
     107                 :            :                            void *accel_sequence, int *rc)
     108                 :            : {
     109                 :     789476 :         uint32_t                sector_size = _nvme_get_host_buffer_sector_size(ns, io_flags);
     110                 :     789476 :         uint32_t                remaining_lba_count = lba_count;
     111                 :            :         struct nvme_request     *child;
     112                 :            : 
     113         [ -  + ]:     789476 :         if (spdk_unlikely(accel_sequence != NULL)) {
     114                 :          0 :                 SPDK_ERRLOG("Splitting requests with accel sequence is unsupported\n");
     115         [ #  # ]:          0 :                 *rc = -EINVAL;
     116                 :          0 :                 return NULL;
     117                 :            :         }
     118                 :            : 
     119         [ +  + ]:   32254208 :         while (remaining_lba_count > 0) {
     120                 :   31522720 :                 lba_count = sectors_per_max_io - (lba & sector_mask);
     121         [ +  + ]:   31522720 :                 lba_count = spdk_min(remaining_lba_count, lba_count);
     122                 :            : 
     123                 :   31522791 :                 child = _nvme_add_child_request(ns, qpair, payload, payload_offset, md_offset,
     124                 :         71 :                                                 lba, lba_count, cb_fn, cb_arg, opc,
     125                 :         71 :                                                 io_flags, apptag_mask, apptag, cdw13, req, true, rc);
     126         [ +  + ]:   31522720 :                 if (child == NULL) {
     127                 :      57988 :                         return NULL;
     128                 :            :                 }
     129                 :            : 
     130                 :   31464732 :                 remaining_lba_count -= lba_count;
     131                 :   31464732 :                 lba += lba_count;
     132                 :   31464732 :                 payload_offset += lba_count * sector_size;
     133   [ #  #  #  # ]:   31464732 :                 md_offset += lba_count * ns->md_size;
     134                 :            :         }
     135                 :            : 
     136                 :     731488 :         return req;
     137                 :         17 : }
     138                 :            : 
     139                 :            : static inline bool
     140                 :  109187799 : _is_io_flags_valid(uint32_t io_flags)
     141                 :            : {
     142         [ +  + ]:  109187799 :         if (spdk_unlikely(io_flags & ~SPDK_NVME_IO_FLAGS_VALID_MASK)) {
     143                 :            :                 /* Invalid io_flags */
     144                 :         12 :                 SPDK_ERRLOG("Invalid io_flags 0x%x\n", io_flags);
     145                 :         12 :                 return false;
     146                 :            :         }
     147                 :            : 
     148                 :  109187787 :         return true;
     149                 :    2611706 : }
     150                 :            : 
     151                 :            : static inline bool
     152                 :     488959 : _is_accel_sequence_valid(struct spdk_nvme_qpair *qpair, void *seq)
     153                 :            : {
     154                 :            :         /* An accel sequence can only be executed if the controller supports accel and a qpair is
     155                 :            :          * part of a of a poll group */
     156   [ +  +  +  -  :     488959 :         if (spdk_likely(seq == NULL || ((qpair->ctrlr->flags & SPDK_NVME_CTRLR_ACCEL_SEQUENCE_SUPPORTED) &&
          +  -  +  -  #  
          #  #  #  #  #  
             #  #  #  # ]
     157                 :            :                                         qpair->poll_group != NULL))) {
     158                 :     488959 :                 return true;
     159                 :            :         }
     160                 :            : 
     161                 :          0 :         return false;
     162                 :          2 : }
     163                 :            : 
     164                 :            : static void
     165                 :   69483778 : _nvme_ns_cmd_setup_request(struct spdk_nvme_ns *ns, struct nvme_request *req,
     166                 :            :                            uint32_t opc, uint64_t lba, uint32_t lba_count,
     167                 :            :                            uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag,
     168                 :            :                            uint32_t cdw13)
     169                 :            : {
     170                 :            :         struct spdk_nvme_cmd    *cmd;
     171                 :            : 
     172   [ +  +  #  # ]:   69483778 :         assert(_is_io_flags_valid(io_flags));
     173                 :            : 
     174         [ +  - ]:   69483778 :         cmd = &req->cmd;
     175         [ +  - ]:   69483778 :         cmd->opc = opc;
     176   [ +  -  +  -  :   69483778 :         cmd->nsid = ns->id;
             +  -  +  - ]
     177                 :            : 
     178   [ +  -  +  -  :   69483778 :         *(uint64_t *)&cmd->cdw10 = lba;
                   +  - ]
     179                 :            : 
     180   [ +  +  +  -  :   69483778 :         if (ns->flags & SPDK_NVME_NS_DPS_PI_SUPPORTED) {
                   +  - ]
     181   [ +  +  #  #  :         52 :                 switch (ns->pi_type) {
                   #  # ]
     182                 :          3 :                 case SPDK_NVME_FMT_NVM_PROTECTION_TYPE1:
     183                 :            :                 case SPDK_NVME_FMT_NVM_PROTECTION_TYPE2:
     184   [ #  #  #  # ]:          4 :                         cmd->cdw14 = (uint32_t)lba;
     185                 :          4 :                         break;
     186                 :            :                 }
     187                 :         13 :         }
     188                 :            : 
     189   [ -  +  +  -  :   69483778 :         cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
                   +  - ]
     190                 :            : 
     191   [ +  -  +  -  :   69483778 :         cmd->cdw12 = lba_count - 1;
                   +  - ]
     192   [ +  -  +  -  :   69483778 :         cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
                   +  - ]
     193                 :            : 
     194   [ +  -  +  -  :   69483778 :         cmd->cdw13 = cdw13;
                   +  - ]
     195                 :            : 
     196   [ +  -  +  - ]:   69483778 :         cmd->cdw15 = apptag_mask;
     197   [ +  -  +  -  :   69483778 :         cmd->cdw15 = (cmd->cdw15 << 16 | apptag);
          +  -  +  -  +  
                      - ]
     198                 :   69483778 : }
     199                 :            : 
     200                 :            : static struct nvme_request *
     201                 :    1854299 : _nvme_ns_cmd_split_request_prp(struct spdk_nvme_ns *ns,
     202                 :            :                                struct spdk_nvme_qpair *qpair,
     203                 :            :                                const struct nvme_payload *payload,
     204                 :            :                                uint32_t payload_offset, uint32_t md_offset,
     205                 :            :                                uint64_t lba, uint32_t lba_count,
     206                 :            :                                spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
     207                 :            :                                uint32_t io_flags, struct nvme_request *req,
     208                 :            :                                uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13,
     209                 :            :                                void *accel_sequence, int *rc)
     210                 :            : {
     211   [ #  #  #  #  :    1854299 :         spdk_nvme_req_reset_sgl_cb reset_sgl_fn = req->payload.reset_sgl_fn;
                   #  # ]
     212   [ #  #  #  #  :    1854299 :         spdk_nvme_req_next_sge_cb next_sge_fn = req->payload.next_sge_fn;
                   #  # ]
     213   [ #  #  #  #  :    1854299 :         void *sgl_cb_arg = req->payload.contig_or_cb_arg;
                   #  # ]
     214                 :            :         bool start_valid, end_valid, last_sge, child_equals_parent;
     215                 :    1854299 :         uint64_t child_lba = lba;
     216                 :    1854299 :         uint32_t req_current_length = 0;
     217                 :    1854299 :         uint32_t child_length = 0;
     218                 :    1357565 :         uint32_t sge_length;
     219   [ #  #  #  #  :    1854299 :         uint32_t page_size = qpair->ctrlr->page_size;
             #  #  #  # ]
     220                 :    1357565 :         uintptr_t address;
     221                 :            : 
     222   [ #  #  #  # ]:    1854299 :         reset_sgl_fn(sgl_cb_arg, payload_offset);
     223   [ #  #  #  # ]:    1854299 :         next_sge_fn(sgl_cb_arg, (void **)&address, &sge_length);
     224   [ +  +  #  #  :    4324657 :         while (req_current_length < req->payload_size) {
                   #  # ]
     225                 :            : 
     226         [ -  + ]:    2470362 :                 if (sge_length == 0) {
     227                 :          0 :                         continue;
     228   [ +  +  #  #  :    2470362 :                 } else if (req_current_length + sge_length > req->payload_size) {
                   #  # ]
     229   [ #  #  #  # ]:     170533 :                         sge_length = req->payload_size - req_current_length;
     230                 :          5 :                 }
     231                 :            : 
     232                 :            :                 /*
     233                 :            :                  * The start of the SGE is invalid if the start address is not page aligned,
     234                 :            :                  *  unless it is the first SGE in the child request.
     235                 :            :                  */
     236   [ +  +  +  - ]:    2470362 :                 start_valid = child_length == 0 || _is_page_aligned(address, page_size);
     237                 :            : 
     238                 :            :                 /* Boolean for whether this is the last SGE in the parent request. */
     239   [ #  #  #  # ]:    2470362 :                 last_sge = (req_current_length + sge_length == req->payload_size);
     240                 :            : 
     241                 :            :                 /*
     242                 :            :                  * The end of the SGE is invalid if the end address is not page aligned,
     243                 :            :                  *  unless it is the last SGE in the parent request.
     244                 :            :                  */
     245   [ +  +  +  + ]:    2470362 :                 end_valid = last_sge || _is_page_aligned(address + sge_length, page_size);
     246                 :            : 
     247                 :            :                 /*
     248                 :            :                  * This child request equals the parent request, meaning that no splitting
     249                 :            :                  *  was required for the parent request (the one passed into this function).
     250                 :            :                  *  In this case, we do not create a child request at all - we just send
     251                 :            :                  *  the original request as a single request at the end of this function.
     252                 :            :                  */
     253   [ #  #  #  # ]:    2470362 :                 child_equals_parent = (child_length + sge_length == req->payload_size);
     254                 :            : 
     255   [ +  +  #  # ]:    2470362 :                 if (start_valid) {
     256                 :            :                         /*
     257                 :            :                          * The start of the SGE is valid, so advance the length parameters,
     258                 :            :                          *  to include this SGE with previous SGEs for this child request
     259                 :            :                          *  (if any).  If it is not valid, we do not advance the length
     260                 :            :                          *  parameters nor get the next SGE, because we must send what has
     261                 :            :                          *  been collected before this SGE as a child request.
     262                 :            :                          */
     263                 :    2470362 :                         child_length += sge_length;
     264                 :    2470362 :                         req_current_length += sge_length;
     265   [ +  +  #  #  :    2470362 :                         if (req_current_length < req->payload_size) {
                   #  # ]
     266   [ #  #  #  # ]:     616067 :                                 next_sge_fn(sgl_cb_arg, (void **)&address, &sge_length);
     267                 :            :                                 /*
     268                 :            :                                  * If the next SGE is not page aligned, we will need to create a
     269                 :            :                                  *  child request for what we have so far, and then start a new
     270                 :            :                                  *  child request for the next SGE.
     271                 :            :                                  */
     272                 :     616067 :                                 start_valid = _is_page_aligned(address, page_size);
     273                 :          2 :                         }
     274                 :         19 :                 }
     275                 :            : 
     276   [ +  +  +  +  :    2470362 :                 if (start_valid && end_valid && !last_sge) {
          +  +  #  #  #  
                #  #  # ]
     277                 :     615598 :                         continue;
     278                 :            :                 }
     279                 :            : 
     280                 :            :                 /*
     281                 :            :                  * We need to create a split here.  Send what we have accumulated so far as a child
     282                 :            :                  *  request.  Checking if child_equals_parent allows us to *not* create a child request
     283                 :            :                  *  when no splitting is required - in that case we will fall-through and just create
     284                 :            :                  *  a single request with no children for the entire I/O.
     285                 :            :                  */
     286   [ +  +  #  # ]:    1854764 :                 if (!child_equals_parent) {
     287                 :            :                         struct nvme_request *child;
     288                 :            :                         uint32_t child_lba_count;
     289                 :            : 
     290   [ +  +  +  +  :        780 :                         if ((child_length % ns->extended_lba_size) != 0) {
             #  #  #  # ]
     291   [ #  #  #  # ]:          4 :                                 SPDK_ERRLOG("child_length %u not even multiple of lba_size %u\n",
     292                 :            :                                             child_length, ns->extended_lba_size);
     293         [ #  # ]:          4 :                                 *rc = -EINVAL;
     294                 :          4 :                                 return NULL;
     295                 :            :                         }
     296         [ -  + ]:        776 :                         if (spdk_unlikely(accel_sequence != NULL)) {
     297                 :          0 :                                 SPDK_ERRLOG("Splitting requests with accel sequence is unsupported\n");
     298         [ #  # ]:          0 :                                 *rc = -EINVAL;
     299                 :          0 :                                 return NULL;
     300                 :            :                         }
     301                 :            : 
     302   [ -  +  #  #  :        776 :                         child_lba_count = child_length / ns->extended_lba_size;
                   #  # ]
     303                 :            :                         /*
     304                 :            :                          * Note the last parameter is set to "false" - this tells the recursive
     305                 :            :                          *  call to _nvme_ns_cmd_rw() to not bother with checking for SGL splitting
     306                 :            :                          *  since we have already verified it here.
     307                 :            :                          */
     308                 :        776 :                         child = _nvme_add_child_request(ns, qpair, payload, payload_offset, md_offset,
     309                 :          0 :                                                         child_lba, child_lba_count,
     310                 :          0 :                                                         cb_fn, cb_arg, opc, io_flags,
     311                 :          0 :                                                         apptag_mask, apptag, cdw13, req, false, rc);
     312         [ -  + ]:        776 :                         if (child == NULL) {
     313                 :          0 :                                 return NULL;
     314                 :            :                         }
     315                 :        776 :                         payload_offset += child_length;
     316   [ #  #  #  # ]:        776 :                         md_offset += child_lba_count * ns->md_size;
     317                 :        776 :                         child_lba += child_lba_count;
     318                 :        776 :                         child_length = 0;
     319                 :          0 :                 }
     320                 :            :         }
     321                 :            : 
     322   [ +  +  #  #  :    1854295 :         if (child_length == req->payload_size) {
                   #  # ]
     323                 :            :                 /* No splitting was required, so setup the whole payload as one request. */
     324                 :    1853984 :                 _nvme_ns_cmd_setup_request(ns, req, opc, lba, lba_count, io_flags, apptag_mask, apptag, cdw13);
     325                 :         17 :         }
     326                 :            : 
     327                 :    1854295 :         return req;
     328                 :         18 : }
     329                 :            : 
     330                 :            : static struct nvme_request *
     331                 :     403001 : _nvme_ns_cmd_split_request_sgl(struct spdk_nvme_ns *ns,
     332                 :            :                                struct spdk_nvme_qpair *qpair,
     333                 :            :                                const struct nvme_payload *payload,
     334                 :            :                                uint32_t payload_offset, uint32_t md_offset,
     335                 :            :                                uint64_t lba, uint32_t lba_count,
     336                 :            :                                spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
     337                 :            :                                uint32_t io_flags, struct nvme_request *req,
     338                 :            :                                uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13,
     339                 :            :                                void *accel_sequence, int *rc)
     340                 :            : {
     341   [ #  #  #  #  :     403001 :         spdk_nvme_req_reset_sgl_cb reset_sgl_fn = req->payload.reset_sgl_fn;
                   #  # ]
     342   [ #  #  #  #  :     403001 :         spdk_nvme_req_next_sge_cb next_sge_fn = req->payload.next_sge_fn;
                   #  # ]
     343   [ #  #  #  #  :     403001 :         void *sgl_cb_arg = req->payload.contig_or_cb_arg;
                   #  # ]
     344                 :     403001 :         uint64_t child_lba = lba;
     345                 :     403001 :         uint32_t req_current_length = 0;
     346                 :     403001 :         uint32_t accumulated_length = 0;
     347                 :     180700 :         uint32_t sge_length;
     348                 :            :         uint16_t max_sges, num_sges;
     349                 :     180700 :         uintptr_t address;
     350                 :            : 
     351   [ #  #  #  #  :     403001 :         max_sges = ns->ctrlr->max_sges;
             #  #  #  # ]
     352                 :            : 
     353   [ #  #  #  # ]:     403001 :         reset_sgl_fn(sgl_cb_arg, payload_offset);
     354                 :     403001 :         num_sges = 0;
     355                 :            : 
     356   [ +  +  #  #  :    2314638 :         while (req_current_length < req->payload_size) {
                   #  # ]
     357   [ #  #  #  # ]:    1911641 :                 next_sge_fn(sgl_cb_arg, (void **)&address, &sge_length);
     358                 :            : 
     359   [ +  +  #  #  :    1911641 :                 if (req_current_length + sge_length > req->payload_size) {
                   #  # ]
     360   [ #  #  #  # ]:        470 :                         sge_length = req->payload_size - req_current_length;
     361                 :          0 :                 }
     362                 :            : 
     363                 :    1911641 :                 accumulated_length += sge_length;
     364                 :    1911641 :                 req_current_length += sge_length;
     365                 :    1911641 :                 num_sges++;
     366                 :            : 
     367   [ +  +  +  +  :    1911641 :                 if (num_sges < max_sges && req_current_length < req->payload_size) {
             #  #  #  # ]
     368                 :    1508636 :                         continue;
     369                 :            :                 }
     370                 :            : 
     371                 :            :                 /*
     372                 :            :                  * We need to create a split here.  Send what we have accumulated so far as a child
     373                 :            :                  *  request.  Checking if the child equals the full payload allows us to *not*
     374                 :            :                  *  create a child request when no splitting is required - in that case we will
     375                 :            :                  *  fall-through and just create a single request with no children for the entire I/O.
     376                 :            :                  */
     377   [ +  +  #  #  :     403005 :                 if (accumulated_length != req->payload_size) {
                   #  # ]
     378                 :            :                         struct nvme_request *child;
     379                 :            :                         uint32_t child_lba_count;
     380                 :            :                         uint32_t child_length;
     381                 :            :                         uint32_t extra_length;
     382                 :            : 
     383                 :         12 :                         child_length = accumulated_length;
     384                 :            :                         /* Child length may not be a multiple of the block size! */
     385   [ -  +  #  #  :         12 :                         child_lba_count = child_length / ns->extended_lba_size;
                   #  # ]
     386   [ #  #  #  # ]:         12 :                         extra_length = child_length - (child_lba_count * ns->extended_lba_size);
     387         [ +  + ]:         12 :                         if (extra_length != 0) {
     388                 :            :                                 /* The last SGE does not end on a block boundary. We need to cut it off. */
     389         [ +  + ]:          8 :                                 if (extra_length >= child_length) {
     390                 :          4 :                                         SPDK_ERRLOG("Unable to send I/O. Would require more than the supported number of "
     391                 :            :                                                     "SGL Elements.");
     392         [ #  # ]:          4 :                                         *rc = -EINVAL;
     393                 :          4 :                                         return NULL;
     394                 :            :                                 }
     395                 :          4 :                                 child_length -= extra_length;
     396                 :          1 :                         }
     397                 :            : 
     398         [ +  + ]:          8 :                         if (spdk_unlikely(accel_sequence != NULL)) {
     399                 :          0 :                                 SPDK_ERRLOG("Splitting requests with accel sequence is unsupported\n");
     400         [ #  # ]:          0 :                                 *rc = -EINVAL;
     401                 :          0 :                                 return NULL;
     402                 :            :                         }
     403                 :            : 
     404                 :            :                         /*
     405                 :            :                          * Note the last parameter is set to "false" - this tells the recursive
     406                 :            :                          *  call to _nvme_ns_cmd_rw() to not bother with checking for SGL splitting
     407                 :            :                          *  since we have already verified it here.
     408                 :            :                          */
     409                 :         10 :                         child = _nvme_add_child_request(ns, qpair, payload, payload_offset, md_offset,
     410                 :          2 :                                                         child_lba, child_lba_count,
     411                 :          2 :                                                         cb_fn, cb_arg, opc, io_flags,
     412                 :          2 :                                                         apptag_mask, apptag, cdw13, req, false, rc);
     413         [ +  + ]:          8 :                         if (child == NULL) {
     414                 :          0 :                                 return NULL;
     415                 :            :                         }
     416                 :          8 :                         payload_offset += child_length;
     417   [ #  #  #  # ]:          8 :                         md_offset += child_lba_count * ns->md_size;
     418                 :          8 :                         child_lba += child_lba_count;
     419                 :          8 :                         accumulated_length -= child_length;
     420                 :          8 :                         num_sges = accumulated_length > 0;
     421                 :          2 :                 }
     422                 :            :         }
     423                 :            : 
     424   [ +  +  #  #  :     402997 :         if (accumulated_length == req->payload_size) {
                   #  # ]
     425                 :            :                 /* No splitting was required, so setup the whole payload as one request. */
     426                 :     402993 :                 _nvme_ns_cmd_setup_request(ns, req, opc, lba, lba_count, io_flags, apptag_mask, apptag, cdw13);
     427                 :         34 :         }
     428                 :            : 
     429                 :     402997 :         return req;
     430                 :         36 : }
     431                 :            : 
     432                 :            : static inline struct nvme_request *
     433                 :   70442389 : _nvme_ns_cmd_rw(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     434                 :            :                 const struct nvme_payload *payload, uint32_t payload_offset, uint32_t md_offset,
     435                 :            :                 uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
     436                 :            :                 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag, uint32_t cdw13, bool check_sgl,
     437                 :            :                 void *accel_sequence, int *rc)
     438                 :            : {
     439                 :            :         struct nvme_request     *req;
     440                 :   70442389 :         uint32_t                sector_size = _nvme_get_host_buffer_sector_size(ns, io_flags);
     441                 :   70442389 :         uint32_t                sectors_per_max_io = _nvme_get_sectors_per_max_io(ns, io_flags);
     442   [ +  -  +  - ]:   70442389 :         uint32_t                sectors_per_stripe = ns->sectors_per_stripe;
     443                 :            : 
     444   [ +  +  #  # ]:   70442389 :         assert(rc != NULL);
     445   [ +  +  +  -  :   70442389 :         assert(*rc == 0);
                   #  # ]
     446                 :            : 
     447   [ +  -  +  - ]:   71615982 :         req = nvme_allocate_request(qpair, payload, lba_count * sector_size, lba_count * ns->md_size,
     448                 :    1260198 :                                     cb_fn, cb_arg);
     449         [ +  + ]:   70442389 :         if (req == NULL) {
     450         [ #  # ]:     168788 :                 *rc = -ENOMEM;
     451                 :     168788 :                 return NULL;
     452                 :            :         }
     453                 :            : 
     454   [ +  -  +  - ]:   70273601 :         req->payload_offset = payload_offset;
     455   [ +  -  +  - ]:   70273601 :         req->md_offset = md_offset;
     456   [ +  -  +  - ]:   70273601 :         req->accel_sequence = accel_sequence;
     457                 :            : 
     458                 :            :         /* Zone append commands cannot be split. */
     459         [ +  + ]:   70273601 :         if (opc == SPDK_NVME_OPC_ZONE_APPEND) {
     460   [ -  +  #  #  :     216280 :                 assert(ns->csi == SPDK_NVME_CSI_ZNS);
             #  #  #  # ]
     461                 :            :                 /*
     462                 :            :                  * As long as we disable driver-assisted striping for Zone append commands,
     463                 :            :                  * _nvme_ns_cmd_rw() should never cause a proper request to be split.
     464                 :            :                  * If a request is split, after all, error handling is done in caller functions.
     465                 :            :                  */
     466                 :     216280 :                 sectors_per_stripe = 0;
     467                 :          3 :         }
     468                 :            : 
     469                 :            :         /*
     470                 :            :          * Intel DC P3*00 NVMe controllers benefit from driver-assisted striping.
     471                 :            :          * If this controller defines a stripe boundary and this I/O spans a stripe
     472                 :            :          *  boundary, split the request into multiple requests and submit each
     473                 :            :          *  separately to hardware.
     474                 :            :          */
     475   [ +  +  +  + ]:   70273601 :         if (sectors_per_stripe > 0 &&
     476         [ +  + ]:   13478865 :             (((lba & (sectors_per_stripe - 1)) + lba_count) > sectors_per_stripe)) {
     477                 :     665946 :                 return _nvme_ns_cmd_split_request(ns, qpair, payload, payload_offset, md_offset, lba, lba_count,
     478                 :          1 :                                                   cb_fn,
     479                 :          1 :                                                   cb_arg, opc,
     480                 :          1 :                                                   io_flags, req, sectors_per_stripe, sectors_per_stripe - 1,
     481                 :          1 :                                                   apptag_mask, apptag, cdw13,  accel_sequence, rc);
     482         [ +  + ]:   69607656 :         } else if (lba_count > sectors_per_max_io) {
     483                 :     123547 :                 return _nvme_ns_cmd_split_request(ns, qpair, payload, payload_offset, md_offset, lba, lba_count,
     484                 :         16 :                                                   cb_fn,
     485                 :         16 :                                                   cb_arg, opc,
     486                 :         16 :                                                   io_flags, req, sectors_per_max_io, 0, apptag_mask,
     487                 :         16 :                                                   apptag, cdw13, accel_sequence, rc);
     488   [ +  +  +  +  :   69484125 :         } else if (nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_SGL && check_sgl) {
             #  #  #  # ]
     489   [ +  +  #  #  :    2257300 :                 if (ns->ctrlr->flags & SPDK_NVME_CTRLR_SGL_SUPPORTED) {
          #  #  #  #  #  
                      # ]
     490                 :     403037 :                         return _nvme_ns_cmd_split_request_sgl(ns, qpair, payload, payload_offset, md_offset,
     491                 :         36 :                                                               lba, lba_count, cb_fn, cb_arg, opc, io_flags,
     492                 :         36 :                                                               req, apptag_mask, apptag, cdw13,
     493                 :         36 :                                                               accel_sequence, rc);
     494                 :            :                 } else {
     495                 :    1854317 :                         return _nvme_ns_cmd_split_request_prp(ns, qpair, payload, payload_offset, md_offset,
     496                 :         18 :                                                               lba, lba_count, cb_fn, cb_arg, opc, io_flags,
     497                 :         18 :                                                               req, apptag_mask, apptag, cdw13,
     498                 :         18 :                                                               accel_sequence, rc);
     499                 :            :                 }
     500                 :            :         }
     501                 :            : 
     502                 :   67226825 :         _nvme_ns_cmd_setup_request(ns, req, opc, lba, lba_count, io_flags, apptag_mask, apptag, cdw13);
     503                 :   67226825 :         return req;
     504                 :    1260198 : }
     505                 :            : 
     506                 :            : int
     507                 :       2052 : spdk_nvme_ns_cmd_compare(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, void *buffer,
     508                 :            :                          uint64_t lba,
     509                 :            :                          uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     510                 :            :                          uint32_t io_flags)
     511                 :            : {
     512                 :            :         struct nvme_request *req;
     513                 :          3 :         struct nvme_payload payload;
     514                 :       2052 :         int rc = 0;
     515                 :            : 
     516         [ -  + ]:       2052 :         if (!_is_io_flags_valid(io_flags)) {
     517                 :          0 :                 return -EINVAL;
     518                 :            :         }
     519                 :            : 
     520                 :       2052 :         payload = NVME_PAYLOAD_CONTIG(buffer, NULL);
     521                 :            : 
     522                 :       2053 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg,
     523                 :            :                               SPDK_NVME_OPC_COMPARE,
     524                 :          1 :                               io_flags, 0,
     525                 :            :                               0, 0, false, NULL, &rc);
     526         [ +  + ]:       2052 :         if (req != NULL) {
     527                 :       2052 :                 return nvme_qpair_submit_request(qpair, req);
     528                 :            :         } else {
     529                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     530   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     531   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     532   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     533                 :          0 :                                               rc);
     534                 :            :         }
     535                 :          1 : }
     536                 :            : 
     537                 :            : int
     538                 :         24 : spdk_nvme_ns_cmd_compare_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     539                 :            :                                  void *buffer,
     540                 :            :                                  void *metadata,
     541                 :            :                                  uint64_t lba,
     542                 :            :                                  uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     543                 :            :                                  uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag)
     544                 :            : {
     545                 :            :         struct nvme_request *req;
     546                 :         18 :         struct nvme_payload payload;
     547                 :         24 :         int rc = 0;
     548                 :            : 
     549         [ -  + ]:         24 :         if (!_is_io_flags_valid(io_flags)) {
     550                 :          0 :                 return -EINVAL;
     551                 :            :         }
     552                 :            : 
     553                 :         24 :         payload = NVME_PAYLOAD_CONTIG(buffer, metadata);
     554                 :            : 
     555                 :         30 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg,
     556                 :            :                               SPDK_NVME_OPC_COMPARE,
     557                 :          6 :                               io_flags,
     558                 :          6 :                               apptag_mask, apptag, 0, false, NULL, &rc);
     559         [ +  + ]:         24 :         if (req != NULL) {
     560                 :         24 :                 return nvme_qpair_submit_request(qpair, req);
     561                 :            :         } else {
     562                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     563   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     564   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     565   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     566                 :          0 :                                               rc);
     567                 :            :         }
     568                 :          6 : }
     569                 :            : 
     570                 :            : int
     571                 :          8 : spdk_nvme_ns_cmd_comparev(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     572                 :            :                           uint64_t lba, uint32_t lba_count,
     573                 :            :                           spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
     574                 :            :                           spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     575                 :            :                           spdk_nvme_req_next_sge_cb next_sge_fn)
     576                 :            : {
     577                 :            :         struct nvme_request *req;
     578                 :          6 :         struct nvme_payload payload;
     579                 :          8 :         int rc = 0;
     580                 :            : 
     581         [ -  + ]:          8 :         if (!_is_io_flags_valid(io_flags)) {
     582                 :          0 :                 return -EINVAL;
     583                 :            :         }
     584                 :            : 
     585   [ +  -  +  + ]:          8 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     586                 :          4 :                 return -EINVAL;
     587                 :            :         }
     588                 :            : 
     589                 :          4 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, NULL);
     590                 :            : 
     591                 :          5 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg,
     592                 :            :                               SPDK_NVME_OPC_COMPARE,
     593                 :          1 :                               io_flags, 0, 0, 0, true, NULL, &rc);
     594         [ +  + ]:          4 :         if (req != NULL) {
     595                 :          4 :                 return nvme_qpair_submit_request(qpair, req);
     596                 :            :         } else {
     597                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     598   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     599   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     600   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     601                 :          0 :                                               rc);
     602                 :            :         }
     603                 :          2 : }
     604                 :            : 
     605                 :            : int
     606                 :        106 : spdk_nvme_ns_cmd_comparev_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     607                 :            :                                   uint64_t lba, uint32_t lba_count,
     608                 :            :                                   spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
     609                 :            :                                   spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     610                 :            :                                   spdk_nvme_req_next_sge_cb next_sge_fn, void *metadata,
     611                 :            :                                   uint16_t apptag_mask, uint16_t apptag)
     612                 :            : {
     613                 :            :         struct nvme_request *req;
     614                 :         52 :         struct nvme_payload payload;
     615                 :        106 :         int rc = 0;
     616                 :            : 
     617         [ -  + ]:        106 :         if (!_is_io_flags_valid(io_flags)) {
     618                 :          0 :                 return -EINVAL;
     619                 :            :         }
     620                 :            : 
     621   [ +  -  -  + ]:        106 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     622                 :          0 :                 return -EINVAL;
     623                 :            :         }
     624                 :            : 
     625                 :        106 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, metadata);
     626                 :            : 
     627                 :        114 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg,
     628                 :          8 :                               SPDK_NVME_OPC_COMPARE, io_flags, apptag_mask, apptag, 0, true,
     629                 :            :                               NULL, &rc);
     630         [ +  + ]:        106 :         if (req != NULL) {
     631                 :        106 :                 return nvme_qpair_submit_request(qpair, req);
     632                 :            :         } else {
     633                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     634   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     635   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     636   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     637                 :          0 :                                               rc);
     638                 :            :         }
     639                 :          8 : }
     640                 :            : 
     641                 :            : int
     642                 :    1388019 : spdk_nvme_ns_cmd_read(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, void *buffer,
     643                 :            :                       uint64_t lba,
     644                 :            :                       uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     645                 :            :                       uint32_t io_flags)
     646                 :            : {
     647                 :            :         struct nvme_request *req;
     648                 :     253351 :         struct nvme_payload payload;
     649                 :    1388019 :         int rc = 0;
     650                 :            : 
     651         [ -  + ]:    1388019 :         if (!_is_io_flags_valid(io_flags)) {
     652                 :          0 :                 return -EINVAL;
     653                 :            :         }
     654                 :            : 
     655                 :    1388019 :         payload = NVME_PAYLOAD_CONTIG(buffer, NULL);
     656                 :            : 
     657                 :    1482739 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ,
     658                 :      94720 :                               io_flags, 0,
     659                 :            :                               0, 0, false, NULL, &rc);
     660         [ +  + ]:    1388019 :         if (req != NULL) {
     661                 :    1388015 :                 return nvme_qpair_submit_request(qpair, req);
     662                 :            :         } else {
     663                 :          5 :                 return nvme_ns_map_failure_rc(lba_count,
     664   [ #  #  #  # ]:          1 :                                               ns->sectors_per_max_io,
     665   [ #  #  #  # ]:          1 :                                               ns->sectors_per_stripe,
     666   [ #  #  #  #  :          4 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     667                 :          1 :                                               rc);
     668                 :            :         }
     669                 :      94720 : }
     670                 :            : 
     671                 :            : int
     672                 :   19578230 : spdk_nvme_ns_cmd_read_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, void *buffer,
     673                 :            :                               void *metadata,
     674                 :            :                               uint64_t lba,
     675                 :            :                               uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     676                 :            :                               uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag)
     677                 :            : {
     678                 :            :         struct nvme_request *req;
     679                 :    5988130 :         struct nvme_payload payload;
     680                 :   19578230 :         int rc = 0;
     681                 :            : 
     682         [ -  + ]:   19578230 :         if (!_is_io_flags_valid(io_flags)) {
     683                 :          0 :                 return -EINVAL;
     684                 :            :         }
     685                 :            : 
     686                 :   19578230 :         payload = NVME_PAYLOAD_CONTIG(buffer, metadata);
     687                 :            : 
     688                 :   20135569 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ,
     689                 :     557339 :                               io_flags,
     690                 :     557339 :                               apptag_mask, apptag, 0, false, NULL, &rc);
     691         [ +  + ]:   19578230 :         if (req != NULL) {
     692                 :   19464949 :                 return nvme_qpair_submit_request(qpair, req);
     693                 :            :         } else {
     694                 :     113281 :                 return nvme_ns_map_failure_rc(lba_count,
     695   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     696   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     697   [ #  #  #  #  :     113281 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     698                 :          0 :                                               rc);
     699                 :            :         }
     700                 :     557339 : }
     701                 :            : 
     702                 :            : static int
     703                 :     488950 : nvme_ns_cmd_rw_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, void *buffer,
     704                 :            :                    uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     705                 :            :                    struct spdk_nvme_ns_cmd_ext_io_opts *opts, enum spdk_nvme_nvm_opcode opc)
     706                 :            : {
     707                 :            :         struct nvme_request *req;
     708                 :          0 :         struct nvme_payload payload;
     709                 :            :         void *seq;
     710                 :     488950 :         int rc = 0;
     711                 :            : 
     712   [ +  +  -  +  :     488950 :         assert(opc == SPDK_NVME_OPC_READ || opc == SPDK_NVME_OPC_WRITE);
                   #  # ]
     713   [ -  +  #  # ]:     488950 :         assert(opts);
     714                 :            : 
     715   [ #  #  #  # ]:     488950 :         payload = NVME_PAYLOAD_CONTIG(buffer, opts->metadata);
     716                 :            : 
     717   [ -  +  #  #  :     488950 :         if (spdk_unlikely(!_is_io_flags_valid(opts->io_flags))) {
                   #  # ]
     718                 :          0 :                 return -EINVAL;
     719                 :            :         }
     720                 :            : 
     721   [ +  -  +  -  :     488950 :         seq = nvme_ns_cmd_get_ext_io_opt(opts, accel_sequence, NULL);
          #  #  #  #  #  
                #  #  # ]
     722         [ -  + ]:     488950 :         if (spdk_unlikely(!_is_accel_sequence_valid(qpair, seq))) {
     723                 :          0 :                 return -EINVAL;
     724                 :            :         }
     725                 :            : 
     726         [ #  # ]:     488950 :         payload.opts = opts;
     727                 :            : 
     728   [ #  #  #  # ]:     488950 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, opc, opts->io_flags,
     729   [ #  #  #  #  :     488950 :                               opts->apptag_mask, opts->apptag, 0, false, seq, &rc);
             #  #  #  # ]
     730         [ -  + ]:     488950 :         if (spdk_unlikely(req == NULL)) {
     731                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     732   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     733   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     734   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     735                 :          0 :                                               rc);
     736                 :            :         }
     737                 :            : 
     738                 :     488950 :         return nvme_qpair_submit_request(qpair, req);
     739                 :          0 : }
     740                 :            : 
     741                 :            : int
     742                 :     310716 : spdk_nvme_ns_cmd_read_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, void *buffer,
     743                 :            :                           uint64_t lba,
     744                 :            :                           uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     745                 :            :                           struct spdk_nvme_ns_cmd_ext_io_opts *opts)
     746                 :            : {
     747                 :     310716 :         return nvme_ns_cmd_rw_ext(ns, qpair, buffer, lba, lba_count, cb_fn, cb_arg, opts,
     748                 :            :                                   SPDK_NVME_OPC_READ);
     749                 :            : }
     750                 :            : 
     751                 :            : int
     752                 :         84 : spdk_nvme_ns_cmd_readv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     753                 :            :                        uint64_t lba, uint32_t lba_count,
     754                 :            :                        spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
     755                 :            :                        spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     756                 :            :                        spdk_nvme_req_next_sge_cb next_sge_fn)
     757                 :            : {
     758                 :            :         struct nvme_request *req;
     759                 :         42 :         struct nvme_payload payload;
     760                 :         84 :         int rc = 0;
     761                 :            : 
     762         [ -  + ]:         84 :         if (!_is_io_flags_valid(io_flags)) {
     763                 :          0 :                 return -EINVAL;
     764                 :            :         }
     765                 :            : 
     766   [ +  -  +  + ]:         84 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     767                 :          8 :                 return -EINVAL;
     768                 :            :         }
     769                 :            : 
     770                 :         76 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, NULL);
     771                 :            : 
     772                 :         86 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ,
     773                 :         10 :                               io_flags, 0, 0, 0, true, NULL, &rc);
     774         [ +  + ]:         76 :         if (req != NULL) {
     775                 :         72 :                 return nvme_qpair_submit_request(qpair, req);
     776                 :            :         } else {
     777                 :          5 :                 return nvme_ns_map_failure_rc(lba_count,
     778   [ #  #  #  # ]:          1 :                                               ns->sectors_per_max_io,
     779   [ #  #  #  # ]:          1 :                                               ns->sectors_per_stripe,
     780   [ #  #  #  #  :          4 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     781                 :          1 :                                               rc);
     782                 :            :         }
     783                 :         12 : }
     784                 :            : 
     785                 :            : int
     786                 :     314064 : spdk_nvme_ns_cmd_readv_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     787                 :            :                                uint64_t lba, uint32_t lba_count,
     788                 :            :                                spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
     789                 :            :                                spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     790                 :            :                                spdk_nvme_req_next_sge_cb next_sge_fn, void *metadata,
     791                 :            :                                uint16_t apptag_mask, uint16_t apptag)
     792                 :            : {
     793                 :            :         struct nvme_request *req;
     794                 :     158992 :         struct nvme_payload payload;
     795                 :     314064 :         int rc = 0;
     796                 :            : 
     797         [ -  + ]:     314064 :         if (!_is_io_flags_valid(io_flags)) {
     798                 :          0 :                 return -EINVAL;
     799                 :            :         }
     800                 :            : 
     801   [ +  -  +  + ]:     314064 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     802                 :          4 :                 return -EINVAL;
     803                 :            :         }
     804                 :            : 
     805                 :     314060 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, metadata);
     806                 :            : 
     807                 :     314066 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ,
     808                 :          6 :                               io_flags, apptag_mask, apptag, 0, true, NULL, &rc);
     809         [ +  + ]:     314060 :         if (req != NULL) {
     810                 :     313917 :                 return nvme_qpair_submit_request(qpair, req);
     811                 :            :         } else {
     812                 :        143 :                 return nvme_ns_map_failure_rc(lba_count,
     813   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     814   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     815   [ #  #  #  #  :        143 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     816                 :          0 :                                               rc);
     817                 :            :         }
     818                 :          7 : }
     819                 :            : 
     820                 :            : static int
     821                 :         33 : nvme_ns_cmd_rwv_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t lba,
     822                 :            :                     uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     823                 :            :                     spdk_nvme_req_next_sge_cb next_sge_fn, struct spdk_nvme_ns_cmd_ext_io_opts *opts,
     824                 :            :                     enum spdk_nvme_nvm_opcode opc)
     825                 :            : {
     826                 :            :         struct nvme_request *req;
     827                 :         25 :         struct nvme_payload payload;
     828                 :            :         void *seq;
     829                 :         33 :         int rc = 0;
     830                 :            : 
     831   [ +  +  +  +  :         33 :         assert(opc == SPDK_NVME_OPC_READ || opc == SPDK_NVME_OPC_WRITE);
                   #  # ]
     832                 :            : 
     833   [ +  +  +  + ]:         33 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     834                 :         16 :                 return -EINVAL;
     835                 :            :         }
     836                 :            : 
     837                 :         17 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, NULL);
     838                 :            : 
     839         [ +  - ]:         17 :         if (opts) {
     840   [ +  +  #  #  :         17 :                 if (spdk_unlikely(!_is_io_flags_valid(opts->io_flags))) {
                   #  # ]
     841                 :          8 :                         return -EINVAL;
     842                 :            :                 }
     843                 :            : 
     844   [ +  -  +  +  :          9 :                 seq = nvme_ns_cmd_get_ext_io_opt(opts, accel_sequence, NULL);
          #  #  #  #  #  
                #  #  # ]
     845         [ -  + ]:          9 :                 if (spdk_unlikely(!_is_accel_sequence_valid(qpair, seq))) {
     846                 :          0 :                         return -EINVAL;
     847                 :            :                 }
     848                 :            : 
     849         [ #  # ]:          9 :                 payload.opts = opts;
     850   [ #  #  #  #  :          9 :                 payload.md = opts->metadata;
                   #  # ]
     851   [ #  #  #  # ]:         16 :                 req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, opc, opts->io_flags,
     852   [ #  #  #  #  :          9 :                                       opts->apptag_mask, opts->apptag, opts->cdw13, true, seq, &rc);
          #  #  #  #  #  
                #  #  # ]
     853                 :            : 
     854                 :          2 :         } else {
     855                 :          0 :                 req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, opc, 0, 0, 0, 0,
     856                 :            :                                       true, NULL, &rc);
     857                 :            :         }
     858                 :            : 
     859         [ +  + ]:          9 :         if (req == NULL) {
     860                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     861   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     862   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     863   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     864                 :          0 :                                               rc);
     865                 :            :         }
     866                 :            : 
     867                 :          9 :         return nvme_qpair_submit_request(qpair, req);
     868                 :          8 : }
     869                 :            : 
     870                 :            : int
     871                 :         16 : spdk_nvme_ns_cmd_readv_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     872                 :            :                            uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn,
     873                 :            :                            void *cb_arg, spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     874                 :            :                            spdk_nvme_req_next_sge_cb next_sge_fn,
     875                 :            :                            struct spdk_nvme_ns_cmd_ext_io_opts *opts)
     876                 :            : {
     877                 :         20 :         return nvme_ns_cmd_rwv_ext(ns, qpair, lba, lba_count, cb_fn, cb_arg, reset_sgl_fn, next_sge_fn,
     878                 :          4 :                                    opts, SPDK_NVME_OPC_READ);
     879                 :            : }
     880                 :            : 
     881                 :            : int
     882                 :    2748604 : spdk_nvme_ns_cmd_write(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     883                 :            :                        void *buffer, uint64_t lba,
     884                 :            :                        uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     885                 :            :                        uint32_t io_flags)
     886                 :            : {
     887                 :            :         struct nvme_request *req;
     888                 :      15261 :         struct nvme_payload payload;
     889                 :    2748604 :         int rc = 0;
     890                 :            : 
     891         [ +  + ]:    2748604 :         if (!_is_io_flags_valid(io_flags)) {
     892                 :          4 :                 return -EINVAL;
     893                 :            :         }
     894                 :            : 
     895                 :    2748600 :         payload = NVME_PAYLOAD_CONTIG(buffer, NULL);
     896                 :            : 
     897                 :    2833761 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE,
     898                 :      85161 :                               io_flags, 0, 0, 0, false, NULL, &rc);
     899         [ +  + ]:    2748600 :         if (req != NULL) {
     900                 :    2748600 :                 return nvme_qpair_submit_request(qpair, req);
     901                 :            :         } else {
     902                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     903   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     904   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     905   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     906                 :          0 :                                               rc);
     907                 :            :         }
     908                 :      85162 : }
     909                 :            : 
     910                 :            : static int
     911                 :     216292 : nvme_ns_cmd_check_zone_append(struct spdk_nvme_ns *ns, uint32_t lba_count, uint32_t io_flags)
     912                 :            : {
     913                 :            :         uint32_t sector_size;
     914                 :            : 
     915                 :            :         /* Not all NVMe Zoned Namespaces support the zone append command. */
     916   [ -  +  #  #  :     216292 :         if (!(ns->ctrlr->flags & SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED)) {
          #  #  #  #  #  
                      # ]
     917                 :          0 :                 return -EINVAL;
     918                 :            :         }
     919                 :            : 
     920                 :     216292 :         sector_size =  _nvme_get_host_buffer_sector_size(ns, io_flags);
     921                 :            : 
     922                 :            :         /* Fail a too large zone append command early. */
     923   [ +  +  #  #  :     216292 :         if (lba_count * sector_size > ns->ctrlr->max_zone_append_size) {
          #  #  #  #  #  
                      # ]
     924                 :         12 :                 return -EINVAL;
     925                 :            :         }
     926                 :            : 
     927                 :     216280 :         return 0;
     928                 :          6 : }
     929                 :            : 
     930                 :            : int
     931                 :     216284 : nvme_ns_cmd_zone_append_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     932                 :            :                                 void *buffer, void *metadata, uint64_t zslba,
     933                 :            :                                 uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     934                 :            :                                 uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag)
     935                 :            : {
     936                 :            :         struct nvme_request *req;
     937                 :         12 :         struct nvme_payload payload;
     938                 :     216284 :         int rc = 0;
     939                 :            : 
     940         [ -  + ]:     216284 :         if (!_is_io_flags_valid(io_flags)) {
     941                 :          0 :                 return -EINVAL;
     942                 :            :         }
     943                 :            : 
     944                 :     216284 :         rc = nvme_ns_cmd_check_zone_append(ns, lba_count, io_flags);
     945         [ +  + ]:     216284 :         if (rc) {
     946                 :          8 :                 return rc;
     947                 :            :         }
     948                 :            : 
     949                 :     216276 :         payload = NVME_PAYLOAD_CONTIG(buffer, metadata);
     950                 :            : 
     951                 :     216278 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, zslba, lba_count, cb_fn, cb_arg,
     952                 :            :                               SPDK_NVME_OPC_ZONE_APPEND,
     953                 :          2 :                               io_flags, apptag_mask, apptag, 0, false, NULL, &rc);
     954         [ +  - ]:     216276 :         if (req != NULL) {
     955                 :            :                 /*
     956                 :            :                  * Zone append commands cannot be split (num_children has to be 0).
     957                 :            :                  * For NVME_PAYLOAD_TYPE_CONTIG, _nvme_ns_cmd_rw() should never cause a split
     958                 :            :                  * to happen, since a too large request would have already been failed by
     959                 :            :                  * nvme_ns_cmd_check_zone_append(), since zasl <= mdts.
     960                 :            :                  */
     961   [ -  +  #  #  :     216276 :                 assert(req->num_children == 0);
             #  #  #  # ]
     962   [ -  +  #  #  :     216276 :                 if (req->num_children) {
                   #  # ]
     963                 :          0 :                         nvme_request_free_children(req);
     964                 :          0 :                         nvme_free_request(req);
     965                 :          0 :                         return -EINVAL;
     966                 :            :                 }
     967                 :     216276 :                 return nvme_qpair_submit_request(qpair, req);
     968                 :            :         } else {
     969                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
     970   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
     971   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
     972   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
     973                 :          0 :                                               rc);
     974                 :            :         }
     975                 :          4 : }
     976                 :            : 
     977                 :            : int
     978                 :          8 : nvme_ns_cmd_zone_appendv_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
     979                 :            :                                  uint64_t zslba, uint32_t lba_count,
     980                 :            :                                  spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
     981                 :            :                                  spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
     982                 :            :                                  spdk_nvme_req_next_sge_cb next_sge_fn, void *metadata,
     983                 :            :                                  uint16_t apptag_mask, uint16_t apptag)
     984                 :            : {
     985                 :            :         struct nvme_request *req;
     986                 :          6 :         struct nvme_payload payload;
     987                 :          8 :         int rc = 0;
     988                 :            : 
     989         [ -  + ]:          8 :         if (!_is_io_flags_valid(io_flags)) {
     990                 :          0 :                 return -EINVAL;
     991                 :            :         }
     992                 :            : 
     993   [ +  -  -  + ]:          8 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     994                 :          0 :                 return -EINVAL;
     995                 :            :         }
     996                 :            : 
     997                 :          8 :         rc = nvme_ns_cmd_check_zone_append(ns, lba_count, io_flags);
     998         [ +  + ]:          8 :         if (rc) {
     999                 :          4 :                 return rc;
    1000                 :            :         }
    1001                 :            : 
    1002                 :          4 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, metadata);
    1003                 :            : 
    1004                 :          5 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, zslba, lba_count, cb_fn, cb_arg,
    1005                 :            :                               SPDK_NVME_OPC_ZONE_APPEND,
    1006                 :          1 :                               io_flags, apptag_mask, apptag, 0, true, NULL, &rc);
    1007         [ +  - ]:          4 :         if (req != NULL) {
    1008                 :            :                 /*
    1009                 :            :                  * Zone append commands cannot be split (num_children has to be 0).
    1010                 :            :                  * For NVME_PAYLOAD_TYPE_SGL, _nvme_ns_cmd_rw() can cause a split.
    1011                 :            :                  * However, _nvme_ns_cmd_split_request_sgl() and _nvme_ns_cmd_split_request_prp()
    1012                 :            :                  * do not always cause a request to be split. These functions verify payload size,
    1013                 :            :                  * verify num sge < max_sge, and verify SGE alignment rules (in case of PRPs).
    1014                 :            :                  * If any of the verifications fail, they will split the request.
    1015                 :            :                  * In our case, a split is very unlikely, since we already verified the size using
    1016                 :            :                  * nvme_ns_cmd_check_zone_append(), however, we still need to call these functions
    1017                 :            :                  * in order to perform the verification part. If they do cause a split, we return
    1018                 :            :                  * an error here. For proper requests, these functions will never cause a split.
    1019                 :            :                  */
    1020   [ +  +  #  #  :          4 :                 if (req->num_children) {
                   #  # ]
    1021                 :          0 :                         nvme_request_free_children(req);
    1022                 :          0 :                         nvme_free_request(req);
    1023                 :          0 :                         return -EINVAL;
    1024                 :            :                 }
    1025                 :          4 :                 return nvme_qpair_submit_request(qpair, req);
    1026                 :            :         } else {
    1027                 :          0 :                 return nvme_ns_map_failure_rc(lba_count,
    1028   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
    1029   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
    1030   [ #  #  #  #  :          0 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
    1031                 :          0 :                                               rc);
    1032                 :            :         }
    1033                 :          2 : }
    1034                 :            : 
    1035                 :            : int
    1036                 :   13674185 : spdk_nvme_ns_cmd_write_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1037                 :            :                                void *buffer, void *metadata, uint64_t lba,
    1038                 :            :                                uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
    1039                 :            :                                uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag)
    1040                 :            : {
    1041                 :            :         struct nvme_request *req;
    1042                 :    2798763 :         struct nvme_payload payload;
    1043                 :   13674185 :         int rc = 0;
    1044                 :            : 
    1045         [ -  + ]:   13674185 :         if (!_is_io_flags_valid(io_flags)) {
    1046                 :          0 :                 return -EINVAL;
    1047                 :            :         }
    1048                 :            : 
    1049                 :   13674185 :         payload = NVME_PAYLOAD_CONTIG(buffer, metadata);
    1050                 :            : 
    1051                 :   14197352 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE,
    1052                 :     523167 :                               io_flags, apptag_mask, apptag, 0, false, NULL, &rc);
    1053         [ +  + ]:   13674185 :         if (req != NULL) {
    1054                 :   13618881 :                 return nvme_qpair_submit_request(qpair, req);
    1055                 :            :         } else {
    1056                 :      55304 :                 return nvme_ns_map_failure_rc(lba_count,
    1057   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
    1058   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
    1059   [ #  #  #  #  :      55304 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
    1060                 :          0 :                                               rc);
    1061                 :            :         }
    1062                 :     523167 : }
    1063                 :            : 
    1064                 :            : int
    1065                 :     178234 : spdk_nvme_ns_cmd_write_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1066                 :            :                            void *buffer, uint64_t lba,
    1067                 :            :                            uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
    1068                 :            :                            struct spdk_nvme_ns_cmd_ext_io_opts *opts)
    1069                 :            : {
    1070                 :     178234 :         return nvme_ns_cmd_rw_ext(ns, qpair, buffer, lba, lba_count, cb_fn, cb_arg, opts,
    1071                 :            :                                   SPDK_NVME_OPC_WRITE);
    1072                 :            : }
    1073                 :            : 
    1074                 :            : int
    1075                 :         76 : spdk_nvme_ns_cmd_writev(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1076                 :            :                         uint64_t lba, uint32_t lba_count,
    1077                 :            :                         spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
    1078                 :            :                         spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
    1079                 :            :                         spdk_nvme_req_next_sge_cb next_sge_fn)
    1080                 :            : {
    1081                 :            :         struct nvme_request *req;
    1082                 :         36 :         struct nvme_payload payload;
    1083                 :         76 :         int rc = 0;
    1084                 :            : 
    1085         [ -  + ]:         76 :         if (!_is_io_flags_valid(io_flags)) {
    1086                 :          0 :                 return -EINVAL;
    1087                 :            :         }
    1088                 :            : 
    1089   [ +  +  -  + ]:         76 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
    1090                 :          4 :                 return -EINVAL;
    1091                 :            :         }
    1092                 :            : 
    1093                 :         72 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, NULL);
    1094                 :            : 
    1095                 :         81 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE,
    1096                 :          9 :                               io_flags, 0, 0, 0, true, NULL, &rc);
    1097         [ +  + ]:         72 :         if (req != NULL) {
    1098                 :         68 :                 return nvme_qpair_submit_request(qpair, req);
    1099                 :            :         } else {
    1100                 :          5 :                 return nvme_ns_map_failure_rc(lba_count,
    1101   [ #  #  #  # ]:          1 :                                               ns->sectors_per_max_io,
    1102   [ #  #  #  # ]:          1 :                                               ns->sectors_per_stripe,
    1103   [ #  #  #  #  :          4 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
    1104                 :          1 :                                               rc);
    1105                 :            :         }
    1106                 :         10 : }
    1107                 :            : 
    1108                 :            : int
    1109                 :     508528 : spdk_nvme_ns_cmd_writev_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1110                 :            :                                 uint64_t lba, uint32_t lba_count,
    1111                 :            :                                 spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
    1112                 :            :                                 spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
    1113                 :            :                                 spdk_nvme_req_next_sge_cb next_sge_fn, void *metadata,
    1114                 :            :                                 uint16_t apptag_mask, uint16_t apptag)
    1115                 :            : {
    1116                 :            :         struct nvme_request *req;
    1117                 :     329459 :         struct nvme_payload payload;
    1118                 :     508528 :         int rc = 0;
    1119                 :            : 
    1120         [ -  + ]:     508528 :         if (!_is_io_flags_valid(io_flags)) {
    1121                 :          0 :                 return -EINVAL;
    1122                 :            :         }
    1123                 :            : 
    1124   [ +  -  -  + ]:     508528 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
    1125                 :          0 :                 return -EINVAL;
    1126                 :            :         }
    1127                 :            : 
    1128                 :     508528 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, metadata);
    1129                 :            : 
    1130                 :     508530 :         req = _nvme_ns_cmd_rw(ns, qpair, &payload, 0, 0, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE,
    1131                 :          2 :                               io_flags, apptag_mask, apptag, 0, true, NULL, &rc);
    1132         [ +  + ]:     508528 :         if (req != NULL) {
    1133                 :     508472 :                 return nvme_qpair_submit_request(qpair, req);
    1134                 :            :         } else {
    1135                 :         56 :                 return nvme_ns_map_failure_rc(lba_count,
    1136   [ #  #  #  # ]:          0 :                                               ns->sectors_per_max_io,
    1137   [ #  #  #  # ]:          0 :                                               ns->sectors_per_stripe,
    1138   [ #  #  #  #  :         56 :                                               qpair->ctrlr->opts.io_queue_requests,
          #  #  #  #  #  
                      # ]
    1139                 :          0 :                                               rc);
    1140                 :            :         }
    1141                 :          2 : }
    1142                 :            : 
    1143                 :            : int
    1144                 :         17 : spdk_nvme_ns_cmd_writev_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t lba,
    1145                 :            :                             uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
    1146                 :            :                             spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
    1147                 :            :                             spdk_nvme_req_next_sge_cb next_sge_fn,
    1148                 :            :                             struct spdk_nvme_ns_cmd_ext_io_opts *opts)
    1149                 :            : {
    1150                 :         21 :         return nvme_ns_cmd_rwv_ext(ns, qpair, lba, lba_count, cb_fn, cb_arg, reset_sgl_fn, next_sge_fn,
    1151                 :          4 :                                    opts, SPDK_NVME_OPC_WRITE);
    1152                 :            : }
    1153                 :            : 
    1154                 :            : int
    1155                 :     785913 : spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1156                 :            :                               uint64_t lba, uint32_t lba_count,
    1157                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg,
    1158                 :            :                               uint32_t io_flags)
    1159                 :            : {
    1160                 :            :         struct nvme_request     *req;
    1161                 :            :         struct spdk_nvme_cmd    *cmd;
    1162                 :            :         uint64_t                *tmp_lba;
    1163                 :            : 
    1164         [ -  + ]:     785913 :         if (!_is_io_flags_valid(io_flags)) {
    1165                 :          0 :                 return -EINVAL;
    1166                 :            :         }
    1167                 :            : 
    1168   [ +  -  -  + ]:     785913 :         if (lba_count == 0 || lba_count > UINT16_MAX + 1) {
    1169                 :          0 :                 return -EINVAL;
    1170                 :            :         }
    1171                 :            : 
    1172                 :     785913 :         req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
    1173         [ +  + ]:     785913 :         if (req == NULL) {
    1174                 :          0 :                 return -ENOMEM;
    1175                 :            :         }
    1176                 :            : 
    1177         [ #  # ]:     785913 :         cmd = &req->cmd;
    1178         [ #  # ]:     785913 :         cmd->opc = SPDK_NVME_OPC_WRITE_ZEROES;
    1179   [ #  #  #  #  :     785913 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1180                 :            : 
    1181   [ #  #  #  # ]:     785913 :         tmp_lba = (uint64_t *)&cmd->cdw10;
    1182         [ #  # ]:     785913 :         *tmp_lba = lba;
    1183   [ #  #  #  #  :     785913 :         cmd->cdw12 = lba_count - 1;
                   #  # ]
    1184   [ #  #  #  #  :     785913 :         cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
                   #  # ]
    1185   [ #  #  #  #  :     785913 :         cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
                   #  # ]
    1186                 :            : 
    1187                 :     785913 :         return nvme_qpair_submit_request(qpair, req);
    1188                 :      92244 : }
    1189                 :            : 
    1190                 :            : int
    1191                 :          4 : spdk_nvme_ns_cmd_verify(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1192                 :            :                         uint64_t lba, uint32_t lba_count,
    1193                 :            :                         spdk_nvme_cmd_cb cb_fn, void *cb_arg,
    1194                 :            :                         uint32_t io_flags)
    1195                 :            : {
    1196                 :            :         struct nvme_request     *req;
    1197                 :            :         struct spdk_nvme_cmd    *cmd;
    1198                 :            : 
    1199         [ -  + ]:          4 :         if (!_is_io_flags_valid(io_flags)) {
    1200                 :          0 :                 return -EINVAL;
    1201                 :            :         }
    1202                 :            : 
    1203   [ +  -  -  + ]:          4 :         if (lba_count == 0 || lba_count > UINT16_MAX + 1) {
    1204                 :          0 :                 return -EINVAL;
    1205                 :            :         }
    1206                 :            : 
    1207                 :          4 :         req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
    1208         [ +  + ]:          4 :         if (req == NULL) {
    1209                 :          0 :                 return -ENOMEM;
    1210                 :            :         }
    1211                 :            : 
    1212         [ #  # ]:          4 :         cmd = &req->cmd;
    1213         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_VERIFY;
    1214   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1215                 :            : 
    1216   [ #  #  #  #  :          4 :         *(uint64_t *)&cmd->cdw10 = lba;
                   #  # ]
    1217   [ #  #  #  #  :          4 :         cmd->cdw12 = lba_count - 1;
                   #  # ]
    1218   [ #  #  #  #  :          4 :         cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
                   #  # ]
    1219   [ #  #  #  #  :          4 :         cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
                   #  # ]
    1220                 :            : 
    1221                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1222                 :          1 : }
    1223                 :            : 
    1224                 :            : int
    1225                 :          4 : spdk_nvme_ns_cmd_write_uncorrectable(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1226                 :            :                                      uint64_t lba, uint32_t lba_count,
    1227                 :            :                                      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1228                 :            : {
    1229                 :            :         struct nvme_request     *req;
    1230                 :            :         struct spdk_nvme_cmd    *cmd;
    1231                 :            :         uint64_t                *tmp_lba;
    1232                 :            : 
    1233   [ +  -  -  + ]:          4 :         if (lba_count == 0 || lba_count > UINT16_MAX + 1) {
    1234                 :          0 :                 return -EINVAL;
    1235                 :            :         }
    1236                 :            : 
    1237                 :          4 :         req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
    1238         [ -  + ]:          4 :         if (req == NULL) {
    1239                 :          0 :                 return -ENOMEM;
    1240                 :            :         }
    1241                 :            : 
    1242         [ #  # ]:          4 :         cmd = &req->cmd;
    1243         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_WRITE_UNCORRECTABLE;
    1244   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1245                 :            : 
    1246   [ #  #  #  # ]:          4 :         tmp_lba = (uint64_t *)&cmd->cdw10;
    1247         [ #  # ]:          4 :         *tmp_lba = lba;
    1248   [ #  #  #  #  :          4 :         cmd->cdw12 = lba_count - 1;
                   #  # ]
    1249                 :            : 
    1250                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1251                 :          1 : }
    1252                 :            : 
    1253                 :            : int
    1254                 :      49062 : spdk_nvme_ns_cmd_dataset_management(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1255                 :            :                                     uint32_t type,
    1256                 :            :                                     const struct spdk_nvme_dsm_range *ranges, uint16_t num_ranges,
    1257                 :            :                                     spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1258                 :            : {
    1259                 :            :         struct nvme_request     *req;
    1260                 :            :         struct spdk_nvme_cmd    *cmd;
    1261                 :            : 
    1262   [ +  +  -  + ]:      49062 :         if (num_ranges == 0 || num_ranges > SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES) {
    1263                 :          4 :                 return -EINVAL;
    1264                 :            :         }
    1265                 :            : 
    1266         [ +  + ]:      49058 :         if (ranges == NULL) {
    1267                 :          0 :                 return -EINVAL;
    1268                 :            :         }
    1269                 :            : 
    1270                 :      49062 :         req = nvme_allocate_request_user_copy(qpair, (void *)ranges,
    1271                 :          4 :                                               num_ranges * sizeof(struct spdk_nvme_dsm_range),
    1272                 :          4 :                                               cb_fn, cb_arg, true);
    1273         [ -  + ]:      49058 :         if (req == NULL) {
    1274                 :          0 :                 return -ENOMEM;
    1275                 :            :         }
    1276                 :            : 
    1277         [ #  # ]:      49058 :         cmd = &req->cmd;
    1278         [ #  # ]:      49058 :         cmd->opc = SPDK_NVME_OPC_DATASET_MANAGEMENT;
    1279   [ #  #  #  #  :      49058 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1280                 :            : 
    1281   [ #  #  #  #  :      49058 :         cmd->cdw10_bits.dsm.nr = num_ranges - 1;
          #  #  #  #  #  
                      # ]
    1282   [ #  #  #  #  :      49058 :         cmd->cdw11 = type;
                   #  # ]
    1283                 :            : 
    1284                 :      49058 :         return nvme_qpair_submit_request(qpair, req);
    1285                 :          5 : }
    1286                 :            : 
    1287                 :            : int
    1288                 :         51 : spdk_nvme_ns_cmd_copy(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1289                 :            :                       const struct spdk_nvme_scc_source_range *ranges,
    1290                 :            :                       uint16_t num_ranges, uint64_t dest_lba,
    1291                 :            :                       spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1292                 :            : {
    1293                 :            :         struct nvme_request     *req;
    1294                 :            :         struct spdk_nvme_cmd    *cmd;
    1295                 :            : 
    1296         [ +  + ]:         51 :         if (num_ranges == 0) {
    1297                 :          4 :                 return -EINVAL;
    1298                 :            :         }
    1299                 :            : 
    1300         [ +  + ]:         47 :         if (ranges == NULL) {
    1301                 :          0 :                 return -EINVAL;
    1302                 :            :         }
    1303                 :            : 
    1304                 :         50 :         req = nvme_allocate_request_user_copy(qpair, (void *)ranges,
    1305                 :          3 :                                               num_ranges * sizeof(struct spdk_nvme_scc_source_range),
    1306                 :          3 :                                               cb_fn, cb_arg, true);
    1307         [ -  + ]:         47 :         if (req == NULL) {
    1308                 :          0 :                 return -ENOMEM;
    1309                 :            :         }
    1310                 :            : 
    1311         [ #  # ]:         47 :         cmd = &req->cmd;
    1312         [ #  # ]:         47 :         cmd->opc = SPDK_NVME_OPC_COPY;
    1313   [ #  #  #  #  :         47 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1314                 :            : 
    1315   [ #  #  #  #  :         47 :         *(uint64_t *)&cmd->cdw10 = dest_lba;
                   #  # ]
    1316   [ #  #  #  #  :         47 :         cmd->cdw12 = num_ranges - 1;
             #  #  #  # ]
    1317                 :            : 
    1318                 :         47 :         return nvme_qpair_submit_request(qpair, req);
    1319                 :          4 : }
    1320                 :            : 
    1321                 :            : int
    1322                 :          4 : spdk_nvme_ns_cmd_flush(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1323                 :            :                        spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1324                 :            : {
    1325                 :            :         struct nvme_request     *req;
    1326                 :            :         struct spdk_nvme_cmd    *cmd;
    1327                 :            : 
    1328                 :          4 :         req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
    1329         [ -  + ]:          4 :         if (req == NULL) {
    1330                 :          0 :                 return -ENOMEM;
    1331                 :            :         }
    1332                 :            : 
    1333         [ #  # ]:          4 :         cmd = &req->cmd;
    1334         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_FLUSH;
    1335   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1336                 :            : 
    1337                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1338                 :          1 : }
    1339                 :            : 
    1340                 :            : int
    1341                 :          4 : spdk_nvme_ns_cmd_reservation_register(struct spdk_nvme_ns *ns,
    1342                 :            :                                       struct spdk_nvme_qpair *qpair,
    1343                 :            :                                       struct spdk_nvme_reservation_register_data *payload,
    1344                 :            :                                       bool ignore_key,
    1345                 :            :                                       enum spdk_nvme_reservation_register_action action,
    1346                 :            :                                       enum spdk_nvme_reservation_register_cptpl cptpl,
    1347                 :            :                                       spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1348                 :            : {
    1349                 :            :         struct nvme_request     *req;
    1350                 :            :         struct spdk_nvme_cmd    *cmd;
    1351                 :            : 
    1352                 :          5 :         req = nvme_allocate_request_user_copy(qpair,
    1353                 :          1 :                                               payload, sizeof(struct spdk_nvme_reservation_register_data),
    1354                 :          1 :                                               cb_fn, cb_arg, true);
    1355         [ -  + ]:          4 :         if (req == NULL) {
    1356                 :          0 :                 return -ENOMEM;
    1357                 :            :         }
    1358                 :            : 
    1359         [ #  # ]:          4 :         cmd = &req->cmd;
    1360         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_RESERVATION_REGISTER;
    1361   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1362                 :            : 
    1363   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_register.rrega = action;
             #  #  #  # ]
    1364   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_register.iekey = ignore_key;
          #  #  #  #  #  
                      # ]
    1365   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_register.cptpl = cptpl;
             #  #  #  # ]
    1366                 :            : 
    1367                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1368                 :          1 : }
    1369                 :            : 
    1370                 :            : int
    1371                 :          4 : spdk_nvme_ns_cmd_reservation_release(struct spdk_nvme_ns *ns,
    1372                 :            :                                      struct spdk_nvme_qpair *qpair,
    1373                 :            :                                      struct spdk_nvme_reservation_key_data *payload,
    1374                 :            :                                      bool ignore_key,
    1375                 :            :                                      enum spdk_nvme_reservation_release_action action,
    1376                 :            :                                      enum spdk_nvme_reservation_type type,
    1377                 :            :                                      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1378                 :            : {
    1379                 :            :         struct nvme_request     *req;
    1380                 :            :         struct spdk_nvme_cmd    *cmd;
    1381                 :            : 
    1382                 :          5 :         req = nvme_allocate_request_user_copy(qpair,
    1383                 :          1 :                                               payload, sizeof(struct spdk_nvme_reservation_key_data), cb_fn,
    1384                 :          1 :                                               cb_arg, true);
    1385         [ -  + ]:          4 :         if (req == NULL) {
    1386                 :          0 :                 return -ENOMEM;
    1387                 :            :         }
    1388                 :            : 
    1389         [ #  # ]:          4 :         cmd = &req->cmd;
    1390         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_RESERVATION_RELEASE;
    1391   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1392                 :            : 
    1393   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_release.rrela = action;
             #  #  #  # ]
    1394   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_release.iekey = ignore_key;
          #  #  #  #  #  
                      # ]
    1395   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_release.rtype = type;
             #  #  #  # ]
    1396                 :            : 
    1397                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1398                 :          1 : }
    1399                 :            : 
    1400                 :            : int
    1401                 :          4 : spdk_nvme_ns_cmd_reservation_acquire(struct spdk_nvme_ns *ns,
    1402                 :            :                                      struct spdk_nvme_qpair *qpair,
    1403                 :            :                                      struct spdk_nvme_reservation_acquire_data *payload,
    1404                 :            :                                      bool ignore_key,
    1405                 :            :                                      enum spdk_nvme_reservation_acquire_action action,
    1406                 :            :                                      enum spdk_nvme_reservation_type type,
    1407                 :            :                                      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1408                 :            : {
    1409                 :            :         struct nvme_request     *req;
    1410                 :            :         struct spdk_nvme_cmd    *cmd;
    1411                 :            : 
    1412                 :          5 :         req = nvme_allocate_request_user_copy(qpair,
    1413                 :          1 :                                               payload, sizeof(struct spdk_nvme_reservation_acquire_data),
    1414                 :          1 :                                               cb_fn, cb_arg, true);
    1415         [ -  + ]:          4 :         if (req == NULL) {
    1416                 :          0 :                 return -ENOMEM;
    1417                 :            :         }
    1418                 :            : 
    1419         [ #  # ]:          4 :         cmd = &req->cmd;
    1420         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_RESERVATION_ACQUIRE;
    1421   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1422                 :            : 
    1423   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_acquire.racqa = action;
             #  #  #  # ]
    1424   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_acquire.iekey = ignore_key;
          #  #  #  #  #  
                      # ]
    1425   [ #  #  #  #  :          4 :         cmd->cdw10_bits.resv_acquire.rtype = type;
             #  #  #  # ]
    1426                 :            : 
    1427                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1428                 :          1 : }
    1429                 :            : 
    1430                 :            : int
    1431                 :          4 : spdk_nvme_ns_cmd_reservation_report(struct spdk_nvme_ns *ns,
    1432                 :            :                                     struct spdk_nvme_qpair *qpair,
    1433                 :            :                                     void *payload, uint32_t len,
    1434                 :            :                                     spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1435                 :            : {
    1436                 :            :         uint32_t                num_dwords;
    1437                 :            :         struct nvme_request     *req;
    1438                 :            :         struct spdk_nvme_cmd    *cmd;
    1439                 :            : 
    1440         [ -  + ]:          4 :         if (len & 0x3) {
    1441                 :          0 :                 return -EINVAL;
    1442                 :            :         }
    1443                 :            : 
    1444                 :          4 :         req = nvme_allocate_request_user_copy(qpair, payload, len, cb_fn, cb_arg, false);
    1445         [ -  + ]:          4 :         if (req == NULL) {
    1446                 :          0 :                 return -ENOMEM;
    1447                 :            :         }
    1448                 :            : 
    1449         [ #  # ]:          4 :         cmd = &req->cmd;
    1450         [ #  # ]:          4 :         cmd->opc = SPDK_NVME_OPC_RESERVATION_REPORT;
    1451   [ #  #  #  #  :          4 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1452                 :            : 
    1453         [ #  # ]:          4 :         num_dwords = (len >> 2);
    1454   [ #  #  #  #  :          4 :         cmd->cdw10 = num_dwords - 1; /* 0-based */
                   #  # ]
    1455                 :            : 
    1456                 :          4 :         return nvme_qpair_submit_request(qpair, req);
    1457                 :          1 : }
    1458                 :            : 
    1459                 :            : int
    1460                 :         10 : spdk_nvme_ns_cmd_io_mgmt_recv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1461                 :            :                               void *payload, uint32_t len, uint8_t mo, uint16_t mos,
    1462                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1463                 :            : {
    1464                 :            :         uint32_t                num_dwords;
    1465                 :            :         struct nvme_request     *req;
    1466                 :            :         struct spdk_nvme_cmd    *cmd;
    1467                 :            : 
    1468         [ +  + ]:         10 :         if (len & 0x3) {
    1469                 :          4 :                 return -EINVAL;
    1470                 :            :         }
    1471                 :            : 
    1472                 :          6 :         req = nvme_allocate_request_user_copy(qpair, payload, len, cb_fn, cb_arg, false);
    1473         [ -  + ]:          6 :         if (req == NULL) {
    1474                 :          0 :                 return -ENOMEM;
    1475                 :            :         }
    1476                 :            : 
    1477         [ #  # ]:          6 :         cmd = &req->cmd;
    1478         [ #  # ]:          6 :         cmd->opc = SPDK_NVME_OPC_IO_MANAGEMENT_RECEIVE;
    1479   [ #  #  #  #  :          6 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1480                 :            : 
    1481   [ #  #  #  #  :          6 :         cmd->cdw10_bits.mgmt_send_recv.mo = mo;
             #  #  #  # ]
    1482   [ #  #  #  #  :          6 :         cmd->cdw10_bits.mgmt_send_recv.mos = mos;
             #  #  #  # ]
    1483                 :            : 
    1484         [ #  # ]:          6 :         num_dwords = (len >> 2);
    1485   [ #  #  #  #  :          6 :         cmd->cdw11 = num_dwords - 1; /* 0-based */
                   #  # ]
    1486                 :            : 
    1487                 :          6 :         return nvme_qpair_submit_request(qpair, req);
    1488                 :          2 : }
    1489                 :            : 
    1490                 :            : int
    1491                 :          5 : spdk_nvme_ns_cmd_io_mgmt_send(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
    1492                 :            :                               void *payload, uint32_t len, uint8_t mo, uint16_t mos,
    1493                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1494                 :            : {
    1495                 :            :         struct nvme_request     *req;
    1496                 :            :         struct spdk_nvme_cmd    *cmd;
    1497                 :            : 
    1498                 :          5 :         req = nvme_allocate_request_user_copy(qpair, payload, len, cb_fn, cb_arg, false);
    1499         [ -  + ]:          5 :         if (req == NULL) {
    1500                 :          0 :                 return -ENOMEM;
    1501                 :            :         }
    1502                 :            : 
    1503         [ #  # ]:          5 :         cmd = &req->cmd;
    1504         [ #  # ]:          5 :         cmd->opc = SPDK_NVME_OPC_IO_MANAGEMENT_SEND;
    1505   [ #  #  #  #  :          5 :         cmd->nsid = ns->id;
             #  #  #  # ]
    1506                 :            : 
    1507   [ #  #  #  #  :          5 :         cmd->cdw10_bits.mgmt_send_recv.mo = mo;
             #  #  #  # ]
    1508   [ #  #  #  #  :          5 :         cmd->cdw10_bits.mgmt_send_recv.mos = mos;
             #  #  #  # ]
    1509                 :            : 
    1510                 :          5 :         return nvme_qpair_submit_request(qpair, req);
    1511                 :          1 : }

Generated by: LCOV version 1.15