Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2015 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk_internal/cunit.h"
7 : :
8 : : #include "nvme/nvme_ns_cmd.c"
9 : : #include "nvme/nvme.c"
10 : :
11 : : #include "common/lib/test_env.c"
12 : :
13 : : #define UT_MAX_IOVS 2u
14 : : #define UT_SIZE_IOMS 128u
15 : :
16 : : struct nvme_ns_cmd_ut_cb_arg {
17 : : struct iovec iovs[UT_MAX_IOVS];
18 : : uint32_t iovpos;
19 : : };
20 : :
21 : : static struct nvme_driver _g_nvme_driver = {
22 : : .lock = PTHREAD_MUTEX_INITIALIZER,
23 : : };
24 : :
25 : : static struct nvme_request *g_request = NULL;
26 : : static uint32_t g_ctrlr_quirks;
27 : :
28 : 0 : DEFINE_STUB_V(nvme_io_msg_ctrlr_detach, (struct spdk_nvme_ctrlr *ctrlr));
29 : :
30 : 0 : DEFINE_STUB_V(nvme_ctrlr_destruct_async,
31 : : (struct spdk_nvme_ctrlr *ctrlr, struct nvme_ctrlr_detach_ctx *ctx));
32 : :
33 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_destruct_poll_async,
34 : : int,
35 : : (struct spdk_nvme_ctrlr *ctrlr, struct nvme_ctrlr_detach_ctx *ctx),
36 : : 0);
37 : :
38 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_poll_group_process_completions,
39 : : int64_t,
40 : : (struct spdk_nvme_poll_group *group, uint32_t completions_per_qpair,
41 : : spdk_nvme_disconnected_qpair_cb disconnected_qpair_cb),
42 : : 0);
43 : :
44 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_qpair_process_completions,
45 : : int32_t,
46 : : (struct spdk_nvme_qpair *qpair, uint32_t max_completions),
47 : : 0);
48 : :
49 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_ctrlr_get_regs_csts,
50 : : union spdk_nvme_csts_register,
51 : : (struct spdk_nvme_ctrlr *ctrlr),
52 : : {});
53 : :
54 [ # # ]: 0 : DEFINE_STUB(spdk_pci_event_listen, int, (void), 1);
55 : :
56 [ # # ]: 0 : DEFINE_STUB(nvme_transport_ctrlr_destruct,
57 : : int,
58 : : (struct spdk_nvme_ctrlr *ctrlr),
59 : : 0);
60 : :
61 [ # # ]: 0 : DEFINE_STUB(nvme_ctrlr_get_current_process,
62 : : struct spdk_nvme_ctrlr_process *,
63 : : (struct spdk_nvme_ctrlr *ctrlr),
64 : : (struct spdk_nvme_ctrlr_process *)(uintptr_t)0x1);
65 : :
66 [ # # ]: 0 : DEFINE_STUB(nvme_transport_ctrlr_scan_attached,
67 : : int,
68 : : (struct spdk_nvme_probe_ctx *probe_ctx),
69 : : 0);
70 : :
71 : : int
72 : 0 : spdk_pci_enumerate(struct spdk_pci_driver *driver, spdk_pci_enum_cb enum_cb, void *enum_ctx)
73 : : {
74 : 0 : return -1;
75 : : }
76 : :
77 : : static void
78 : 90 : nvme_request_reset_sgl(void *cb_arg, uint32_t sgl_offset)
79 : : {
80 : 90 : }
81 : :
82 : : static int
83 : 80 : nvme_request_next_sge(void *cb_arg, void **address, uint32_t *length)
84 : : {
85 : 80 : uint32_t *lba_count = cb_arg;
86 : :
87 : : /*
88 : : * We need to set address to something here, since the SGL splitting code will
89 : : * use it to determine PRP compatibility. Just use a rather arbitrary address
90 : : * for now - these tests will not actually cause data to be read from or written
91 : : * to this address.
92 : : */
93 : 80 : *address = (void *)(uintptr_t)0x10000000;
94 : 80 : *length = *lba_count;
95 : 80 : return 0;
96 : : }
97 : :
98 : : bool
99 : 0 : spdk_nvme_transport_available_by_name(const char *transport_name)
100 : : {
101 : 0 : return true;
102 : : }
103 : :
104 : 0 : struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_transport_id *trid,
105 : : const struct spdk_nvme_ctrlr_opts *opts,
106 : : void *devhandle)
107 : : {
108 : 0 : return NULL;
109 : : }
110 : :
111 : : void
112 : 0 : nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr)
113 : : {
114 : 0 : }
115 : :
116 : : int
117 : 0 : nvme_ctrlr_add_process(struct spdk_nvme_ctrlr *ctrlr, void *devhandle)
118 : : {
119 : 0 : return 0;
120 : : }
121 : :
122 : : int
123 : 0 : nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
124 : : {
125 : 0 : return 0;
126 : : }
127 : :
128 : : void
129 : 0 : nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr, bool hot_remove)
130 : : {
131 : 0 : }
132 : :
133 : : struct spdk_pci_addr
134 : 0 : spdk_pci_device_get_addr(struct spdk_pci_device *pci_dev)
135 : : {
136 : 0 : struct spdk_pci_addr pci_addr;
137 : :
138 [ # # ]: 0 : memset(&pci_addr, 0, sizeof(pci_addr));
139 : 0 : return pci_addr;
140 : : }
141 : :
142 : : struct spdk_pci_id
143 : 0 : spdk_pci_device_get_id(struct spdk_pci_device *pci_dev)
144 : : {
145 : 0 : struct spdk_pci_id pci_id;
146 : :
147 [ # # ]: 0 : memset(&pci_id, 0xFF, sizeof(pci_id));
148 : :
149 : 0 : return pci_id;
150 : : }
151 : :
152 : : void
153 : 0 : spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t opts_size)
154 : : {
155 [ # # ]: 0 : memset(opts, 0, sizeof(*opts));
156 : 0 : }
157 : :
158 : : uint32_t
159 : 0 : spdk_nvme_ns_get_sector_size(struct spdk_nvme_ns *ns)
160 : : {
161 : 0 : return ns->sector_size;
162 : : }
163 : :
164 : : uint32_t
165 : 510 : spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns)
166 : : {
167 : 510 : return ns->ctrlr->max_xfer_size;
168 : : }
169 : :
170 : : int
171 : 280 : nvme_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_request *req)
172 : : {
173 : 280 : g_request = req;
174 : :
175 : 280 : return 0;
176 : : }
177 : :
178 : : void
179 : 0 : nvme_ctrlr_proc_get_ref(struct spdk_nvme_ctrlr *ctrlr)
180 : : {
181 : 0 : return;
182 : : }
183 : :
184 : : void
185 : 0 : nvme_ctrlr_proc_put_ref(struct spdk_nvme_ctrlr *ctrlr)
186 : : {
187 : 0 : return;
188 : : }
189 : :
190 : : int
191 : 0 : nvme_ctrlr_get_ref_count(struct spdk_nvme_ctrlr *ctrlr)
192 : : {
193 : 0 : return 0;
194 : : }
195 : :
196 : : int
197 : 0 : nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx,
198 : : bool direct_connect)
199 : : {
200 : 0 : return 0;
201 : : }
202 : :
203 : : static void
204 : 255 : prepare_for_test(struct spdk_nvme_ns *ns, struct spdk_nvme_ctrlr *ctrlr,
205 : : struct spdk_nvme_qpair *qpair,
206 : : uint32_t sector_size, uint32_t md_size, uint32_t max_xfer_size,
207 : : uint32_t stripe_size, bool extended_lba)
208 : : {
209 : 255 : uint32_t num_requests = 32;
210 : : uint32_t i;
211 : :
212 [ - + ]: 255 : memset(ctrlr, 0, sizeof(*ctrlr));
213 : 255 : ctrlr->quirks = g_ctrlr_quirks;
214 : 255 : ctrlr->max_xfer_size = max_xfer_size;
215 : : /*
216 : : * Clear the flags field - we especially want to make sure the SGL_SUPPORTED flag is not set
217 : : * so that we test the SGL splitting path.
218 : : */
219 : 255 : ctrlr->flags = 0;
220 : 255 : ctrlr->min_page_size = 4096;
221 : 255 : ctrlr->page_size = 4096;
222 [ - + ]: 255 : memset(&ctrlr->opts, 0, sizeof(ctrlr->opts));
223 [ - + ]: 255 : memset(ns, 0, sizeof(*ns));
224 : 255 : ns->ctrlr = ctrlr;
225 : 255 : ns->sector_size = sector_size;
226 : 255 : ns->extended_lba_size = sector_size;
227 [ + + ]: 255 : if (extended_lba) {
228 : 60 : ns->flags |= SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED;
229 : 60 : ns->extended_lba_size += md_size;
230 : : }
231 : 255 : ns->md_size = md_size;
232 [ - + ]: 255 : ns->sectors_per_max_io = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->extended_lba_size;
233 [ - + ]: 255 : ns->sectors_per_max_io_no_md = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->sector_size;
234 [ + + ]: 255 : if (ctrlr->quirks & NVME_QUIRK_MDTS_EXCLUDE_MD) {
235 : 5 : ns->sectors_per_max_io = ns->sectors_per_max_io_no_md;
236 : : }
237 [ - + ]: 255 : ns->sectors_per_stripe = stripe_size / ns->extended_lba_size;
238 : :
239 [ - + ]: 255 : memset(qpair, 0, sizeof(*qpair));
240 : 255 : qpair->ctrlr = ctrlr;
241 : 255 : qpair->req_buf = calloc(num_requests, sizeof(struct nvme_request));
242 [ - + ]: 255 : SPDK_CU_ASSERT_FATAL(qpair->req_buf != NULL);
243 : :
244 [ + + ]: 8415 : for (i = 0; i < num_requests; i++) {
245 : 8160 : struct nvme_request *req = qpair->req_buf + i * sizeof(struct nvme_request);
246 : :
247 : 8160 : req->qpair = qpair;
248 [ + + ]: 8160 : STAILQ_INSERT_HEAD(&qpair->free_req, req, stailq);
249 : : }
250 : :
251 : 255 : g_request = NULL;
252 : 255 : }
253 : :
254 : : static void
255 : 255 : cleanup_after_test(struct spdk_nvme_qpair *qpair)
256 : : {
257 : 255 : free(qpair->req_buf);
258 : 255 : g_ctrlr_quirks = 0;
259 : 255 : }
260 : :
261 : : static void
262 : 80 : nvme_cmd_interpret_rw(const struct spdk_nvme_cmd *cmd,
263 : : uint64_t *lba, uint32_t *num_blocks)
264 : : {
265 : 80 : *lba = *(const uint64_t *)&cmd->cdw10;
266 : 80 : *num_blocks = (cmd->cdw12 & 0xFFFFu) + 1;
267 : 80 : }
268 : :
269 : : static void
270 : 5 : split_test(void)
271 : : {
272 : 4 : struct spdk_nvme_ns ns;
273 : 4 : struct spdk_nvme_qpair qpair;
274 : 4 : struct spdk_nvme_ctrlr ctrlr;
275 : : void *payload;
276 : 4 : uint64_t lba, cmd_lba;
277 : 4 : uint32_t lba_count, cmd_lba_count;
278 : : int rc;
279 : :
280 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
281 : 5 : payload = malloc(512);
282 : 5 : lba = 0;
283 : 5 : lba_count = 1;
284 : :
285 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL, 0);
286 : :
287 : 5 : CU_ASSERT(rc == 0);
288 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
289 : :
290 : 5 : CU_ASSERT(g_request->num_children == 0);
291 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
292 : 5 : CU_ASSERT(cmd_lba == lba);
293 : 5 : CU_ASSERT(cmd_lba_count == lba_count);
294 : :
295 : 5 : free(payload);
296 : 5 : nvme_free_request(g_request);
297 : 5 : cleanup_after_test(&qpair);
298 : 5 : }
299 : :
300 : : static void
301 : 5 : split_test2(void)
302 : : {
303 : 4 : struct spdk_nvme_ns ns;
304 : 4 : struct spdk_nvme_ctrlr ctrlr;
305 : 4 : struct spdk_nvme_qpair qpair;
306 : : struct nvme_request *child;
307 : : void *payload;
308 : 4 : uint64_t lba, cmd_lba;
309 : 4 : uint32_t lba_count, cmd_lba_count;
310 : : int rc;
311 : :
312 : : /*
313 : : * Controller has max xfer of 128 KB (256 blocks).
314 : : * Submit an I/O of 256 KB starting at LBA 0, which should be split
315 : : * on the max I/O boundary into two I/Os of 128 KB.
316 : : */
317 : :
318 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
319 : 5 : payload = malloc(256 * 1024);
320 : 5 : lba = 0;
321 : 5 : lba_count = (256 * 1024) / 512;
322 : :
323 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL, 0);
324 : :
325 : 5 : CU_ASSERT(rc == 0);
326 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
327 : :
328 : 5 : CU_ASSERT(g_request->num_children == 2);
329 : :
330 : 5 : child = TAILQ_FIRST(&g_request->children);
331 : 5 : nvme_request_remove_child(g_request, child);
332 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
333 : 5 : CU_ASSERT(child->num_children == 0);
334 : 5 : CU_ASSERT(child->payload_size == 128 * 1024);
335 : 5 : CU_ASSERT(cmd_lba == 0);
336 : 5 : CU_ASSERT(cmd_lba_count == 256); /* 256 * 512 byte blocks = 128 KB */
337 : 5 : nvme_free_request(child);
338 : :
339 : 5 : child = TAILQ_FIRST(&g_request->children);
340 : 5 : nvme_request_remove_child(g_request, child);
341 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
342 : 5 : CU_ASSERT(child->num_children == 0);
343 : 5 : CU_ASSERT(child->payload_size == 128 * 1024);
344 : 5 : CU_ASSERT(cmd_lba == 256);
345 : 5 : CU_ASSERT(cmd_lba_count == 256);
346 : 5 : nvme_free_request(child);
347 : :
348 : 5 : CU_ASSERT(TAILQ_EMPTY(&g_request->children));
349 : :
350 : 5 : free(payload);
351 : 5 : nvme_free_request(g_request);
352 : 5 : cleanup_after_test(&qpair);
353 : 5 : }
354 : :
355 : : static void
356 : 5 : split_test3(void)
357 : : {
358 : 4 : struct spdk_nvme_ns ns;
359 : 4 : struct spdk_nvme_ctrlr ctrlr;
360 : 4 : struct spdk_nvme_qpair qpair;
361 : : struct nvme_request *child;
362 : : void *payload;
363 : 4 : uint64_t lba, cmd_lba;
364 : 4 : uint32_t lba_count, cmd_lba_count;
365 : : int rc;
366 : :
367 : : /*
368 : : * Controller has max xfer of 128 KB (256 blocks).
369 : : * Submit an I/O of 256 KB starting at LBA 10, which should be split
370 : : * into two I/Os:
371 : : * 1) LBA = 10, count = 256 blocks
372 : : * 2) LBA = 266, count = 256 blocks
373 : : */
374 : :
375 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
376 : 5 : payload = malloc(256 * 1024);
377 : 5 : lba = 10; /* Start at an LBA that isn't aligned to the stripe size */
378 : 5 : lba_count = (256 * 1024) / 512;
379 : :
380 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL, 0);
381 : :
382 : 5 : CU_ASSERT(rc == 0);
383 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
384 : :
385 : 5 : CU_ASSERT(g_request->num_children == 2);
386 : :
387 : 5 : child = TAILQ_FIRST(&g_request->children);
388 : 5 : nvme_request_remove_child(g_request, child);
389 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
390 : 5 : CU_ASSERT(child->num_children == 0);
391 : 5 : CU_ASSERT(child->payload_size == 128 * 1024);
392 : 5 : CU_ASSERT(cmd_lba == 10);
393 : 5 : CU_ASSERT(cmd_lba_count == 256);
394 : 5 : nvme_free_request(child);
395 : :
396 : 5 : child = TAILQ_FIRST(&g_request->children);
397 : 5 : nvme_request_remove_child(g_request, child);
398 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
399 : 5 : CU_ASSERT(child->num_children == 0);
400 : 5 : CU_ASSERT(child->payload_size == 128 * 1024);
401 : 5 : CU_ASSERT(cmd_lba == 266);
402 : 5 : CU_ASSERT(cmd_lba_count == 256);
403 : 5 : nvme_free_request(child);
404 : :
405 : 5 : CU_ASSERT(TAILQ_EMPTY(&g_request->children));
406 : :
407 : 5 : free(payload);
408 : 5 : nvme_free_request(g_request);
409 : 5 : cleanup_after_test(&qpair);
410 : 5 : }
411 : :
412 : : static void
413 : 5 : split_test4(void)
414 : : {
415 : 4 : struct spdk_nvme_ns ns;
416 : 4 : struct spdk_nvme_ctrlr ctrlr;
417 : 4 : struct spdk_nvme_qpair qpair;
418 : : struct nvme_request *child;
419 : : void *payload;
420 : 4 : uint64_t lba, cmd_lba;
421 : 4 : uint32_t lba_count, cmd_lba_count;
422 : : int rc;
423 : :
424 : : /*
425 : : * Controller has max xfer of 128 KB (256 blocks) and a stripe size of 128 KB.
426 : : * (Same as split_test3 except with driver-assisted striping enabled.)
427 : : * Submit an I/O of 256 KB starting at LBA 10, which should be split
428 : : * into three I/Os:
429 : : * 1) LBA = 10, count = 246 blocks (less than max I/O size to align to stripe size)
430 : : * 2) LBA = 256, count = 256 blocks (aligned to stripe size and max I/O size)
431 : : * 3) LBA = 512, count = 10 blocks (finish off the remaining I/O size)
432 : : */
433 : :
434 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 128 * 1024, false);
435 : 5 : payload = malloc(256 * 1024);
436 : 5 : lba = 10; /* Start at an LBA that isn't aligned to the stripe size */
437 : 5 : lba_count = (256 * 1024) / 512;
438 : :
439 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
440 : : SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS);
441 : :
442 : 5 : CU_ASSERT(rc == 0);
443 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
444 : :
445 : 5 : CU_ASSERT(g_request->num_children == 3);
446 : :
447 : 5 : child = TAILQ_FIRST(&g_request->children);
448 : 5 : nvme_request_remove_child(g_request, child);
449 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
450 : 5 : CU_ASSERT(child->num_children == 0);
451 : 5 : CU_ASSERT(child->payload_size == (256 - 10) * 512);
452 : 5 : CU_ASSERT(child->payload_offset == 0);
453 : 5 : CU_ASSERT(cmd_lba == 10);
454 : 5 : CU_ASSERT(cmd_lba_count == 256 - 10);
455 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS) != 0);
456 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) == 0);
457 : 5 : nvme_free_request(child);
458 : :
459 : 5 : child = TAILQ_FIRST(&g_request->children);
460 : 5 : nvme_request_remove_child(g_request, child);
461 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
462 : 5 : CU_ASSERT(child->num_children == 0);
463 : 5 : CU_ASSERT(child->payload_size == 128 * 1024);
464 : 5 : CU_ASSERT(child->payload_offset == (256 - 10) * 512);
465 : 5 : CU_ASSERT(cmd_lba == 256);
466 : 5 : CU_ASSERT(cmd_lba_count == 256);
467 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS) != 0);
468 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) == 0);
469 : 5 : nvme_free_request(child);
470 : :
471 : 5 : child = TAILQ_FIRST(&g_request->children);
472 : 5 : nvme_request_remove_child(g_request, child);
473 : 5 : nvme_cmd_interpret_rw(&child->cmd, &cmd_lba, &cmd_lba_count);
474 : 5 : CU_ASSERT(child->num_children == 0);
475 : 5 : CU_ASSERT(child->payload_size == 10 * 512);
476 : 5 : CU_ASSERT(child->payload_offset == (512 - 10) * 512);
477 : 5 : CU_ASSERT(cmd_lba == 512);
478 : 5 : CU_ASSERT(cmd_lba_count == 10);
479 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS) != 0);
480 : 5 : CU_ASSERT((child->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) == 0);
481 : 5 : nvme_free_request(child);
482 : :
483 : 5 : CU_ASSERT(TAILQ_EMPTY(&g_request->children));
484 : :
485 : 5 : free(payload);
486 : 5 : nvme_free_request(g_request);
487 : 5 : cleanup_after_test(&qpair);
488 : 5 : }
489 : :
490 : : static void
491 : 5 : test_cmd_child_request(void)
492 : : {
493 : :
494 : 4 : struct spdk_nvme_ns ns;
495 : 4 : struct spdk_nvme_ctrlr ctrlr;
496 : 4 : struct spdk_nvme_qpair qpair;
497 : 5 : int rc = 0;
498 : : struct nvme_request *child, *tmp;
499 : : void *payload;
500 : 5 : uint64_t lba = 0x1000;
501 : 5 : uint32_t i = 0;
502 : 5 : uint32_t offset = 0;
503 : 5 : uint32_t sector_size = 512;
504 : 5 : uint32_t max_io_size = 128 * 1024;
505 [ - + ]: 5 : uint32_t sectors_per_max_io = max_io_size / sector_size;
506 : :
507 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, max_io_size, 0, false);
508 : :
509 : 5 : payload = malloc(128 * 1024);
510 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, sectors_per_max_io, NULL, NULL, 0);
511 : 5 : CU_ASSERT(rc == 0);
512 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
513 : 5 : CU_ASSERT(g_request->payload_offset == 0);
514 : 5 : CU_ASSERT(g_request->num_children == 0);
515 : 5 : nvme_free_request(g_request);
516 : :
517 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, sectors_per_max_io - 1, NULL, NULL, 0);
518 : 5 : CU_ASSERT(rc == 0);
519 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
520 : 5 : CU_ASSERT(g_request->payload_offset == 0);
521 : 5 : CU_ASSERT(g_request->num_children == 0);
522 : 5 : nvme_free_request(g_request);
523 : :
524 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, sectors_per_max_io * 4, NULL, NULL, 0);
525 : 5 : CU_ASSERT(rc == 0);
526 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
527 : 5 : CU_ASSERT(g_request->num_children == 4);
528 : :
529 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, (DEFAULT_IO_QUEUE_REQUESTS + 1) * sector_size,
530 : : NULL,
531 : : NULL, 0);
532 : 5 : CU_ASSERT(rc == -EINVAL);
533 : :
534 [ + + ]: 25 : TAILQ_FOREACH_SAFE(child, &g_request->children, child_tailq, tmp) {
535 : 20 : nvme_request_remove_child(g_request, child);
536 : 20 : CU_ASSERT(child->payload_offset == offset);
537 : 20 : CU_ASSERT(child->cmd.opc == SPDK_NVME_OPC_READ);
538 : 20 : CU_ASSERT(child->cmd.nsid == ns.id);
539 : 20 : CU_ASSERT(child->cmd.cdw10 == (lba + sectors_per_max_io * i));
540 : 20 : CU_ASSERT(child->cmd.cdw12 == ((sectors_per_max_io - 1) | 0));
541 : 20 : offset += max_io_size;
542 : 20 : nvme_free_request(child);
543 : 20 : i++;
544 : : }
545 : :
546 : 5 : free(payload);
547 : 5 : nvme_free_request(g_request);
548 : 5 : cleanup_after_test(&qpair);
549 : 5 : }
550 : :
551 : : static void
552 : 5 : test_nvme_ns_cmd_flush(void)
553 : : {
554 : 4 : struct spdk_nvme_ns ns;
555 : 4 : struct spdk_nvme_ctrlr ctrlr;
556 : 4 : struct spdk_nvme_qpair qpair;
557 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
558 : 5 : void *cb_arg = NULL;
559 : : int rc;
560 : :
561 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
562 : :
563 : 5 : rc = spdk_nvme_ns_cmd_flush(&ns, &qpair, cb_fn, cb_arg);
564 : 5 : CU_ASSERT(rc == 0);
565 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
566 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_FLUSH);
567 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
568 : :
569 : 5 : nvme_free_request(g_request);
570 : 5 : cleanup_after_test(&qpair);
571 : 5 : }
572 : :
573 : : static void
574 : 5 : test_nvme_ns_cmd_write_zeroes(void)
575 : : {
576 : 5 : struct spdk_nvme_ns ns = { 0 };
577 : 5 : struct spdk_nvme_ctrlr ctrlr = {{0}};
578 : 4 : struct spdk_nvme_qpair qpair;
579 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
580 : 5 : void *cb_arg = NULL;
581 : 4 : uint64_t cmd_lba;
582 : 4 : uint32_t cmd_lba_count;
583 : : int rc;
584 : :
585 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
586 : :
587 : 5 : rc = spdk_nvme_ns_cmd_write_zeroes(&ns, &qpair, 0, 2, cb_fn, cb_arg, 0);
588 : 5 : CU_ASSERT(rc == 0);
589 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
590 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE_ZEROES);
591 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
592 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
593 : 5 : CU_ASSERT_EQUAL(cmd_lba, 0);
594 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, 2);
595 : :
596 : 5 : nvme_free_request(g_request);
597 : 5 : cleanup_after_test(&qpair);
598 : 5 : }
599 : :
600 : : static void
601 : 5 : test_nvme_ns_cmd_write_uncorrectable(void)
602 : : {
603 : 5 : struct spdk_nvme_ns ns = { 0 };
604 : 5 : struct spdk_nvme_ctrlr ctrlr = {{0}};
605 : 4 : struct spdk_nvme_qpair qpair;
606 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
607 : 5 : void *cb_arg = NULL;
608 : 4 : uint64_t cmd_lba;
609 : 4 : uint32_t cmd_lba_count;
610 : : int rc;
611 : :
612 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
613 : :
614 : 5 : rc = spdk_nvme_ns_cmd_write_uncorrectable(&ns, &qpair, 0, 2, cb_fn, cb_arg);
615 : 5 : CU_ASSERT(rc == 0);
616 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
617 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE_UNCORRECTABLE);
618 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
619 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
620 : 5 : CU_ASSERT_EQUAL(cmd_lba, 0);
621 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, 2);
622 : :
623 : 5 : nvme_free_request(g_request);
624 : 5 : cleanup_after_test(&qpair);
625 : 5 : }
626 : :
627 : : static void
628 : 5 : test_nvme_ns_cmd_dataset_management(void)
629 : : {
630 : 4 : struct spdk_nvme_ns ns;
631 : 4 : struct spdk_nvme_ctrlr ctrlr;
632 : 4 : struct spdk_nvme_qpair qpair;
633 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
634 : 5 : void *cb_arg = NULL;
635 : 4 : struct spdk_nvme_dsm_range ranges[256];
636 : : uint16_t i;
637 : 5 : int rc = 0;
638 : :
639 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
640 : :
641 [ + + ]: 1285 : for (i = 0; i < 256; i++) {
642 : 1280 : ranges[i].starting_lba = i;
643 : 1280 : ranges[i].length = 1;
644 : 1280 : ranges[i].attributes.raw = 0;
645 : : }
646 : :
647 : : /* TRIM one LBA */
648 : 5 : rc = spdk_nvme_ns_cmd_dataset_management(&ns, &qpair, SPDK_NVME_DSM_ATTR_DEALLOCATE,
649 : : ranges, 1, cb_fn, cb_arg);
650 : 5 : CU_ASSERT(rc == 0);
651 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
652 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_DATASET_MANAGEMENT);
653 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
654 : 5 : CU_ASSERT(g_request->cmd.cdw10 == 0);
655 : 5 : CU_ASSERT(g_request->cmd.cdw11_bits.dsm.ad == 1);
656 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
657 : 5 : nvme_free_request(g_request);
658 : :
659 : : /* TRIM 256 LBAs */
660 : 5 : rc = spdk_nvme_ns_cmd_dataset_management(&ns, &qpair, SPDK_NVME_DSM_ATTR_DEALLOCATE,
661 : : ranges, 256, cb_fn, cb_arg);
662 : 5 : CU_ASSERT(rc == 0);
663 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
664 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_DATASET_MANAGEMENT);
665 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
666 : 5 : CU_ASSERT(g_request->cmd.cdw10 == 255u);
667 : 5 : CU_ASSERT(g_request->cmd.cdw11_bits.dsm.ad == 1);
668 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
669 : 5 : nvme_free_request(g_request);
670 : :
671 : 5 : rc = spdk_nvme_ns_cmd_dataset_management(&ns, &qpair, SPDK_NVME_DSM_ATTR_DEALLOCATE,
672 : : NULL, 0, cb_fn, cb_arg);
673 : 5 : CU_ASSERT(rc != 0);
674 : 5 : cleanup_after_test(&qpair);
675 : 5 : }
676 : :
677 : : static void
678 : 5 : test_nvme_ns_cmd_copy(void)
679 : : {
680 : 4 : struct spdk_nvme_ns ns;
681 : 4 : struct spdk_nvme_ctrlr ctrlr;
682 : 4 : struct spdk_nvme_qpair qpair;
683 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
684 : 5 : void *cb_arg = NULL;
685 : : uint16_t i;
686 : 5 : int rc = 0;
687 : 4 : uint64_t cmd_dest_lba;
688 : 4 : uint32_t cmd_range_count;
689 : 4 : struct spdk_nvme_scc_source_range ranges[64];
690 : :
691 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
692 : :
693 [ + + ]: 325 : for (i = 0; i < 64; i++) {
694 : 320 : ranges[i].slba = i;
695 : 320 : ranges[i].nlb = 1;
696 : : }
697 : :
698 : : /* COPY one LBA */
699 : 5 : rc = spdk_nvme_ns_cmd_copy(&ns, &qpair, ranges,
700 : : 1, 64, cb_fn, cb_arg);
701 : 5 : CU_ASSERT(rc == 0);
702 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
703 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_COPY);
704 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
705 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_dest_lba, &cmd_range_count);
706 : 5 : CU_ASSERT_EQUAL(cmd_dest_lba, 64);
707 : 5 : CU_ASSERT_EQUAL(cmd_range_count, 1);
708 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
709 : 5 : nvme_free_request(g_request);
710 : :
711 : : /* COPY 64 LBAs */
712 : 5 : rc = spdk_nvme_ns_cmd_copy(&ns, &qpair, ranges,
713 : : 64, 64, cb_fn, cb_arg);
714 : 5 : CU_ASSERT(rc == 0);
715 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
716 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_COPY);
717 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
718 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_dest_lba, &cmd_range_count);
719 : 5 : CU_ASSERT_EQUAL(cmd_dest_lba, 64);
720 : 5 : CU_ASSERT_EQUAL(cmd_range_count, 64);
721 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
722 : 5 : nvme_free_request(g_request);
723 : :
724 : 5 : rc = spdk_nvme_ns_cmd_copy(&ns, &qpair, ranges,
725 : : 0, 64, cb_fn, cb_arg);
726 : 5 : CU_ASSERT(rc != 0);
727 : 5 : cleanup_after_test(&qpair);
728 : 5 : }
729 : :
730 : : static void
731 : 5 : test_nvme_ns_cmd_readv(void)
732 : : {
733 : 4 : struct spdk_nvme_ns ns;
734 : 4 : struct spdk_nvme_ctrlr ctrlr;
735 : 4 : struct spdk_nvme_qpair qpair;
736 : 5 : int rc = 0;
737 : : void *cb_arg;
738 : 5 : uint32_t lba_count = 256;
739 : 5 : uint32_t sector_size = 512;
740 : 5 : uint64_t sge_length = lba_count * sector_size;
741 : :
742 : 5 : cb_arg = malloc(512);
743 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, 128 * 1024, 0, false);
744 : 5 : rc = spdk_nvme_ns_cmd_readv(&ns, &qpair, 0x1000, lba_count, NULL, &sge_length, 0,
745 : : nvme_request_reset_sgl, nvme_request_next_sge);
746 : :
747 : 5 : CU_ASSERT(rc == 0);
748 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
749 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_READ);
750 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
751 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
752 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
753 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
754 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
755 : :
756 : 5 : rc = spdk_nvme_ns_cmd_readv(&ns, &qpair, 0x1000, 256, NULL, cb_arg, 0, nvme_request_reset_sgl,
757 : : NULL);
758 : 5 : CU_ASSERT(rc != 0);
759 : :
760 : 5 : free(cb_arg);
761 : 5 : nvme_free_request(g_request);
762 : 5 : cleanup_after_test(&qpair);
763 : 5 : }
764 : :
765 : : static int
766 : 20 : nvme_request_next_sge_invalid_prp1(void *cb_arg, void **address, uint32_t *length)
767 : : {
768 : 20 : struct nvme_ns_cmd_ut_cb_arg *iovs = cb_arg;
769 : :
770 : 20 : CU_ASSERT(iovs->iovpos < UT_MAX_IOVS);
771 : 20 : *address = iovs->iovs[iovs->iovpos].iov_base;
772 : 20 : *length = iovs->iovs[iovs->iovpos].iov_len;
773 : 20 : iovs->iovpos++;
774 : :
775 : 20 : return 0;
776 : : }
777 : :
778 : : static void
779 : 5 : test_nvme_ns_cmd_writev(void)
780 : : {
781 : 4 : struct spdk_nvme_ns ns;
782 : 4 : struct spdk_nvme_ctrlr ctrlr;
783 : 4 : struct spdk_nvme_qpair qpair;
784 : 5 : struct nvme_ns_cmd_ut_cb_arg iovs_cb_arg = {
785 : : .iovs = {
786 : : {.iov_base = (void *)(uintptr_t)0x3E8000, .iov_len = 200},
787 : : {.iov_base = (void *)(uintptr_t)0x3E9000, .iov_len = 312}
788 : : },
789 : : };
790 : 5 : int rc = 0;
791 : 5 : uint32_t lba_count = 256;
792 : 5 : uint32_t sector_size = 512;
793 : 5 : uint64_t sge_length = lba_count * sector_size;
794 : :
795 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, 128 * 1024, 0, false);
796 : 5 : rc = spdk_nvme_ns_cmd_writev(&ns, &qpair, 0x1000, lba_count, NULL, &sge_length, 0,
797 : : nvme_request_reset_sgl, nvme_request_next_sge);
798 : :
799 : 5 : CU_ASSERT(rc == 0);
800 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
801 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE);
802 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
803 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
804 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
805 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
806 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
807 : :
808 : : /* Test case: NULL reset_sgl callback, expect fail */
809 : 5 : rc = spdk_nvme_ns_cmd_writev(&ns, &qpair, 0x1000, 256, NULL, &sge_length, 0,
810 : : NULL, nvme_request_next_sge);
811 : 5 : CU_ASSERT(rc == -EINVAL);
812 : :
813 : : /* PRP1 start address is page aligned while end address is not. NVME driver
814 : : * tries to split such a request but iov[0] length is not multiple of block size.
815 : : * Expect fail */
816 : 5 : rc = spdk_nvme_ns_cmd_writev(&ns, &qpair, 0x1000, 1, NULL, &iovs_cb_arg, 0,
817 : : nvme_request_reset_sgl, nvme_request_next_sge_invalid_prp1);
818 : 5 : CU_ASSERT(rc == -EINVAL);
819 : :
820 : : /* PRP1 end address is page aligned while start address is not. Expect pass */
821 : 5 : iovs_cb_arg.iovs[0].iov_base = (void *)(((uintptr_t)iovs_cb_arg.iovs[0].iov_base) + ctrlr.page_size
822 : 5 : - iovs_cb_arg.iovs[0].iov_len);
823 : 5 : iovs_cb_arg.iovpos = 0;
824 : 5 : rc = spdk_nvme_ns_cmd_writev(&ns, &qpair, 0x1000, 1, NULL, &iovs_cb_arg, 0,
825 : : nvme_request_reset_sgl, nvme_request_next_sge_invalid_prp1);
826 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE);
827 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
828 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
829 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge_invalid_prp1);
830 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &iovs_cb_arg);
831 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
832 : :
833 : 5 : nvme_free_request(g_request);
834 : 5 : cleanup_after_test(&qpair);
835 : 5 : }
836 : :
837 : : static void
838 : 5 : test_nvme_ns_cmd_comparev(void)
839 : : {
840 : 4 : struct spdk_nvme_ns ns;
841 : 4 : struct spdk_nvme_ctrlr ctrlr;
842 : 4 : struct spdk_nvme_qpair qpair;
843 : 5 : int rc = 0;
844 : : void *cb_arg;
845 : 5 : uint32_t lba_count = 256;
846 : 5 : uint32_t sector_size = 512;
847 : 5 : uint64_t sge_length = lba_count * sector_size;
848 : :
849 : 5 : cb_arg = malloc(512);
850 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, 128 * 1024, 0, false);
851 : 5 : rc = spdk_nvme_ns_cmd_comparev(&ns, &qpair, 0x1000, lba_count, NULL, &sge_length, 0,
852 : : nvme_request_reset_sgl, nvme_request_next_sge);
853 : :
854 : 5 : CU_ASSERT(rc == 0);
855 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
856 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_COMPARE);
857 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
858 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
859 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
860 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
861 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
862 : :
863 : 5 : rc = spdk_nvme_ns_cmd_comparev(&ns, &qpair, 0x1000, 256, NULL, cb_arg, 0,
864 : : nvme_request_reset_sgl, NULL);
865 : 5 : CU_ASSERT(rc != 0);
866 : :
867 : 5 : free(cb_arg);
868 : 5 : nvme_free_request(g_request);
869 : 5 : cleanup_after_test(&qpair);
870 : 5 : }
871 : :
872 : : static void
873 : 5 : test_nvme_ns_cmd_comparev_with_md(void)
874 : : {
875 : 4 : struct spdk_nvme_ns ns;
876 : 4 : struct spdk_nvme_ctrlr ctrlr;
877 : 4 : struct spdk_nvme_qpair qpair;
878 : 5 : int rc = 0;
879 : 5 : char *buffer = NULL;
880 : 5 : char *metadata = NULL;
881 : : uint32_t block_size, md_size;
882 : : struct nvme_request *child0, *child1;
883 : 5 : uint32_t lba_count = 256;
884 : 5 : uint32_t sector_size = 512;
885 : 5 : uint64_t sge_length = lba_count * sector_size;
886 : :
887 : 5 : block_size = 512;
888 : 5 : md_size = 128;
889 : :
890 : 5 : buffer = malloc((block_size + md_size) * 384);
891 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(buffer != NULL);
892 : 5 : metadata = malloc(md_size * 384);
893 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
894 : :
895 : : /*
896 : : * 512 byte data + 128 byte metadata
897 : : * Separate metadata buffer
898 : : * Max data transfer size 128 KB
899 : : * No stripe size
900 : : *
901 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
902 : : */
903 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, false);
904 : :
905 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 256, NULL, &sge_length, 0,
906 : : nvme_request_reset_sgl, nvme_request_next_sge, metadata, 0, 0);
907 : :
908 : 5 : CU_ASSERT(rc == 0);
909 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
910 : 5 : CU_ASSERT(g_request->num_children == 0);
911 : :
912 : 5 : CU_ASSERT(g_request->payload.md == metadata);
913 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
914 : :
915 : 5 : nvme_free_request(g_request);
916 : 5 : cleanup_after_test(&qpair);
917 : :
918 : : /*
919 : : * 512 byte data + 128 byte metadata
920 : : * Extended LBA
921 : : * Max data transfer size 128 KB
922 : : * No stripe size
923 : : *
924 : : * 256 blocks * (512 + 128) bytes per block = two I/Os:
925 : : * child 0: 204 blocks - 204 * (512 + 128) = 127.5 KB
926 : : * child 1: 52 blocks
927 : : */
928 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, true);
929 : :
930 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 256, NULL, &sge_length, 0,
931 : : nvme_request_reset_sgl, nvme_request_next_sge, NULL, 0, 0);
932 : :
933 : 5 : CU_ASSERT(rc == 0);
934 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
935 : 5 : CU_ASSERT(g_request->num_children == 2);
936 : 5 : child0 = TAILQ_FIRST(&g_request->children);
937 : :
938 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
939 : 5 : CU_ASSERT(child0->payload.md == NULL);
940 : 5 : CU_ASSERT(child0->payload_offset == 0);
941 : 5 : CU_ASSERT(child0->payload_size == 204 * (512 + 128));
942 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
943 : :
944 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
945 : 5 : CU_ASSERT(child1->payload.md == NULL);
946 : 5 : CU_ASSERT(child1->payload_offset == 204 * (512 + 128));
947 : 5 : CU_ASSERT(child1->payload_size == 52 * (512 + 128));
948 : :
949 : 5 : nvme_request_free_children(g_request);
950 : 5 : nvme_free_request(g_request);
951 : 5 : cleanup_after_test(&qpair);
952 : :
953 : : /*
954 : : * 512 byte data + 8 byte metadata
955 : : * Extended LBA
956 : : * Max data transfer size 128 KB
957 : : * No stripe size
958 : : * No protection information
959 : : *
960 : : * 256 blocks * (512 + 8) bytes per block = two I/Os:
961 : : * child 0: 252 blocks - 252 * (512 + 8) = 127.96875 KB
962 : : * child 1: 4 blocks
963 : : */
964 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
965 : :
966 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 256, NULL, &sge_length, 0,
967 : : nvme_request_reset_sgl, nvme_request_next_sge, NULL, 0, 0);
968 : :
969 : 5 : CU_ASSERT(rc == 0);
970 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
971 : 5 : CU_ASSERT(g_request->num_children == 2);
972 : 5 : child0 = TAILQ_FIRST(&g_request->children);
973 : :
974 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
975 : 5 : CU_ASSERT(child0->payload.md == NULL);
976 : 5 : CU_ASSERT(child0->payload_offset == 0);
977 : 5 : CU_ASSERT(child0->payload_size == 252 * (512 + 8));
978 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
979 : :
980 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
981 : 5 : CU_ASSERT(child1->payload.md == NULL);
982 : 5 : CU_ASSERT(child1->payload_offset == 252 * (512 + 8));
983 : 5 : CU_ASSERT(child1->payload_size == 4 * (512 + 8));
984 : :
985 : 5 : nvme_request_free_children(g_request);
986 : 5 : nvme_free_request(g_request);
987 : 5 : cleanup_after_test(&qpair);
988 : :
989 : : /*
990 : : * 512 byte data + 8 byte metadata
991 : : * Extended LBA
992 : : * Max data transfer size 128 KB
993 : : * No stripe size
994 : : * Protection information enabled + PRACT
995 : : *
996 : : * Special case for 8-byte metadata + PI + PRACT: no metadata transferred
997 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
998 : : */
999 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
1000 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1001 : :
1002 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 256, NULL, &sge_length,
1003 : : SPDK_NVME_IO_FLAGS_PRACT, nvme_request_reset_sgl, nvme_request_next_sge, NULL, 0, 0);
1004 : :
1005 : 5 : CU_ASSERT(rc == 0);
1006 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1007 : 5 : CU_ASSERT(g_request->num_children == 0);
1008 : :
1009 : 5 : CU_ASSERT(g_request->payload.md == NULL);
1010 : 5 : CU_ASSERT(g_request->payload_offset == 0);
1011 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512); /* NOTE: does not include metadata! */
1012 : :
1013 : 5 : nvme_request_free_children(g_request);
1014 : 5 : nvme_free_request(g_request);
1015 : 5 : cleanup_after_test(&qpair);
1016 : :
1017 : : /*
1018 : : * 512 byte data + 8 byte metadata
1019 : : * Separate metadata buffer
1020 : : * Max data transfer size 128 KB
1021 : : * No stripe size
1022 : : * Protection information enabled + PRACT
1023 : : */
1024 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1025 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1026 : :
1027 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 256, NULL, &sge_length,
1028 : : SPDK_NVME_IO_FLAGS_PRACT, nvme_request_reset_sgl, nvme_request_next_sge, metadata, 0, 0);
1029 : :
1030 : 5 : CU_ASSERT(rc == 0);
1031 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1032 : 5 : CU_ASSERT(g_request->num_children == 0);
1033 : :
1034 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1035 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1036 : :
1037 : 5 : nvme_free_request(g_request);
1038 : 5 : cleanup_after_test(&qpair);
1039 : :
1040 : : /*
1041 : : * 512 byte data + 8 byte metadata
1042 : : * Separate metadata buffer
1043 : : * Max data transfer size 128 KB
1044 : : * No stripe size
1045 : : * Protection information enabled + PRACT
1046 : : *
1047 : : * 384 blocks * 512 bytes = two I/Os:
1048 : : * child 0: 256 blocks
1049 : : * child 1: 128 blocks
1050 : : */
1051 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1052 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1053 : :
1054 : 5 : rc = spdk_nvme_ns_cmd_comparev_with_md(&ns, &qpair, 0x1000, 384, NULL, &sge_length,
1055 : : SPDK_NVME_IO_FLAGS_PRACT, nvme_request_reset_sgl, nvme_request_next_sge, metadata, 0, 0);
1056 : :
1057 : 5 : CU_ASSERT(rc == 0);
1058 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1059 : 5 : CU_ASSERT(g_request->num_children == 2);
1060 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1061 : :
1062 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1063 : 5 : CU_ASSERT(child0->payload_offset == 0);
1064 : 5 : CU_ASSERT(child0->payload_size == 256 * 512);
1065 : 5 : CU_ASSERT(child0->md_offset == 0);
1066 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1067 : :
1068 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1069 : 5 : CU_ASSERT(child1->payload_offset == 256 * 512);
1070 : 5 : CU_ASSERT(child1->payload_size == 128 * 512);
1071 : 5 : CU_ASSERT(child1->md_offset == 256 * 8);
1072 : :
1073 : 5 : nvme_request_free_children(g_request);
1074 : 5 : nvme_free_request(g_request);
1075 : 5 : cleanup_after_test(&qpair);
1076 : :
1077 : 5 : free(buffer);
1078 : 5 : free(metadata);
1079 : 5 : }
1080 : :
1081 : : static void
1082 : 5 : test_nvme_ns_cmd_compare_and_write(void)
1083 : : {
1084 : 4 : struct spdk_nvme_ns ns;
1085 : 4 : struct spdk_nvme_ctrlr ctrlr;
1086 : 4 : struct spdk_nvme_qpair qpair;
1087 : 5 : int rc = 0;
1088 : 5 : uint64_t lba = 0x1000;
1089 : 5 : uint32_t lba_count = 256;
1090 : 4 : uint64_t cmd_lba;
1091 : 4 : uint32_t cmd_lba_count;
1092 : 5 : uint32_t sector_size = 512;
1093 : :
1094 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, 128 * 1024, 0, false);
1095 : :
1096 : 5 : rc = spdk_nvme_ns_cmd_compare(&ns, &qpair, NULL, lba, lba_count, NULL, NULL,
1097 : : SPDK_NVME_IO_FLAGS_FUSE_FIRST);
1098 : :
1099 : 5 : CU_ASSERT(rc == 0);
1100 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1101 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_COMPARE);
1102 : 5 : CU_ASSERT(g_request->cmd.fuse == SPDK_NVME_CMD_FUSE_FIRST);
1103 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1104 : :
1105 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
1106 : 5 : CU_ASSERT_EQUAL(cmd_lba, lba);
1107 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
1108 : :
1109 : 5 : nvme_free_request(g_request);
1110 : :
1111 : 5 : rc = spdk_nvme_ns_cmd_write(&ns, &qpair, NULL, lba, lba_count, NULL, NULL,
1112 : : SPDK_NVME_IO_FLAGS_FUSE_SECOND);
1113 : :
1114 : 5 : CU_ASSERT(rc == 0);
1115 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1116 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE);
1117 : 5 : CU_ASSERT(g_request->cmd.fuse == SPDK_NVME_CMD_FUSE_SECOND);
1118 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1119 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
1120 : 5 : CU_ASSERT_EQUAL(cmd_lba, lba);
1121 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
1122 : :
1123 : 5 : nvme_free_request(g_request);
1124 : :
1125 : 5 : cleanup_after_test(&qpair);
1126 : 5 : }
1127 : :
1128 : : static void
1129 : 5 : test_io_flags(void)
1130 : : {
1131 : 4 : struct spdk_nvme_ns ns;
1132 : 4 : struct spdk_nvme_ctrlr ctrlr;
1133 : 4 : struct spdk_nvme_qpair qpair;
1134 : : void *payload;
1135 : : uint64_t lba;
1136 : : uint32_t lba_count;
1137 : 4 : uint64_t cmd_lba;
1138 : 4 : uint32_t cmd_lba_count;
1139 : : int rc;
1140 : :
1141 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 128 * 1024, false);
1142 : 5 : payload = malloc(256 * 1024);
1143 : 5 : lba = 0;
1144 : 5 : lba_count = (4 * 1024) / 512;
1145 : :
1146 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
1147 : : SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS);
1148 : 5 : CU_ASSERT(rc == 0);
1149 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1150 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS) != 0);
1151 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) == 0);
1152 : 5 : nvme_free_request(g_request);
1153 : :
1154 : 5 : rc = spdk_nvme_ns_cmd_read(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
1155 : : SPDK_NVME_IO_FLAGS_LIMITED_RETRY);
1156 : 5 : CU_ASSERT(rc == 0);
1157 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1158 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS) == 0);
1159 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) != 0);
1160 : 5 : nvme_free_request(g_request);
1161 : :
1162 : 5 : rc = spdk_nvme_ns_cmd_write(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
1163 : : SPDK_NVME_IO_FLAGS_VALID_MASK);
1164 : 5 : CU_ASSERT(rc == 0);
1165 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1166 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
1167 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
1168 : 5 : CU_ASSERT_EQUAL(cmd_lba, lba);
1169 : 5 : CU_ASSERT_EQUAL(g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_CDW12_MASK,
1170 : : SPDK_NVME_IO_FLAGS_CDW12_MASK);
1171 : 5 : nvme_free_request(g_request);
1172 : :
1173 : 5 : rc = spdk_nvme_ns_cmd_write(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
1174 : : ~SPDK_NVME_IO_FLAGS_VALID_MASK);
1175 : 5 : CU_ASSERT(rc == -EINVAL);
1176 : :
1177 : 5 : free(payload);
1178 : 5 : cleanup_after_test(&qpair);
1179 : 5 : }
1180 : :
1181 : : static void
1182 : 5 : test_nvme_ns_cmd_reservation_register(void)
1183 : : {
1184 : 4 : struct spdk_nvme_ns ns;
1185 : 4 : struct spdk_nvme_ctrlr ctrlr;
1186 : 4 : struct spdk_nvme_qpair qpair;
1187 : : struct spdk_nvme_reservation_register_data *payload;
1188 : 5 : bool ignore_key = 1;
1189 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
1190 : 5 : void *cb_arg = NULL;
1191 : 5 : int rc = 0;
1192 : : uint32_t tmp_cdw10;
1193 : :
1194 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
1195 : 5 : payload = malloc(sizeof(struct spdk_nvme_reservation_register_data));
1196 : :
1197 : 5 : rc = spdk_nvme_ns_cmd_reservation_register(&ns, &qpair, payload, ignore_key,
1198 : : SPDK_NVME_RESERVE_REGISTER_KEY,
1199 : : SPDK_NVME_RESERVE_PTPL_NO_CHANGES,
1200 : : cb_fn, cb_arg);
1201 : :
1202 : 5 : CU_ASSERT(rc == 0);
1203 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1204 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_RESERVATION_REGISTER);
1205 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1206 : :
1207 : 5 : tmp_cdw10 = SPDK_NVME_RESERVE_REGISTER_KEY;
1208 [ + - ]: 5 : tmp_cdw10 |= ignore_key ? 1 << 3 : 0;
1209 : 5 : tmp_cdw10 |= (uint32_t)SPDK_NVME_RESERVE_PTPL_NO_CHANGES << 30;
1210 : :
1211 : 5 : CU_ASSERT(g_request->cmd.cdw10 == tmp_cdw10);
1212 : :
1213 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
1214 : 5 : nvme_free_request(g_request);
1215 : 5 : free(payload);
1216 : 5 : cleanup_after_test(&qpair);
1217 : 5 : }
1218 : :
1219 : : static void
1220 : 5 : test_nvme_ns_cmd_reservation_release(void)
1221 : : {
1222 : 4 : struct spdk_nvme_ns ns;
1223 : 4 : struct spdk_nvme_ctrlr ctrlr;
1224 : 4 : struct spdk_nvme_qpair qpair;
1225 : : struct spdk_nvme_reservation_key_data *payload;
1226 : 5 : bool ignore_key = 1;
1227 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
1228 : 5 : void *cb_arg = NULL;
1229 : 5 : int rc = 0;
1230 : : uint32_t tmp_cdw10;
1231 : :
1232 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
1233 : 5 : payload = malloc(sizeof(struct spdk_nvme_reservation_key_data));
1234 : :
1235 : 5 : rc = spdk_nvme_ns_cmd_reservation_release(&ns, &qpair, payload, ignore_key,
1236 : : SPDK_NVME_RESERVE_RELEASE,
1237 : : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE,
1238 : : cb_fn, cb_arg);
1239 : :
1240 : 5 : CU_ASSERT(rc == 0);
1241 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1242 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_RESERVATION_RELEASE);
1243 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1244 : :
1245 : 5 : tmp_cdw10 = SPDK_NVME_RESERVE_RELEASE;
1246 [ + - ]: 5 : tmp_cdw10 |= ignore_key ? 1 << 3 : 0;
1247 : 5 : tmp_cdw10 |= (uint32_t)SPDK_NVME_RESERVE_WRITE_EXCLUSIVE << 8;
1248 : :
1249 : 5 : CU_ASSERT(g_request->cmd.cdw10 == tmp_cdw10);
1250 : :
1251 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
1252 : 5 : nvme_free_request(g_request);
1253 : 5 : free(payload);
1254 : 5 : cleanup_after_test(&qpair);
1255 : 5 : }
1256 : :
1257 : : static void
1258 : 5 : test_nvme_ns_cmd_reservation_acquire(void)
1259 : : {
1260 : 4 : struct spdk_nvme_ns ns;
1261 : 4 : struct spdk_nvme_ctrlr ctrlr;
1262 : 4 : struct spdk_nvme_qpair qpair;
1263 : : struct spdk_nvme_reservation_acquire_data *payload;
1264 : 5 : bool ignore_key = 1;
1265 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
1266 : 5 : void *cb_arg = NULL;
1267 : 5 : int rc = 0;
1268 : : uint32_t tmp_cdw10;
1269 : :
1270 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
1271 : 5 : payload = malloc(sizeof(struct spdk_nvme_reservation_acquire_data));
1272 : :
1273 : 5 : rc = spdk_nvme_ns_cmd_reservation_acquire(&ns, &qpair, payload, ignore_key,
1274 : : SPDK_NVME_RESERVE_ACQUIRE,
1275 : : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE,
1276 : : cb_fn, cb_arg);
1277 : :
1278 : 5 : CU_ASSERT(rc == 0);
1279 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1280 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_RESERVATION_ACQUIRE);
1281 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1282 : :
1283 : 5 : tmp_cdw10 = SPDK_NVME_RESERVE_ACQUIRE;
1284 [ + - ]: 5 : tmp_cdw10 |= ignore_key ? 1 << 3 : 0;
1285 : 5 : tmp_cdw10 |= (uint32_t)SPDK_NVME_RESERVE_WRITE_EXCLUSIVE << 8;
1286 : :
1287 : 5 : CU_ASSERT(g_request->cmd.cdw10 == tmp_cdw10);
1288 : :
1289 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
1290 : 5 : nvme_free_request(g_request);
1291 : 5 : free(payload);
1292 : 5 : cleanup_after_test(&qpair);
1293 : 5 : }
1294 : :
1295 : : static void
1296 : 5 : test_nvme_ns_cmd_reservation_report(void)
1297 : : {
1298 : 4 : struct spdk_nvme_ns ns;
1299 : 4 : struct spdk_nvme_ctrlr ctrlr;
1300 : 4 : struct spdk_nvme_qpair qpair;
1301 : : struct spdk_nvme_reservation_status_data *payload;
1302 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
1303 : 5 : void *cb_arg = NULL;
1304 : 5 : int rc = 0;
1305 : 5 : uint32_t size = sizeof(struct spdk_nvme_reservation_status_data);
1306 : :
1307 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
1308 : :
1309 : 5 : payload = calloc(1, size);
1310 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(payload != NULL);
1311 : :
1312 : 5 : rc = spdk_nvme_ns_cmd_reservation_report(&ns, &qpair, payload, size, cb_fn, cb_arg);
1313 : :
1314 : 5 : CU_ASSERT(rc == 0);
1315 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1316 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_RESERVATION_REPORT);
1317 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1318 : :
1319 : 5 : CU_ASSERT(g_request->cmd.cdw10 == (size >> 2) - 1);
1320 : :
1321 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
1322 : 5 : nvme_free_request(g_request);
1323 : 5 : free(payload);
1324 : 5 : cleanup_after_test(&qpair);
1325 : 5 : }
1326 : :
1327 : : static void
1328 : 5 : test_nvme_ns_cmd_write_with_md(void)
1329 : : {
1330 : 4 : struct spdk_nvme_ns ns;
1331 : 4 : struct spdk_nvme_ctrlr ctrlr;
1332 : 4 : struct spdk_nvme_qpair qpair;
1333 : 5 : int rc = 0;
1334 : 5 : char *buffer = NULL;
1335 : 5 : char *metadata = NULL;
1336 : : uint32_t block_size, md_size;
1337 : : struct nvme_request *child0, *child1;
1338 : :
1339 : 5 : block_size = 512;
1340 : 5 : md_size = 128;
1341 : :
1342 : 5 : buffer = malloc((block_size + md_size) * 384);
1343 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(buffer != NULL);
1344 : 5 : metadata = malloc(md_size * 384);
1345 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
1346 : :
1347 : : /*
1348 : : * 512 byte data + 128 byte metadata
1349 : : * Separate metadata buffer
1350 : : * Max data transfer size 128 KB
1351 : : * No stripe size
1352 : : *
1353 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1354 : : */
1355 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, false);
1356 : :
1357 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, metadata, 0x1000, 256, NULL, NULL, 0, 0,
1358 : : 0);
1359 : :
1360 : 5 : CU_ASSERT(rc == 0);
1361 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1362 : 5 : CU_ASSERT(g_request->num_children == 0);
1363 : :
1364 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1365 : 5 : CU_ASSERT(g_request->md_size == 256 * 128);
1366 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1367 : :
1368 : 5 : nvme_free_request(g_request);
1369 : 5 : cleanup_after_test(&qpair);
1370 : :
1371 : : /*
1372 : : * 512 byte data + 128 byte metadata
1373 : : * Extended LBA
1374 : : * Max data transfer size 128 KB
1375 : : * No stripe size
1376 : : *
1377 : : * 256 blocks * (512 + 128) bytes per block = two I/Os:
1378 : : * child 0: 204 blocks - 204 * (512 + 128) = 127.5 KB
1379 : : * child 1: 52 blocks
1380 : : */
1381 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, true);
1382 : :
1383 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256, NULL, NULL, 0, 0,
1384 : : 0);
1385 : :
1386 : 5 : CU_ASSERT(rc == 0);
1387 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1388 : 5 : CU_ASSERT(g_request->num_children == 2);
1389 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1390 : :
1391 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1392 : 5 : CU_ASSERT(child0->payload.md == NULL);
1393 : 5 : CU_ASSERT(child0->payload_offset == 0);
1394 : 5 : CU_ASSERT(child0->payload_size == 204 * (512 + 128));
1395 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1396 : :
1397 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1398 : 5 : CU_ASSERT(child1->payload.md == NULL);
1399 : 5 : CU_ASSERT(child1->payload_offset == 204 * (512 + 128));
1400 : 5 : CU_ASSERT(child1->payload_size == 52 * (512 + 128));
1401 : :
1402 : 5 : nvme_request_free_children(g_request);
1403 : 5 : nvme_free_request(g_request);
1404 : 5 : cleanup_after_test(&qpair);
1405 : :
1406 : : /*
1407 : : * 512 byte data + 128 byte metadata
1408 : : * Extended LBA
1409 : : * Max data transfer size 128 KB
1410 : : * No stripe size
1411 : : * Enable NVME_QUIRK_MDTS_EXCLUDE_MD quirk
1412 : : *
1413 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1414 : : */
1415 : 5 : g_ctrlr_quirks = NVME_QUIRK_MDTS_EXCLUDE_MD;
1416 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, true);
1417 : :
1418 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256, NULL, NULL, 0, 0,
1419 : : 0);
1420 : :
1421 : 5 : CU_ASSERT(rc == 0);
1422 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1423 : 5 : CU_ASSERT(g_request->num_children == 0);
1424 : 5 : CU_ASSERT(g_request->md_size == 256 * 128);
1425 : 5 : CU_ASSERT(g_request->payload_size == 256 * (512 + 128));
1426 : :
1427 : 5 : nvme_free_request(g_request);
1428 : 5 : cleanup_after_test(&qpair);
1429 : :
1430 : : /*
1431 : : * 512 byte data + 8 byte metadata
1432 : : * Extended LBA
1433 : : * Max data transfer size 128 KB
1434 : : * No stripe size
1435 : : * No protection information
1436 : : *
1437 : : * 256 blocks * (512 + 8) bytes per block = two I/Os:
1438 : : * child 0: 252 blocks - 252 * (512 + 8) = 127.96875 KB
1439 : : * child 1: 4 blocks
1440 : : */
1441 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
1442 : :
1443 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256, NULL, NULL, 0, 0,
1444 : : 0);
1445 : :
1446 : 5 : CU_ASSERT(rc == 0);
1447 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1448 : 5 : CU_ASSERT(g_request->num_children == 2);
1449 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1450 : :
1451 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1452 : 5 : CU_ASSERT(child0->payload.md == NULL);
1453 : 5 : CU_ASSERT(child0->payload_offset == 0);
1454 : 5 : CU_ASSERT(child0->payload_size == 252 * (512 + 8));
1455 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1456 : :
1457 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1458 : 5 : CU_ASSERT(child1->payload.md == NULL);
1459 : 5 : CU_ASSERT(child1->payload_offset == 252 * (512 + 8));
1460 : 5 : CU_ASSERT(child1->payload_size == 4 * (512 + 8));
1461 : :
1462 : 5 : nvme_request_free_children(g_request);
1463 : 5 : nvme_free_request(g_request);
1464 : 5 : cleanup_after_test(&qpair);
1465 : :
1466 : : /*
1467 : : * 512 byte data + 8 byte metadata
1468 : : * Extended LBA
1469 : : * Max data transfer size 128 KB
1470 : : * No stripe size
1471 : : * Protection information enabled + PRACT
1472 : : *
1473 : : * Special case for 8-byte metadata + PI + PRACT: no metadata transferred
1474 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1475 : : */
1476 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
1477 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1478 : :
1479 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256, NULL, NULL,
1480 : : SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1481 : :
1482 : 5 : CU_ASSERT(rc == 0);
1483 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1484 : 5 : CU_ASSERT(g_request->num_children == 0);
1485 : :
1486 : 5 : CU_ASSERT(g_request->payload.md == NULL);
1487 : 5 : CU_ASSERT(g_request->payload_offset == 0);
1488 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512); /* NOTE: does not include metadata! */
1489 : :
1490 : 5 : nvme_request_free_children(g_request);
1491 : 5 : nvme_free_request(g_request);
1492 : 5 : cleanup_after_test(&qpair);
1493 : :
1494 : : /*
1495 : : * 512 byte data + 8 byte metadata
1496 : : * Separate metadata buffer
1497 : : * Max data transfer size 128 KB
1498 : : * No stripe size
1499 : : * Protection information enabled + PRACT
1500 : : */
1501 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1502 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1503 : :
1504 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, metadata, 0x1000, 256, NULL, NULL,
1505 : : SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1506 : :
1507 : 5 : CU_ASSERT(rc == 0);
1508 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1509 : 5 : CU_ASSERT(g_request->num_children == 0);
1510 : :
1511 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1512 : 5 : CU_ASSERT(g_request->md_size == 256 * 8);
1513 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1514 : :
1515 : 5 : nvme_free_request(g_request);
1516 : 5 : cleanup_after_test(&qpair);
1517 : :
1518 : : /*
1519 : : * 512 byte data + 8 byte metadata
1520 : : * Separate metadata buffer
1521 : : * Max data transfer size 128 KB
1522 : : * No stripe size
1523 : : * Protection information enabled + PRACT
1524 : : *
1525 : : * 384 blocks * 512 bytes = two I/Os:
1526 : : * child 0: 256 blocks
1527 : : * child 1: 128 blocks
1528 : : */
1529 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1530 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1531 : :
1532 : 5 : rc = spdk_nvme_ns_cmd_write_with_md(&ns, &qpair, buffer, metadata, 0x1000, 384, NULL, NULL,
1533 : : SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1534 : :
1535 : 5 : CU_ASSERT(rc == 0);
1536 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1537 : 5 : CU_ASSERT(g_request->num_children == 2);
1538 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1539 : :
1540 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1541 : 5 : CU_ASSERT(child0->payload_offset == 0);
1542 : 5 : CU_ASSERT(child0->payload_size == 256 * 512);
1543 : 5 : CU_ASSERT(child0->md_offset == 0);
1544 : 5 : CU_ASSERT(child0->md_size == 256 * 8);
1545 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1546 : :
1547 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1548 : 5 : CU_ASSERT(child1->payload_offset == 256 * 512);
1549 : 5 : CU_ASSERT(child1->payload_size == 128 * 512);
1550 : 5 : CU_ASSERT(child1->md_offset == 256 * 8);
1551 : 5 : CU_ASSERT(child1->md_size == 128 * 8);
1552 : :
1553 : 5 : nvme_request_free_children(g_request);
1554 : 5 : nvme_free_request(g_request);
1555 : 5 : cleanup_after_test(&qpair);
1556 : :
1557 : 5 : free(buffer);
1558 : 5 : free(metadata);
1559 : 5 : }
1560 : :
1561 : : static void
1562 : 5 : test_nvme_ns_cmd_zone_append_with_md(void)
1563 : : {
1564 : 4 : struct spdk_nvme_ns ns;
1565 : 4 : struct spdk_nvme_ctrlr ctrlr;
1566 : 4 : struct spdk_nvme_qpair qpair;
1567 : 5 : int rc = 0;
1568 : 5 : char *buffer = NULL;
1569 : 5 : char *metadata = NULL;
1570 : : uint32_t block_size, md_size;
1571 : :
1572 : 5 : block_size = 512;
1573 : 5 : md_size = 128;
1574 : :
1575 : 5 : buffer = malloc((block_size + md_size) * 384);
1576 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(buffer != NULL);
1577 : 5 : metadata = malloc(md_size * 384);
1578 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
1579 : :
1580 : : /*
1581 : : * 512 byte data + 128 byte metadata
1582 : : * Separate metadata buffer
1583 : : * Max data transfer size 256 KB
1584 : : * Max zone append size 128 KB
1585 : : *
1586 : : * 256 blocks * 512 bytes per block = 128 KB I/O
1587 : : * 128 KB I/O <= max zone append size. Test should pass.
1588 : : */
1589 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 256 * 1024, 0, false);
1590 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1591 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1592 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1593 : :
1594 : 5 : rc = nvme_ns_cmd_zone_append_with_md(&ns, &qpair, buffer, metadata, 0x0, 256,
1595 : : NULL, NULL, 0, 0, 0);
1596 : 5 : CU_ASSERT(rc == 0);
1597 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1598 : 5 : CU_ASSERT(g_request->num_children == 0);
1599 : :
1600 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1601 : 5 : CU_ASSERT(g_request->md_size == 256 * 128);
1602 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1603 : :
1604 : 5 : nvme_free_request(g_request);
1605 : 5 : cleanup_after_test(&qpair);
1606 : :
1607 : : /*
1608 : : * 512 byte data + 128 byte metadata
1609 : : * Separate metadata buffer
1610 : : * Max data transfer size 256 KB
1611 : : * Max zone append size 128 KB
1612 : : *
1613 : : * 512 blocks * 512 bytes per block = 256 KB I/O
1614 : : * 256 KB I/O > max zone append size. Test should fail.
1615 : : */
1616 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 256 * 1024, 0, false);
1617 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1618 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1619 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1620 : :
1621 : 5 : rc = nvme_ns_cmd_zone_append_with_md(&ns, &qpair, buffer, metadata, 0x0, 512,
1622 : : NULL, NULL, 0, 0, 0);
1623 : 5 : CU_ASSERT(rc == -EINVAL);
1624 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request == NULL);
1625 : :
1626 : 5 : cleanup_after_test(&qpair);
1627 : :
1628 : : /*
1629 : : * 512 byte data + 128 byte metadata
1630 : : * Extended LBA
1631 : : * Max data transfer size 256 KB
1632 : : * Max zone append size 128 KB
1633 : : *
1634 : : * 128 blocks * (512 + 128) bytes per block = 80 KB I/O
1635 : : * 80 KB I/O <= max zone append size. Test should pass.
1636 : : */
1637 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 256 * 1024, 0, true);
1638 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1639 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1640 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1641 : :
1642 : 5 : rc = nvme_ns_cmd_zone_append_with_md(&ns, &qpair, buffer, NULL, 0x0, 128,
1643 : : NULL, NULL, 0, 0, 0);
1644 : 5 : CU_ASSERT(rc == 0);
1645 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1646 : 5 : CU_ASSERT(g_request->num_children == 0);
1647 : :
1648 : 5 : CU_ASSERT(g_request->payload.md == NULL);
1649 : 5 : CU_ASSERT(g_request->payload_offset == 0);
1650 : 5 : CU_ASSERT(g_request->payload_size == 128 * (512 + 128));
1651 : :
1652 : 5 : nvme_free_request(g_request);
1653 : 5 : cleanup_after_test(&qpair);
1654 : :
1655 : : /*
1656 : : * 512 byte data + 128 byte metadata
1657 : : * Extended LBA
1658 : : * Max data transfer size 256 KB
1659 : : * Max zone append size 128 KB
1660 : : *
1661 : : * 256 blocks * (512 + 128) bytes per block = 160 KB I/O
1662 : : * 160 KB I/O > max zone append size. Test should fail.
1663 : : */
1664 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 256 * 1024, 0, true);
1665 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1666 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1667 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1668 : :
1669 : 5 : rc = nvme_ns_cmd_zone_append_with_md(&ns, &qpair, buffer, NULL, 0x0, 256,
1670 : : NULL, NULL, 0, 0, 0);
1671 : 5 : CU_ASSERT(rc == -EINVAL);
1672 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request == NULL);
1673 : :
1674 : 5 : cleanup_after_test(&qpair);
1675 : :
1676 : 5 : free(buffer);
1677 : 5 : free(metadata);
1678 : 5 : }
1679 : :
1680 : : static void
1681 : 5 : test_nvme_ns_cmd_zone_appendv_with_md(void)
1682 : : {
1683 : 4 : struct spdk_nvme_ns ns;
1684 : 4 : struct spdk_nvme_ctrlr ctrlr;
1685 : 4 : struct spdk_nvme_qpair qpair;
1686 : 5 : int rc = 0;
1687 : : uint32_t lba_count;
1688 : 5 : uint32_t sector_size = 512;
1689 : 5 : uint32_t md_size = 128;
1690 : 5 : char *metadata = NULL;
1691 : 4 : uint64_t sge_length;
1692 : :
1693 : 5 : metadata = malloc(md_size * 384);
1694 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
1695 : :
1696 : : /*
1697 : : * 512 byte data + 128 byte metadata
1698 : : * Separate metadata buffer
1699 : : * Max data transfer size 256 KB
1700 : : * Max zone append size 128 KB
1701 : : *
1702 : : * 256 blocks * 512 bytes per block = 128 KB I/O
1703 : : * 128 KB I/O <= max zone append size. Test should pass.
1704 : : */
1705 : 5 : lba_count = 256;
1706 : 5 : sge_length = lba_count * sector_size;
1707 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, md_size, 256 * 1024, 0, false);
1708 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1709 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1710 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1711 : 5 : rc = nvme_ns_cmd_zone_appendv_with_md(&ns, &qpair, 0x0, lba_count, NULL, &sge_length, 0,
1712 : : nvme_request_reset_sgl, nvme_request_next_sge, metadata, 0, 0);
1713 : 5 : CU_ASSERT(rc == 0);
1714 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1715 : 5 : CU_ASSERT(g_request->num_children == 0);
1716 : :
1717 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1718 : 5 : CU_ASSERT(g_request->md_size == lba_count * md_size);
1719 : 5 : CU_ASSERT(g_request->payload_size == lba_count * sector_size);
1720 : :
1721 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_ZONE_APPEND);
1722 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
1723 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
1724 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
1725 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
1726 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
1727 : :
1728 : 5 : nvme_free_request(g_request);
1729 : 5 : cleanup_after_test(&qpair);
1730 : :
1731 : : /*
1732 : : * 512 byte data + 128 byte metadata
1733 : : * Separate metadata buffer
1734 : : * Max data transfer size 256 KB
1735 : : * Max zone append size 128 KB
1736 : : *
1737 : : * 512 blocks * 512 bytes per block = 256 KB I/O
1738 : : * 256 KB I/O > max zone append size. Test should fail.
1739 : : */
1740 : 5 : lba_count = 512;
1741 : 5 : sge_length = lba_count * sector_size;
1742 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size, md_size, 256 * 1024, 0, false);
1743 : 5 : ctrlr.max_zone_append_size = 128 * 1024;
1744 : 5 : ctrlr.flags |= SPDK_NVME_CTRLR_ZONE_APPEND_SUPPORTED;
1745 : 5 : ns.csi = SPDK_NVME_CSI_ZNS;
1746 : :
1747 : 5 : rc = nvme_ns_cmd_zone_appendv_with_md(&ns, &qpair, 0x0, lba_count, NULL, &sge_length, 0,
1748 : : nvme_request_reset_sgl, nvme_request_next_sge, metadata, 0, 0);
1749 : 5 : CU_ASSERT(rc == -EINVAL);
1750 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request == NULL);
1751 : :
1752 : 5 : cleanup_after_test(&qpair);
1753 : :
1754 : 5 : free(metadata);
1755 : 5 : }
1756 : :
1757 : : static void
1758 : 5 : test_nvme_ns_cmd_read_with_md(void)
1759 : : {
1760 : 4 : struct spdk_nvme_ns ns;
1761 : 4 : struct spdk_nvme_ctrlr ctrlr;
1762 : 4 : struct spdk_nvme_qpair qpair;
1763 : 5 : int rc = 0;
1764 : 5 : char *buffer = NULL;
1765 : 5 : char *metadata = NULL;
1766 : : uint32_t block_size, md_size;
1767 : :
1768 : 5 : block_size = 512;
1769 : 5 : md_size = 128;
1770 : :
1771 : 5 : buffer = malloc(block_size * 256);
1772 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(buffer != NULL);
1773 : 5 : metadata = malloc(md_size * 256);
1774 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
1775 : :
1776 : : /*
1777 : : * 512 byte data + 128 byte metadata
1778 : : * Separate metadata buffer
1779 : : * Max data transfer size 128 KB
1780 : : * No stripe size
1781 : : *
1782 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1783 : : */
1784 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, false);
1785 : :
1786 : 5 : rc = spdk_nvme_ns_cmd_read_with_md(&ns, &qpair, buffer, metadata, 0x1000, 256, NULL, NULL, 0, 0,
1787 : : 0);
1788 : :
1789 : 5 : CU_ASSERT(rc == 0);
1790 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1791 : 5 : CU_ASSERT(g_request->num_children == 0);
1792 : :
1793 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1794 : 5 : CU_ASSERT(g_request->md_size == 256 * md_size);
1795 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1796 : :
1797 : 5 : nvme_free_request(g_request);
1798 : 5 : cleanup_after_test(&qpair);
1799 : 5 : free(buffer);
1800 : 5 : free(metadata);
1801 : 5 : }
1802 : :
1803 : : static void
1804 : 5 : test_nvme_ns_cmd_compare_with_md(void)
1805 : : {
1806 : 4 : struct spdk_nvme_ns ns;
1807 : 4 : struct spdk_nvme_ctrlr ctrlr;
1808 : 4 : struct spdk_nvme_qpair qpair;
1809 : 5 : int rc = 0;
1810 : 5 : char *buffer = NULL;
1811 : 5 : char *metadata = NULL;
1812 : : uint32_t block_size, md_size;
1813 : : struct nvme_request *child0, *child1;
1814 : :
1815 : 5 : block_size = 512;
1816 : 5 : md_size = 128;
1817 : :
1818 : 5 : buffer = malloc((block_size + md_size) * 384);
1819 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(buffer != NULL);
1820 : 5 : metadata = malloc(md_size * 384);
1821 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(metadata != NULL);
1822 : :
1823 : : /*
1824 : : * 512 byte data + 128 byte metadata
1825 : : * Separate metadata buffer
1826 : : * Max data transfer size 128 KB
1827 : : * No stripe size
1828 : : *
1829 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1830 : : */
1831 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, false);
1832 : :
1833 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, metadata, 0x1000, 256,
1834 : : NULL, NULL, 0, 0, 0);
1835 : :
1836 : 5 : CU_ASSERT(rc == 0);
1837 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1838 : 5 : CU_ASSERT(g_request->num_children == 0);
1839 : :
1840 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1841 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1842 : :
1843 : 5 : nvme_free_request(g_request);
1844 : 5 : cleanup_after_test(&qpair);
1845 : :
1846 : : /*
1847 : : * 512 byte data + 128 byte metadata
1848 : : * Extended LBA
1849 : : * Max data transfer size 128 KB
1850 : : * No stripe size
1851 : : *
1852 : : * 256 blocks * (512 + 128) bytes per block = two I/Os:
1853 : : * child 0: 204 blocks - 204 * (512 + 128) = 127.5 KB
1854 : : * child 1: 52 blocks
1855 : : */
1856 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 128, 128 * 1024, 0, true);
1857 : :
1858 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256,
1859 : : NULL, NULL, 0, 0, 0);
1860 : :
1861 : 5 : CU_ASSERT(rc == 0);
1862 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1863 : 5 : CU_ASSERT(g_request->num_children == 2);
1864 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1865 : :
1866 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1867 : 5 : CU_ASSERT(child0->payload.md == NULL);
1868 : 5 : CU_ASSERT(child0->payload_offset == 0);
1869 : 5 : CU_ASSERT(child0->payload_size == 204 * (512 + 128));
1870 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1871 : :
1872 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1873 : 5 : CU_ASSERT(child1->payload.md == NULL);
1874 : 5 : CU_ASSERT(child1->payload_offset == 204 * (512 + 128));
1875 : 5 : CU_ASSERT(child1->payload_size == 52 * (512 + 128));
1876 : :
1877 : 5 : nvme_request_free_children(g_request);
1878 : 5 : nvme_free_request(g_request);
1879 : 5 : cleanup_after_test(&qpair);
1880 : :
1881 : : /*
1882 : : * 512 byte data + 8 byte metadata
1883 : : * Extended LBA
1884 : : * Max data transfer size 128 KB
1885 : : * No stripe size
1886 : : * No protection information
1887 : : *
1888 : : * 256 blocks * (512 + 8) bytes per block = two I/Os:
1889 : : * child 0: 252 blocks - 252 * (512 + 8) = 127.96875 KB
1890 : : * child 1: 4 blocks
1891 : : */
1892 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
1893 : :
1894 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256,
1895 : : NULL, NULL, 0, 0, 0);
1896 : :
1897 : 5 : CU_ASSERT(rc == 0);
1898 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1899 : 5 : CU_ASSERT(g_request->num_children == 2);
1900 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1901 : :
1902 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1903 : 5 : CU_ASSERT(child0->payload.md == NULL);
1904 : 5 : CU_ASSERT(child0->payload_offset == 0);
1905 : 5 : CU_ASSERT(child0->payload_size == 252 * (512 + 8));
1906 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1907 : :
1908 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1909 : 5 : CU_ASSERT(child1->payload.md == NULL);
1910 : 5 : CU_ASSERT(child1->payload_offset == 252 * (512 + 8));
1911 : 5 : CU_ASSERT(child1->payload_size == 4 * (512 + 8));
1912 : :
1913 : 5 : nvme_request_free_children(g_request);
1914 : 5 : nvme_free_request(g_request);
1915 : 5 : cleanup_after_test(&qpair);
1916 : :
1917 : : /*
1918 : : * 512 byte data + 8 byte metadata
1919 : : * Extended LBA
1920 : : * Max data transfer size 128 KB
1921 : : * No stripe size
1922 : : * Protection information enabled + PRACT
1923 : : *
1924 : : * Special case for 8-byte metadata + PI + PRACT: no metadata transferred
1925 : : * 256 blocks * 512 bytes per block = single 128 KB I/O (no splitting required)
1926 : : */
1927 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, true);
1928 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1929 : :
1930 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, NULL, 0x1000, 256,
1931 : : NULL, NULL, SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1932 : :
1933 : 5 : CU_ASSERT(rc == 0);
1934 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1935 : 5 : CU_ASSERT(g_request->num_children == 0);
1936 : :
1937 : 5 : CU_ASSERT(g_request->payload.md == NULL);
1938 : 5 : CU_ASSERT(g_request->payload_offset == 0);
1939 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512); /* NOTE: does not include metadata! */
1940 : :
1941 : 5 : nvme_request_free_children(g_request);
1942 : 5 : nvme_free_request(g_request);
1943 : 5 : cleanup_after_test(&qpair);
1944 : :
1945 : : /*
1946 : : * 512 byte data + 8 byte metadata
1947 : : * Separate metadata buffer
1948 : : * Max data transfer size 128 KB
1949 : : * No stripe size
1950 : : * Protection information enabled + PRACT
1951 : : */
1952 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1953 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1954 : :
1955 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, metadata, 0x1000, 256,
1956 : : NULL, NULL, SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1957 : :
1958 : 5 : CU_ASSERT(rc == 0);
1959 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1960 : 5 : CU_ASSERT(g_request->num_children == 0);
1961 : :
1962 : 5 : CU_ASSERT(g_request->payload.md == metadata);
1963 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
1964 : :
1965 : 5 : nvme_free_request(g_request);
1966 : 5 : cleanup_after_test(&qpair);
1967 : :
1968 : : /*
1969 : : * 512 byte data + 8 byte metadata
1970 : : * Separate metadata buffer
1971 : : * Max data transfer size 128 KB
1972 : : * No stripe size
1973 : : * Protection information enabled + PRACT
1974 : : *
1975 : : * 384 blocks * 512 bytes = two I/Os:
1976 : : * child 0: 256 blocks
1977 : : * child 1: 128 blocks
1978 : : */
1979 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 8, 128 * 1024, 0, false);
1980 : 5 : ns.flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
1981 : :
1982 : 5 : rc = spdk_nvme_ns_cmd_compare_with_md(&ns, &qpair, buffer, metadata, 0x1000, 384,
1983 : : NULL, NULL, SPDK_NVME_IO_FLAGS_PRACT, 0, 0);
1984 : :
1985 : 5 : CU_ASSERT(rc == 0);
1986 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
1987 : 5 : CU_ASSERT(g_request->num_children == 2);
1988 : 5 : child0 = TAILQ_FIRST(&g_request->children);
1989 : :
1990 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child0 != NULL);
1991 : 5 : CU_ASSERT(child0->payload_offset == 0);
1992 : 5 : CU_ASSERT(child0->payload_size == 256 * 512);
1993 : 5 : CU_ASSERT(child0->md_offset == 0);
1994 : 5 : child1 = TAILQ_NEXT(child0, child_tailq);
1995 : :
1996 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(child1 != NULL);
1997 : 5 : CU_ASSERT(child1->payload_offset == 256 * 512);
1998 : 5 : CU_ASSERT(child1->payload_size == 128 * 512);
1999 : 5 : CU_ASSERT(child1->md_offset == 256 * 8);
2000 : :
2001 : 5 : nvme_request_free_children(g_request);
2002 : 5 : nvme_free_request(g_request);
2003 : 5 : cleanup_after_test(&qpair);
2004 : :
2005 : 5 : free(buffer);
2006 : 5 : free(metadata);
2007 : 5 : }
2008 : :
2009 : : static void
2010 : 5 : test_nvme_ns_cmd_setup_request(void)
2011 : : {
2012 : 5 : struct spdk_nvme_ns ns = {};
2013 : 5 : struct nvme_request req = {};
2014 : :
2015 : 5 : ns.id = 1;
2016 : 5 : ns.pi_type = SPDK_NVME_FMT_NVM_PROTECTION_TYPE1;
2017 : 5 : ns.flags = SPDK_NVME_NS_DPS_PI_SUPPORTED;
2018 : :
2019 : 5 : _nvme_ns_cmd_setup_request(&ns, &req, SPDK_NVME_OPC_READ,
2020 : : 1024, 256, SPDK_NVME_IO_FLAGS_PRACT, 1, 1, 0);
2021 : 5 : CU_ASSERT(req.cmd.cdw10 == 1024);
2022 : 5 : CU_ASSERT(req.cmd.opc == SPDK_NVME_OPC_READ);
2023 : 5 : CU_ASSERT(req.cmd.nsid == 1);
2024 : 5 : CU_ASSERT(req.cmd.cdw14 == 1024);
2025 : 5 : CU_ASSERT(req.cmd.fuse == 0);
2026 : 5 : CU_ASSERT(req.cmd.cdw12 == (255 | SPDK_NVME_IO_FLAGS_PRACT));
2027 : 5 : CU_ASSERT(req.cmd.cdw15 == (1 << 16 | 1));
2028 : 5 : }
2029 : :
2030 : : static void
2031 : 5 : test_spdk_nvme_ns_cmd_readv_with_md(void)
2032 : : {
2033 : 4 : struct spdk_nvme_ns ns;
2034 : 4 : struct spdk_nvme_ctrlr ctrlr;
2035 : 4 : struct spdk_nvme_qpair qpair;
2036 : 5 : int rc = 0;
2037 : 5 : char *metadata = NULL;
2038 : 5 : uint32_t lba_count = 256;
2039 : 5 : uint32_t sector_size = 512;
2040 : 5 : uint32_t md_size = 128;
2041 : 5 : uint64_t sge_length = lba_count * sector_size;
2042 : :
2043 : 5 : metadata = (void *)0xDEADBEEF;
2044 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size,
2045 : : md_size, 128 * 1024, 0, false);
2046 : :
2047 : 5 : rc = spdk_nvme_ns_cmd_readv_with_md(&ns, &qpair, 0x1000, lba_count, NULL,
2048 : : &sge_length, 0, nvme_request_reset_sgl,
2049 : : nvme_request_next_sge, metadata, 0, 0);
2050 : 5 : CU_ASSERT(rc == 0);
2051 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2052 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_READ);
2053 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
2054 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
2055 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
2056 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
2057 : 5 : CU_ASSERT(g_request->payload.md == (void *)0xDEADBEEF);
2058 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2059 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
2060 : 5 : CU_ASSERT(g_request->qpair == &qpair);
2061 : 5 : CU_ASSERT(g_request->md_offset == 0);
2062 : 5 : CU_ASSERT(g_request->payload_offset == 0);
2063 : :
2064 : 5 : rc = spdk_nvme_ns_cmd_readv_with_md(&ns, &qpair, 0x1000, lba_count, NULL,
2065 : : NULL, 0, nvme_request_reset_sgl, NULL,
2066 : : metadata, 0, 0);
2067 : 5 : CU_ASSERT(rc == -EINVAL);
2068 : :
2069 : 5 : nvme_free_request(g_request);
2070 : 5 : cleanup_after_test(&qpair);
2071 : 5 : }
2072 : :
2073 : : static void
2074 : 5 : test_spdk_nvme_ns_cmd_writev_ext(void)
2075 : : {
2076 : 4 : struct spdk_nvme_ns ns;
2077 : 4 : struct spdk_nvme_ctrlr ctrlr;
2078 : 4 : struct spdk_nvme_qpair qpair;
2079 : 5 : struct spdk_nvme_ns_cmd_ext_io_opts ext_opts = {
2080 : : .memory_domain = (struct spdk_memory_domain *)0xfeedbeef,
2081 : : .memory_domain_ctx = (void *)0xf00df00d,
2082 : : .metadata = (void *)0xdeadbeef,
2083 : : .apptag_mask = 0xf,
2084 : : .apptag = 0xff
2085 : : };
2086 : 5 : int rc = 0;
2087 : 5 : uint32_t lba_count = 256;
2088 : 5 : uint32_t sector_size = 512;
2089 : 5 : uint32_t md_size = 128;
2090 : 5 : uint64_t sge_length = lba_count * sector_size;
2091 : :
2092 : 5 : ext_opts.size = SPDK_SIZEOF(&ext_opts, cdw13);
2093 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size,
2094 : : md_size, 128 * 1024, 0, false);
2095 : :
2096 : : /* Invalid io_flags. Expect fail */
2097 : 5 : ext_opts.io_flags = 0xFFFF000F;
2098 : 5 : rc = spdk_nvme_ns_cmd_writev_ext(&ns, &qpair, 0x1000, lba_count,
2099 : : NULL, &sge_length, nvme_request_reset_sgl,
2100 : : nvme_request_next_sge, &ext_opts);
2101 : 5 : CU_ASSERT(rc != 0);
2102 : 5 : ext_opts.io_flags = SPDK_NVME_IO_FLAGS_PRCHK_REFTAG | SPDK_NVME_IO_FLAGS_DATA_PLACEMENT_DIRECTIVE;
2103 : 5 : ext_opts.cdw13 = (1 << 16);
2104 : :
2105 : : /* Empty reset_sgl cb. Expect fail */
2106 : 5 : rc = spdk_nvme_ns_cmd_writev_ext(&ns, &qpair, 0x1000, lba_count,
2107 : : NULL, &sge_length, NULL,
2108 : : nvme_request_next_sge, &ext_opts);
2109 : 5 : CU_ASSERT(rc != 0);
2110 : :
2111 : : /* Empty next_sgl cb. Expect fail */
2112 : 5 : rc = spdk_nvme_ns_cmd_writev_ext(&ns, &qpair, 0x1000, lba_count,
2113 : : NULL, &sge_length, nvme_request_reset_sgl,
2114 : : NULL, &ext_opts);
2115 : 5 : CU_ASSERT(rc != 0);
2116 : :
2117 : : /* Expect pass */
2118 : 5 : rc = spdk_nvme_ns_cmd_writev_ext(&ns, &qpair, 0x1000, lba_count,
2119 : : NULL, &sge_length, nvme_request_reset_sgl,
2120 : : nvme_request_next_sge, &ext_opts);
2121 : 5 : CU_ASSERT(rc == 0);
2122 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2123 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE);
2124 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
2125 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
2126 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
2127 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
2128 : 5 : CU_ASSERT(g_request->payload.md == (void *)0xDEADBEEF);
2129 : 5 : CU_ASSERT(g_request->payload.opts == &ext_opts);
2130 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2131 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_CDW12_MASK) == ext_opts.io_flags);
2132 : 5 : CU_ASSERT(g_request->cmd.cdw13 == ext_opts.cdw13);
2133 : 5 : CU_ASSERT(g_request->cmd.cdw15 >> 16 == ext_opts.apptag_mask);
2134 : 5 : CU_ASSERT((g_request->cmd.cdw15 & 0xff) == ext_opts.apptag);
2135 : :
2136 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
2137 : 5 : CU_ASSERT(g_request->qpair == &qpair);
2138 : 5 : CU_ASSERT(g_request->md_offset == 0);
2139 : 5 : CU_ASSERT(g_request->payload_offset == 0);
2140 : :
2141 : 5 : nvme_free_request(g_request);
2142 : 5 : cleanup_after_test(&qpair);
2143 : 5 : }
2144 : :
2145 : : static void
2146 : 5 : test_spdk_nvme_ns_cmd_readv_ext(void)
2147 : : {
2148 : 4 : struct spdk_nvme_ns ns;
2149 : 4 : struct spdk_nvme_ctrlr ctrlr;
2150 : 4 : struct spdk_nvme_qpair qpair;
2151 : 5 : struct spdk_nvme_ns_cmd_ext_io_opts ext_opts = {
2152 : : .memory_domain = (struct spdk_memory_domain *)0xfeedbeef,
2153 : : .memory_domain_ctx = (void *)0xf00df00d,
2154 : : .metadata = (void *)0xdeadbeef,
2155 : : .apptag_mask = 0xf,
2156 : : .apptag = 0xff
2157 : : };
2158 : 5 : int rc = 0;
2159 : 5 : uint32_t lba_count = 256;
2160 : 5 : uint32_t sector_size = 512;
2161 : 5 : uint32_t md_size = 128;
2162 : 5 : uint64_t sge_length = lba_count * sector_size;
2163 : :
2164 : 5 : ext_opts.size = SPDK_SIZEOF(&ext_opts, cdw13);
2165 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, sector_size,
2166 : : md_size, 128 * 1024, 0, false);
2167 : :
2168 : : /* Invalid io_flags. Expect fail */
2169 : 5 : ext_opts.io_flags = 0xFFFF000F;
2170 : 5 : rc = spdk_nvme_ns_cmd_readv_ext(&ns, &qpair, 0x1000, lba_count,
2171 : : NULL, &sge_length, nvme_request_reset_sgl,
2172 : : nvme_request_next_sge, &ext_opts);
2173 : 5 : CU_ASSERT(rc != 0);
2174 : 5 : ext_opts.io_flags = SPDK_NVME_IO_FLAGS_PRCHK_REFTAG;
2175 : :
2176 : : /* Empty reset_sgl cb. Expect fail */
2177 : 5 : rc = spdk_nvme_ns_cmd_readv_ext(&ns, &qpair, 0x1000, lba_count,
2178 : : NULL, &sge_length, NULL,
2179 : : nvme_request_next_sge, &ext_opts);
2180 : 5 : CU_ASSERT(rc != 0);
2181 : :
2182 : : /* Empty next_sgl cb. Expect fail */
2183 : 5 : rc = spdk_nvme_ns_cmd_readv_ext(&ns, &qpair, 0x1000, lba_count,
2184 : : NULL, &sge_length, nvme_request_reset_sgl,
2185 : : NULL, &ext_opts);
2186 : 5 : CU_ASSERT(rc != 0);
2187 : :
2188 : : /* Expect pass */
2189 : 5 : rc = spdk_nvme_ns_cmd_readv_ext(&ns, &qpair, 0x1000, lba_count,
2190 : : NULL, &sge_length, nvme_request_reset_sgl,
2191 : : nvme_request_next_sge, &ext_opts);
2192 : 5 : CU_ASSERT(rc == 0);
2193 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2194 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_READ);
2195 : 5 : CU_ASSERT(nvme_payload_type(&g_request->payload) == NVME_PAYLOAD_TYPE_SGL);
2196 : 5 : CU_ASSERT(g_request->payload.reset_sgl_fn == nvme_request_reset_sgl);
2197 : 5 : CU_ASSERT(g_request->payload.next_sge_fn == nvme_request_next_sge);
2198 : 5 : CU_ASSERT(g_request->payload.contig_or_cb_arg == &sge_length);
2199 : 5 : CU_ASSERT(g_request->payload.md == (void *)0xDEADBEEF);
2200 : 5 : CU_ASSERT(g_request->payload.opts == &ext_opts);
2201 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2202 : 5 : CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_CDW12_MASK) == ext_opts.io_flags);
2203 : 5 : CU_ASSERT(g_request->cmd.cdw15 >> 16 == ext_opts.apptag_mask);
2204 : 5 : CU_ASSERT((g_request->cmd.cdw15 & 0xff) == ext_opts.apptag);
2205 : :
2206 : 5 : CU_ASSERT(g_request->payload_size == 256 * 512);
2207 : 5 : CU_ASSERT(g_request->qpair == &qpair);
2208 : 5 : CU_ASSERT(g_request->md_offset == 0);
2209 : 5 : CU_ASSERT(g_request->payload_offset == 0);
2210 : :
2211 : 5 : nvme_free_request(g_request);
2212 : 5 : cleanup_after_test(&qpair);
2213 : 5 : }
2214 : :
2215 : : static void
2216 : 5 : test_nvme_ns_cmd_verify(void)
2217 : : {
2218 : 4 : struct spdk_nvme_ns ns;
2219 : 4 : struct spdk_nvme_ctrlr ctrlr;
2220 : 4 : struct spdk_nvme_qpair qpair;
2221 : 4 : uint64_t cmd_lba;
2222 : 4 : uint32_t cmd_lba_count;
2223 : : int rc;
2224 : :
2225 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
2226 : :
2227 : 5 : rc = spdk_nvme_ns_cmd_verify(&ns, &qpair, 0, 2, NULL, NULL, 0);
2228 : 5 : CU_ASSERT(rc == 0);
2229 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2230 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_VERIFY);
2231 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2232 : 5 : nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
2233 : 5 : CU_ASSERT_EQUAL(cmd_lba, 0);
2234 : 5 : CU_ASSERT_EQUAL(cmd_lba_count, 2);
2235 : :
2236 : 5 : nvme_free_request(g_request);
2237 : 5 : cleanup_after_test(&qpair);
2238 : 5 : }
2239 : :
2240 : : static void
2241 : 5 : test_nvme_ns_cmd_io_mgmt_send(void)
2242 : : {
2243 : 4 : struct spdk_nvme_ns ns;
2244 : 4 : struct spdk_nvme_ctrlr ctrlr;
2245 : 4 : struct spdk_nvme_qpair qpair;
2246 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
2247 : 5 : void *cb_arg = NULL;
2248 : 4 : uint16_t list[UT_SIZE_IOMS];
2249 : : uint16_t i;
2250 : : uint32_t tmp_cdw10;
2251 : 5 : int rc = 0;
2252 : :
2253 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
2254 : :
2255 [ + + ]: 645 : for (i = 0; i < UT_SIZE_IOMS; i++) {
2256 : 640 : list[i] = i;
2257 : : }
2258 : :
2259 : : /*
2260 : : * Submit an I/O management send command with a list of 128 placement
2261 : : * identifiers. The management operation specific field is number of
2262 : : * placement identifiers which is 0 based value.
2263 : : */
2264 : 5 : rc = spdk_nvme_ns_cmd_io_mgmt_send(&ns, &qpair, list, UT_SIZE_IOMS * sizeof(uint16_t),
2265 : : SPDK_NVME_FDP_IO_MGMT_SEND_RUHU, UT_SIZE_IOMS - 1, cb_fn, cb_arg);
2266 : 5 : CU_ASSERT(rc == 0);
2267 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2268 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_IO_MANAGEMENT_SEND);
2269 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2270 : 5 : tmp_cdw10 = SPDK_NVME_FDP_IO_MGMT_SEND_RUHU;
2271 : 5 : tmp_cdw10 |= (UT_SIZE_IOMS - 1) << 16;
2272 : :
2273 : 5 : CU_ASSERT(g_request->cmd.cdw10 == tmp_cdw10);
2274 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
2275 : 5 : nvme_free_request(g_request);
2276 : 5 : cleanup_after_test(&qpair);
2277 : 5 : }
2278 : :
2279 : : static void
2280 : 5 : test_nvme_ns_cmd_io_mgmt_recv(void)
2281 : : {
2282 : 4 : struct spdk_nvme_ns ns;
2283 : 4 : struct spdk_nvme_ctrlr ctrlr;
2284 : 4 : struct spdk_nvme_qpair qpair;
2285 : : struct spdk_nvme_fdp_ruhs *payload;;
2286 : 5 : spdk_nvme_cmd_cb cb_fn = NULL;
2287 : 5 : void *cb_arg = NULL;
2288 : 5 : int rc = 0;
2289 : 5 : uint16_t mos = 2;
2290 : : uint32_t tmp_cdw10;
2291 : 5 : uint32_t size = sizeof(struct spdk_nvme_fdp_ruhs);
2292 : :
2293 : 5 : prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
2294 : :
2295 : 5 : payload = calloc(1, size);
2296 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(payload != NULL);
2297 : :
2298 : 5 : rc = spdk_nvme_ns_cmd_io_mgmt_recv(&ns, &qpair, payload, size,
2299 : : SPDK_NVME_FDP_IO_MGMT_RECV_RUHS, mos, cb_fn, cb_arg);
2300 : 5 : CU_ASSERT(rc == 0);
2301 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_request != NULL);
2302 : 5 : CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_IO_MANAGEMENT_RECEIVE);
2303 : 5 : CU_ASSERT(g_request->cmd.nsid == ns.id);
2304 : :
2305 : 5 : tmp_cdw10 = SPDK_NVME_FDP_IO_MGMT_RECV_RUHS;
2306 : 5 : tmp_cdw10 |= (uint32_t)mos << 16;
2307 : :
2308 : 5 : CU_ASSERT(g_request->cmd.cdw10 == tmp_cdw10);
2309 : : /* number of dwords which is 0-based */
2310 : 5 : CU_ASSERT(g_request->cmd.cdw11 == (size >> 2) - 1);
2311 : :
2312 : 5 : spdk_free(g_request->payload.contig_or_cb_arg);
2313 : 5 : nvme_free_request(g_request);
2314 : 5 : free(payload);
2315 : :
2316 : : /* len not multiple of 4 */
2317 : 5 : rc = spdk_nvme_ns_cmd_io_mgmt_recv(&ns, &qpair, NULL, 6,
2318 : : SPDK_NVME_FDP_IO_MGMT_RECV_RUHS, mos, cb_fn, cb_arg);
2319 : 5 : CU_ASSERT(rc != 0);
2320 : 5 : cleanup_after_test(&qpair);
2321 : 5 : }
2322 : :
2323 : : int
2324 : 5 : main(int argc, char **argv)
2325 : : {
2326 : 5 : CU_pSuite suite = NULL;
2327 : : unsigned int num_failures;
2328 : :
2329 : 5 : CU_initialize_registry();
2330 : :
2331 : 5 : suite = CU_add_suite("nvme_ns_cmd", NULL, NULL);
2332 : :
2333 : 5 : CU_ADD_TEST(suite, split_test);
2334 : 5 : CU_ADD_TEST(suite, split_test2);
2335 : 5 : CU_ADD_TEST(suite, split_test3);
2336 : 5 : CU_ADD_TEST(suite, split_test4);
2337 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_flush);
2338 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_dataset_management);
2339 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_copy);
2340 : 5 : CU_ADD_TEST(suite, test_io_flags);
2341 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_write_zeroes);
2342 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_write_uncorrectable);
2343 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_reservation_register);
2344 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_reservation_release);
2345 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_reservation_acquire);
2346 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_reservation_report);
2347 : 5 : CU_ADD_TEST(suite, test_cmd_child_request);
2348 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_readv);
2349 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_read_with_md);
2350 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_writev);
2351 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_write_with_md);
2352 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_zone_append_with_md);
2353 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_zone_appendv_with_md);
2354 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_comparev);
2355 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_compare_and_write);
2356 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_compare_with_md);
2357 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_comparev_with_md);
2358 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_setup_request);
2359 : 5 : CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_readv_with_md);
2360 : 5 : CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_writev_ext);
2361 : 5 : CU_ADD_TEST(suite, test_spdk_nvme_ns_cmd_readv_ext);
2362 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_verify);
2363 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_io_mgmt_send);
2364 : 5 : CU_ADD_TEST(suite, test_nvme_ns_cmd_io_mgmt_recv);
2365 : :
2366 : 5 : g_spdk_nvme_driver = &_g_nvme_driver;
2367 : :
2368 : 5 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
2369 : 5 : CU_cleanup_registry();
2370 : 5 : return num_failures;
2371 : : }
|