1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "subsystem.h" 37 #include "ctrlr.h" 38 #include "request.h" 39 40 #include "spdk/bdev.h" 41 #include "spdk/endian.h" 42 #include "spdk/io_channel.h" 43 #include "spdk/nvme.h" 44 #include "spdk/nvmf_spec.h" 45 #include "spdk/trace.h" 46 #include "spdk/scsi_spec.h" 47 #include "spdk/string.h" 48 #include "spdk/util.h" 49 50 #include "spdk_internal/log.h" 51 52 /* read command dword 12 */ 53 struct __attribute__((packed)) nvme_read_cdw12 { 54 uint16_t nlb; /* number of logical blocks */ 55 uint16_t rsvd : 10; 56 uint8_t prinfo : 4; /* protection information field */ 57 uint8_t fua : 1; /* force unit access */ 58 uint8_t lr : 1; /* limited retry */ 59 }; 60 61 bool 62 spdk_nvmf_ctrlr_dsm_supported(struct spdk_nvmf_ctrlr *ctrlr) 63 { 64 struct spdk_nvmf_subsystem *subsystem = ctrlr->subsys; 65 struct spdk_nvmf_ns *ns; 66 67 for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; 68 ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { 69 if (ns->bdev == NULL) { 70 continue; 71 } 72 73 if (!spdk_bdev_io_type_supported(ns->bdev, SPDK_BDEV_IO_TYPE_UNMAP)) { 74 SPDK_DEBUGLOG(SPDK_TRACE_NVMF, 75 "Subsystem %s namespace %u (%s) does not support unmap - not enabling DSM\n", 76 spdk_nvmf_subsystem_get_nqn(subsystem), 77 ns->id, spdk_bdev_get_name(ns->bdev)); 78 return false; 79 } 80 } 81 82 SPDK_DEBUGLOG(SPDK_TRACE_NVMF, "All devices in Subsystem %s support unmap - enabling DSM\n", 83 spdk_nvmf_subsystem_get_nqn(subsystem)); 84 return true; 85 } 86 87 static void 88 nvmf_bdev_ctrlr_complete_cmd(struct spdk_bdev_io *bdev_io, bool success, 89 void *cb_arg) 90 { 91 struct spdk_nvmf_request *req = cb_arg; 92 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 93 int sc, sct; 94 95 spdk_bdev_io_get_nvme_status(bdev_io, &sc, &sct); 96 response->status.sc = sc; 97 response->status.sct = sct; 98 99 spdk_nvmf_request_complete(req); 100 spdk_bdev_free_io(bdev_io); 101 } 102 103 int 104 spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_bdev *bdev, struct spdk_nvme_ns_data *nsdata) 105 { 106 uint64_t num_blocks; 107 108 num_blocks = spdk_bdev_get_num_blocks(bdev); 109 110 nsdata->nsze = num_blocks; 111 nsdata->ncap = num_blocks; 112 nsdata->nuse = num_blocks; 113 nsdata->nlbaf = 0; 114 nsdata->flbas.format = 0; 115 nsdata->lbaf[0].lbads = spdk_u32log2(spdk_bdev_get_block_size(bdev)); 116 nsdata->noiob = spdk_bdev_get_optimal_io_boundary(bdev); 117 118 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 119 } 120 121 static int 122 nvmf_bdev_ctrlr_rw_cmd(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 123 struct spdk_io_channel *ch, struct spdk_nvmf_request *req) 124 { 125 uint64_t lba_address; 126 uint64_t blockcnt; 127 uint64_t io_bytes; 128 uint64_t offset; 129 uint64_t llen; 130 uint32_t block_size = spdk_bdev_get_block_size(bdev); 131 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 132 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 133 struct nvme_read_cdw12 *cdw12 = (struct nvme_read_cdw12 *)&cmd->cdw12; 134 135 blockcnt = spdk_bdev_get_num_blocks(bdev); 136 lba_address = cmd->cdw11; 137 lba_address = (lba_address << 32) + cmd->cdw10; 138 offset = lba_address * block_size; 139 llen = cdw12->nlb + 1; 140 141 if (lba_address >= blockcnt || llen > blockcnt || lba_address > (blockcnt - llen)) { 142 SPDK_ERRLOG("end of media\n"); 143 response->status.sc = SPDK_NVME_SC_LBA_OUT_OF_RANGE; 144 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 145 } 146 147 io_bytes = llen * block_size; 148 if (io_bytes > req->length) { 149 SPDK_ERRLOG("Read/Write NLB > SGL length\n"); 150 response->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID; 151 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 152 } 153 154 if (cmd->opc == SPDK_NVME_OPC_READ) { 155 spdk_trace_record(TRACE_NVMF_LIB_READ_START, 0, 0, (uint64_t)req, 0); 156 if (spdk_bdev_read(desc, ch, req->data, offset, req->length, nvmf_bdev_ctrlr_complete_cmd, 157 req)) { 158 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 159 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 160 } 161 } else { 162 spdk_trace_record(TRACE_NVMF_LIB_WRITE_START, 0, 0, (uint64_t)req, 0); 163 if (spdk_bdev_write(desc, ch, req->data, offset, req->length, nvmf_bdev_ctrlr_complete_cmd, 164 req)) { 165 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 166 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 167 } 168 } 169 return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 170 171 } 172 173 static int 174 nvmf_bdev_ctrlr_flush_cmd(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 175 struct spdk_io_channel *ch, struct spdk_nvmf_request *req) 176 { 177 uint64_t nbytes; 178 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 179 180 nbytes = spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev); 181 if (spdk_bdev_flush(desc, ch, 0, nbytes, nvmf_bdev_ctrlr_complete_cmd, req)) { 182 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 183 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 184 } 185 return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 186 } 187 188 struct nvmf_virtual_ctrlr_unmap { 189 struct spdk_nvmf_request *req; 190 uint32_t count; 191 }; 192 193 static void 194 nvmf_virtual_ctrlr_dsm_cpl(struct spdk_bdev_io *bdev_io, bool success, 195 void *cb_arg) 196 { 197 struct nvmf_virtual_ctrlr_unmap *unmap_ctx = cb_arg; 198 struct spdk_nvmf_request *req = unmap_ctx->req; 199 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 200 int sc, sct; 201 202 unmap_ctx->count--; 203 204 if (response->status.sct == SPDK_NVME_SCT_GENERIC && 205 response->status.sc == SPDK_NVME_SC_SUCCESS) { 206 spdk_bdev_io_get_nvme_status(bdev_io, &sc, &sct); 207 response->status.sc = sc; 208 response->status.sct = sct; 209 } 210 211 if (unmap_ctx->count == 0) { 212 spdk_nvmf_request_complete(req); 213 spdk_bdev_free_io(bdev_io); 214 free(unmap_ctx); 215 } 216 } 217 218 static int 219 nvmf_bdev_ctrlr_dsm_cmd(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 220 struct spdk_io_channel *ch, struct spdk_nvmf_request *req) 221 { 222 uint32_t attribute; 223 uint16_t nr, i; 224 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 225 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 226 227 nr = ((cmd->cdw10 & 0x000000ff) + 1); 228 if (nr * sizeof(struct spdk_nvme_dsm_range) > req->length) { 229 SPDK_ERRLOG("Dataset Management number of ranges > SGL length\n"); 230 response->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID; 231 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 232 } 233 234 attribute = cmd->cdw11 & 0x00000007; 235 if (attribute & SPDK_NVME_DSM_ATTR_DEALLOCATE) { 236 struct nvmf_virtual_ctrlr_unmap *unmap_ctx; 237 struct spdk_nvme_dsm_range *dsm_range; 238 uint64_t lba; 239 uint32_t lba_count; 240 uint32_t block_size = spdk_bdev_get_block_size(bdev); 241 242 unmap_ctx = calloc(1, sizeof(*unmap_ctx)); 243 if (!unmap_ctx) { 244 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 245 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 246 } 247 248 unmap_ctx->req = req; 249 250 response->status.sct = SPDK_NVME_SCT_GENERIC; 251 response->status.sc = SPDK_NVME_SC_SUCCESS; 252 253 dsm_range = (struct spdk_nvme_dsm_range *)req->data; 254 for (i = 0; i < nr; i++) { 255 lba = dsm_range[i].starting_lba; 256 lba_count = dsm_range[i].length; 257 258 unmap_ctx->count++; 259 260 if (spdk_bdev_unmap(desc, ch, lba * block_size, lba_count * block_size, 261 nvmf_virtual_ctrlr_dsm_cpl, unmap_ctx)) { 262 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 263 unmap_ctx->count--; 264 /* We can't return here - we may have to wait for any other 265 * unmaps already sent to complete */ 266 break; 267 } 268 } 269 270 if (unmap_ctx->count == 0) { 271 free(unmap_ctx); 272 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 273 } 274 275 return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 276 } 277 278 response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; 279 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 280 } 281 282 static int 283 nvmf_bdev_ctrlr_nvme_passthru_io(struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 284 struct spdk_io_channel *ch, struct spdk_nvmf_request *req) 285 { 286 if (spdk_bdev_nvme_io_passthru(desc, ch, &req->cmd->nvme_cmd, req->data, req->length, 287 nvmf_bdev_ctrlr_complete_cmd, req)) { 288 req->rsp->nvme_cpl.status.sct = SPDK_NVME_SCT_GENERIC; 289 req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INVALID_OPCODE; 290 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 291 } 292 293 return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; 294 } 295 296 int 297 spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req) 298 { 299 uint32_t nsid; 300 struct spdk_nvmf_ns *ns; 301 struct spdk_bdev *bdev; 302 struct spdk_bdev_desc *desc; 303 struct spdk_io_channel *ch; 304 struct spdk_nvmf_subsystem *subsystem = req->qpair->ctrlr->subsys; 305 struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; 306 struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; 307 308 /* pre-set response details for this command */ 309 response->status.sc = SPDK_NVME_SC_SUCCESS; 310 nsid = cmd->nsid; 311 312 ns = _spdk_nvmf_subsystem_get_ns(subsystem, nsid); 313 if (ns == NULL || ns->bdev == NULL) { 314 SPDK_ERRLOG("Unsuccessful query for nsid %u\n", cmd->nsid); 315 response->status.sc = SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT; 316 return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; 317 } 318 319 bdev = ns->bdev; 320 desc = ns->desc; 321 ch = ns->ch; 322 switch (cmd->opc) { 323 case SPDK_NVME_OPC_READ: 324 case SPDK_NVME_OPC_WRITE: 325 return nvmf_bdev_ctrlr_rw_cmd(bdev, desc, ch, req); 326 case SPDK_NVME_OPC_FLUSH: 327 return nvmf_bdev_ctrlr_flush_cmd(bdev, desc, ch, req); 328 case SPDK_NVME_OPC_DATASET_MANAGEMENT: 329 return nvmf_bdev_ctrlr_dsm_cmd(bdev, desc, ch, req); 330 default: 331 return nvmf_bdev_ctrlr_nvme_passthru_io(bdev, desc, ch, req); 332 } 333 } 334 335 static int 336 spdk_nvmf_ns_bdev_attach(struct spdk_nvmf_ns *ns) 337 { 338 if (ns->bdev == NULL) { 339 return 0; 340 } 341 342 ns->ch = spdk_bdev_get_io_channel(ns->desc); 343 if (ns->ch == NULL) { 344 SPDK_ERRLOG("io_channel allocation failed\n"); 345 return -1; 346 } 347 348 return 0; 349 } 350 351 static void 352 spdk_nvmf_ns_bdev_detach(struct spdk_nvmf_ns *ns) 353 { 354 if (ns->bdev == NULL) { 355 return; 356 } 357 358 if (ns->ch) { 359 spdk_put_io_channel(ns->ch); 360 ns->ch = NULL; 361 } 362 if (ns->desc) { 363 spdk_bdev_close(ns->desc); 364 ns->desc = NULL; 365 } 366 ns->bdev = NULL; 367 } 368 369 int 370 spdk_nvmf_subsystem_bdev_attach(struct spdk_nvmf_subsystem *subsystem) 371 { 372 struct spdk_nvmf_ns *ns; 373 374 for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; 375 ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { 376 if (spdk_nvmf_ns_bdev_attach(ns)) { 377 return -1; 378 } 379 } 380 381 return 0; 382 } 383 384 void 385 spdk_nvmf_subsystem_bdev_detach(struct spdk_nvmf_subsystem *subsystem) 386 { 387 struct spdk_nvmf_ns *ns; 388 389 for (ns = spdk_nvmf_subsystem_get_first_ns(subsystem); ns != NULL; 390 ns = spdk_nvmf_subsystem_get_next_ns(subsystem, ns)) { 391 spdk_nvmf_ns_bdev_detach(ns); 392 } 393 subsystem->max_nsid = 0; 394 } 395