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