Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2015 Intel Corporation. All rights reserved.
3 : : * Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved.
4 : : */
5 : :
6 : : #include "nvme_internal.h"
7 : :
8 : : static inline struct spdk_nvme_ns_data *
9 : 8100 : _nvme_ns_get_data(struct spdk_nvme_ns *ns)
10 : : {
11 : 8100 : return &ns->nsdata;
12 : : }
13 : :
14 : : /**
15 : : * Update Namespace flags based on Identify Controller
16 : : * and Identify Namespace. This can be also used for
17 : : * Namespace Attribute Notice events and Namespace
18 : : * operations such as Attach/Detach.
19 : : */
20 : : void
21 : 1828 : nvme_ns_set_identify_data(struct spdk_nvme_ns *ns)
22 : : {
23 : : struct spdk_nvme_ns_data *nsdata;
24 : : uint32_t format_index;
25 : :
26 : 1828 : nsdata = _nvme_ns_get_data(ns);
27 : :
28 : 1828 : ns->flags = 0x0000;
29 : 1828 : format_index = spdk_nvme_ns_get_format_index(nsdata);
30 : :
31 [ - + ]: 1828 : ns->sector_size = 1 << nsdata->lbaf[format_index].lbads;
32 : 1828 : ns->extended_lba_size = ns->sector_size;
33 : :
34 : 1828 : ns->md_size = nsdata->lbaf[format_index].ms;
35 [ + + ]: 1828 : if (nsdata->flbas.extended) {
36 : 12 : ns->flags |= SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED;
37 : 12 : ns->extended_lba_size += ns->md_size;
38 : : }
39 : :
40 [ - + ]: 1828 : ns->sectors_per_max_io = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->extended_lba_size;
41 [ - + ]: 1828 : ns->sectors_per_max_io_no_md = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->sector_size;
42 [ + + ]: 1828 : if (ns->ctrlr->quirks & NVME_QUIRK_MDTS_EXCLUDE_MD) {
43 : 6 : ns->sectors_per_max_io = ns->sectors_per_max_io_no_md;
44 : : }
45 : :
46 [ + + ]: 1828 : if (nsdata->noiob) {
47 : 82 : ns->sectors_per_stripe = nsdata->noiob;
48 [ - + - + ]: 82 : SPDK_DEBUGLOG(nvme, "ns %u optimal IO boundary %" PRIu32 " blocks\n",
49 : : ns->id, ns->sectors_per_stripe);
50 [ + + ]: 1746 : } else if (ns->ctrlr->quirks & NVME_INTEL_QUIRK_STRIPING &&
51 [ + - ]: 100 : ns->ctrlr->cdata.vs[3] != 0) {
52 [ - + - + ]: 100 : ns->sectors_per_stripe = (1ULL << ns->ctrlr->cdata.vs[3]) * ns->ctrlr->min_page_size /
53 : 100 : ns->sector_size;
54 [ - + - + ]: 100 : SPDK_DEBUGLOG(nvme, "ns %u stripe size quirk %" PRIu32 " blocks\n",
55 : : ns->id, ns->sectors_per_stripe);
56 : : } else {
57 : 1646 : ns->sectors_per_stripe = 0;
58 : : }
59 : :
60 [ + + ]: 1828 : if (ns->ctrlr->cdata.oncs.dsm) {
61 : 1376 : ns->flags |= SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
62 : : }
63 : :
64 [ + + ]: 1828 : if (ns->ctrlr->cdata.oncs.compare) {
65 : 1648 : ns->flags |= SPDK_NVME_NS_COMPARE_SUPPORTED;
66 : : }
67 : :
68 [ + + ]: 1828 : if (ns->ctrlr->cdata.vwc.present) {
69 : 1635 : ns->flags |= SPDK_NVME_NS_FLUSH_SUPPORTED;
70 : : }
71 : :
72 [ + + ]: 1828 : if (ns->ctrlr->cdata.oncs.write_zeroes) {
73 : 1657 : ns->flags |= SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
74 : : }
75 : :
76 [ + + ]: 1828 : if (ns->ctrlr->cdata.oncs.write_unc) {
77 : 139 : ns->flags |= SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED;
78 : : }
79 : :
80 [ + + ]: 1828 : if (nsdata->nsrescap.raw) {
81 : 832 : ns->flags |= SPDK_NVME_NS_RESERVATION_SUPPORTED;
82 : : }
83 : :
84 : 1828 : ns->pi_type = SPDK_NVME_FMT_NVM_PROTECTION_DISABLE;
85 [ + + + + ]: 1828 : if (nsdata->lbaf[format_index].ms && nsdata->dps.pit) {
86 : 12 : ns->flags |= SPDK_NVME_NS_DPS_PI_SUPPORTED;
87 : 12 : ns->pi_type = nsdata->dps.pit;
88 : : }
89 : 1828 : }
90 : :
91 : : static int
92 : 223 : nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns)
93 : : {
94 : : struct nvme_completion_poll_status *status;
95 : : struct spdk_nvme_ns_data *nsdata;
96 : : int rc;
97 : :
98 : 223 : status = calloc(1, sizeof(*status));
99 [ - + ]: 223 : if (!status) {
100 : 0 : SPDK_ERRLOG("Failed to allocate status tracker\n");
101 : 0 : return -ENOMEM;
102 : : }
103 : :
104 : 223 : nsdata = _nvme_ns_get_data(ns);
105 : 223 : rc = nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS, 0, ns->id, 0,
106 : : nsdata, sizeof(*nsdata),
107 : : nvme_completion_poll_cb, status);
108 [ - + ]: 223 : if (rc != 0) {
109 : 0 : free(status);
110 : 0 : return rc;
111 : : }
112 : :
113 [ - + ]: 223 : if (nvme_wait_for_completion_robust_lock(ns->ctrlr->adminq, status,
114 : 223 : &ns->ctrlr->ctrlr_lock)) {
115 [ # # # # ]: 0 : if (!status->timed_out) {
116 : 0 : free(status);
117 : : }
118 : : /* This can occur if the namespace is not active. Simply zero the
119 : : * namespace data and continue. */
120 : 0 : nvme_ns_destruct(ns);
121 : 0 : return 0;
122 : : }
123 : 223 : free(status);
124 : :
125 : 223 : nvme_ns_set_identify_data(ns);
126 : :
127 : 223 : return 0;
128 : : }
129 : :
130 : : static int
131 : 6 : nvme_ctrlr_identify_ns_iocs_specific(struct spdk_nvme_ns *ns)
132 : : {
133 : : struct nvme_completion_poll_status *status;
134 : 6 : struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr;
135 : : struct spdk_nvme_zns_ns_data *nsdata_zns;
136 : : int rc;
137 : :
138 [ + - ]: 6 : switch (ns->csi) {
139 : 6 : case SPDK_NVME_CSI_ZNS:
140 : 6 : break;
141 : 0 : default:
142 : : /*
143 : : * This switch must handle all cases for which
144 : : * nvme_ns_has_supported_iocs_specific_data() returns true,
145 : : * other cases should never happen.
146 : : */
147 : 0 : assert(0);
148 : : }
149 : :
150 : 6 : nvme_ns_free_zns_specific_data(ns);
151 : :
152 : 6 : nsdata_zns = spdk_zmalloc(sizeof(*nsdata_zns), 64, NULL, SPDK_ENV_SOCKET_ID_ANY,
153 : : SPDK_MALLOC_SHARE);
154 [ - + ]: 6 : if (!nsdata_zns) {
155 : 0 : return -ENOMEM;
156 : : }
157 : :
158 : 6 : status = calloc(1, sizeof(*status));
159 [ - + ]: 6 : if (!status) {
160 : 0 : SPDK_ERRLOG("Failed to allocate status tracker\n");
161 : 0 : spdk_free(nsdata_zns);
162 : 0 : return -ENOMEM;
163 : : }
164 : :
165 : 6 : rc = nvme_ctrlr_cmd_identify(ctrlr, SPDK_NVME_IDENTIFY_NS_IOCS, 0, ns->id, ns->csi,
166 : : nsdata_zns, sizeof(*nsdata_zns),
167 : : nvme_completion_poll_cb, status);
168 [ - + ]: 6 : if (rc != 0) {
169 : 0 : spdk_free(nsdata_zns);
170 : 0 : free(status);
171 : 0 : return rc;
172 : : }
173 : :
174 [ - + ]: 6 : if (nvme_wait_for_completion_robust_lock(ctrlr->adminq, status, &ctrlr->ctrlr_lock)) {
175 : 0 : SPDK_ERRLOG("Failed to retrieve Identify IOCS Specific Namespace Data Structure\n");
176 : 0 : spdk_free(nsdata_zns);
177 [ # # # # ]: 0 : if (!status->timed_out) {
178 : 0 : free(status);
179 : : }
180 : 0 : return -ENXIO;
181 : : }
182 : 6 : free(status);
183 : 6 : ns->nsdata_zns = nsdata_zns;
184 : :
185 : 6 : return 0;
186 : : }
187 : :
188 : : static int
189 : 175 : nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns)
190 : : {
191 : : struct nvme_completion_poll_status *status;
192 : : int rc;
193 : :
194 [ - + ]: 175 : memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
195 : :
196 [ + + ]: 175 : if ((ns->ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) &&
197 [ - + ]: 12 : !(ns->ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS)) ||
198 [ - + ]: 163 : (ns->ctrlr->quirks & NVME_QUIRK_IDENTIFY_CNS)) {
199 [ - + - + ]: 12 : SPDK_DEBUGLOG(nvme, "Version < 1.3; not attempting to retrieve NS ID Descriptor List\n");
200 : 12 : return 0;
201 : : }
202 : :
203 : 163 : status = calloc(1, sizeof(*status));
204 [ - + ]: 163 : if (!status) {
205 : 0 : SPDK_ERRLOG("Failed to allocate status tracker\n");
206 : 0 : return -ENOMEM;
207 : : }
208 : :
209 [ - + - + ]: 163 : SPDK_DEBUGLOG(nvme, "Attempting to retrieve NS ID Descriptor List\n");
210 : 163 : rc = nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST, 0, ns->id,
211 : 163 : 0, ns->id_desc_list, sizeof(ns->id_desc_list),
212 : : nvme_completion_poll_cb, status);
213 [ - + ]: 163 : if (rc < 0) {
214 : 0 : free(status);
215 : 0 : return rc;
216 : : }
217 : :
218 : 163 : rc = nvme_wait_for_completion_robust_lock(ns->ctrlr->adminq, status, &ns->ctrlr->ctrlr_lock);
219 [ - + ]: 163 : if (rc != 0) {
220 : 0 : SPDK_WARNLOG("Failed to retrieve NS ID Descriptor List\n");
221 [ # # ]: 0 : memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
222 : : }
223 : :
224 [ + + + - ]: 163 : if (!status->timed_out) {
225 : 163 : free(status);
226 : : }
227 : :
228 : 163 : nvme_ns_set_id_desc_list_data(ns);
229 : :
230 : 163 : return rc;
231 : : }
232 : :
233 : : uint32_t
234 : 3310 : spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns)
235 : : {
236 : 3310 : return ns->id;
237 : : }
238 : :
239 : : bool
240 : 623 : spdk_nvme_ns_is_active(struct spdk_nvme_ns *ns)
241 : : {
242 : 623 : const struct spdk_nvme_ns_data *nsdata = NULL;
243 : :
244 : : /*
245 : : * According to the spec, valid NS has non-zero id.
246 : : */
247 [ + + ]: 623 : if (ns->id == 0) {
248 : 6 : return false;
249 : : }
250 : :
251 : 617 : nsdata = _nvme_ns_get_data(ns);
252 : :
253 : : /*
254 : : * According to the spec, Identify Namespace will return a zero-filled structure for
255 : : * inactive namespace IDs.
256 : : * Check NCAP since it must be nonzero for an active namespace.
257 : : */
258 : 617 : return nsdata->ncap != 0;
259 : : }
260 : :
261 : : struct spdk_nvme_ctrlr *
262 : 2135033 : spdk_nvme_ns_get_ctrlr(struct spdk_nvme_ns *ns)
263 : : {
264 : 2135033 : return ns->ctrlr;
265 : : }
266 : :
267 : : uint32_t
268 : 3985 : spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns)
269 : : {
270 : 3985 : return ns->ctrlr->max_xfer_size;
271 : : }
272 : :
273 : : uint32_t
274 : 2341 : spdk_nvme_ns_get_sector_size(struct spdk_nvme_ns *ns)
275 : : {
276 : 2341 : return ns->sector_size;
277 : : }
278 : :
279 : : uint32_t
280 : 1796296 : spdk_nvme_ns_get_extended_sector_size(struct spdk_nvme_ns *ns)
281 : : {
282 : 1796296 : return ns->extended_lba_size;
283 : : }
284 : :
285 : : uint64_t
286 : 1301 : spdk_nvme_ns_get_num_sectors(struct spdk_nvme_ns *ns)
287 : : {
288 : 1301 : return _nvme_ns_get_data(ns)->nsze;
289 : : }
290 : :
291 : : uint64_t
292 : 366 : spdk_nvme_ns_get_size(struct spdk_nvme_ns *ns)
293 : : {
294 : 366 : return spdk_nvme_ns_get_num_sectors(ns) * spdk_nvme_ns_get_sector_size(ns);
295 : : }
296 : :
297 : : uint32_t
298 : 1795684 : spdk_nvme_ns_get_flags(struct spdk_nvme_ns *ns)
299 : : {
300 : 1795684 : return ns->flags;
301 : : }
302 : :
303 : : enum spdk_nvme_pi_type
304 : 242 : spdk_nvme_ns_get_pi_type(struct spdk_nvme_ns *ns) {
305 : 242 : return ns->pi_type;
306 : : }
307 : :
308 : : bool
309 : 202 : spdk_nvme_ns_supports_extended_lba(struct spdk_nvme_ns *ns)
310 : : {
311 : 202 : return (ns->flags & SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED) ? true : false;
312 : : }
313 : :
314 : : bool
315 : 3477 : spdk_nvme_ns_supports_compare(struct spdk_nvme_ns *ns)
316 : : {
317 : 3477 : return (ns->flags & SPDK_NVME_NS_COMPARE_SUPPORTED) ? true : false;
318 : : }
319 : :
320 : : uint32_t
321 : 1796266 : spdk_nvme_ns_get_md_size(struct spdk_nvme_ns *ns)
322 : : {
323 : 1796266 : return ns->md_size;
324 : : }
325 : :
326 : : uint32_t
327 : 4462 : spdk_nvme_ns_get_format_index(const struct spdk_nvme_ns_data *nsdata)
328 : : {
329 [ + - ]: 4462 : if (nsdata->nlbaf < 16) {
330 : 4462 : return nsdata->flbas.format;
331 : : } else {
332 [ # # ]: 0 : return ((nsdata->flbas.msb_format << 4) + nsdata->flbas.format);
333 : : }
334 : : }
335 : :
336 : : const struct spdk_nvme_ns_data *
337 : 2565 : spdk_nvme_ns_get_data(struct spdk_nvme_ns *ns)
338 : : {
339 : 2565 : return _nvme_ns_get_data(ns);
340 : : }
341 : :
342 : : /* We have to use the typedef in the function declaration to appease astyle. */
343 : : typedef enum spdk_nvme_dealloc_logical_block_read_value
344 : : spdk_nvme_dealloc_logical_block_read_value_t;
345 : :
346 : : spdk_nvme_dealloc_logical_block_read_value_t
347 : 81 : spdk_nvme_ns_get_dealloc_logical_block_read_value(
348 : : struct spdk_nvme_ns *ns)
349 : : {
350 : 81 : struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr;
351 : 81 : const struct spdk_nvme_ns_data *data = spdk_nvme_ns_get_data(ns);
352 : :
353 [ + + ]: 81 : if (ctrlr->quirks & NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE) {
354 : 12 : return SPDK_NVME_DEALLOC_READ_00;
355 : : } else {
356 : 69 : return data->dlfeat.bits.read_value;
357 : : }
358 : : }
359 : :
360 : : uint32_t
361 : 922 : spdk_nvme_ns_get_optimal_io_boundary(struct spdk_nvme_ns *ns)
362 : : {
363 : 922 : return ns->sectors_per_stripe;
364 : : }
365 : :
366 : : static const void *
367 : 3380 : nvme_ns_find_id_desc(const struct spdk_nvme_ns *ns, enum spdk_nvme_nidt type, size_t *length)
368 : : {
369 : : const struct spdk_nvme_ns_id_desc *desc;
370 : : size_t offset;
371 : :
372 : 3380 : offset = 0;
373 [ + - ]: 6333 : while (offset + 4 < sizeof(ns->id_desc_list)) {
374 : 6333 : desc = (const struct spdk_nvme_ns_id_desc *)&ns->id_desc_list[offset];
375 : :
376 [ + + ]: 6333 : if (desc->nidl == 0) {
377 : : /* End of list */
378 : 2199 : return NULL;
379 : : }
380 : :
381 : : /*
382 : : * Check if this descriptor fits within the list.
383 : : * 4 is the fixed-size descriptor header (not counted in NIDL).
384 : : */
385 [ - + ]: 4134 : if (offset + desc->nidl + 4 > sizeof(ns->id_desc_list)) {
386 : : /* Descriptor longer than remaining space in list (invalid) */
387 : 0 : return NULL;
388 : : }
389 : :
390 [ + + ]: 4134 : if (desc->nidt == type) {
391 : 1181 : *length = desc->nidl;
392 : 1181 : return &desc->nid[0];
393 : : }
394 : :
395 : 2953 : offset += 4 + desc->nidl;
396 : : }
397 : :
398 : 0 : return NULL;
399 : : }
400 : :
401 : : const uint8_t *
402 : 910 : spdk_nvme_ns_get_nguid(const struct spdk_nvme_ns *ns)
403 : : {
404 : : const uint8_t *nguid;
405 : 369 : size_t size;
406 : :
407 : 910 : nguid = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_NGUID, &size);
408 [ + + - + ]: 910 : if (nguid && size != SPDK_SIZEOF_MEMBER(struct spdk_nvme_ns_data, nguid)) {
409 : 0 : SPDK_WARNLOG("Invalid NIDT_NGUID descriptor length reported: %zu (expected: %zu)\n",
410 : : size, SPDK_SIZEOF_MEMBER(struct spdk_nvme_ns_data, nguid));
411 : 0 : return NULL;
412 : : }
413 : :
414 : 910 : return nguid;
415 : : }
416 : :
417 : : const struct spdk_uuid *
418 : 784 : spdk_nvme_ns_get_uuid(const struct spdk_nvme_ns *ns)
419 : : {
420 : : const struct spdk_uuid *uuid;
421 : 379 : size_t uuid_size;
422 : :
423 : 784 : uuid = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_UUID, &uuid_size);
424 [ + + - + ]: 784 : if (uuid && uuid_size != sizeof(*uuid)) {
425 : 0 : SPDK_WARNLOG("Invalid NIDT_UUID descriptor length reported: %zu (expected: %zu)\n",
426 : : uuid_size, sizeof(*uuid));
427 : 0 : return NULL;
428 : : }
429 : :
430 : 784 : return uuid;
431 : : }
432 : :
433 : : static enum spdk_nvme_csi
434 : 1668 : nvme_ns_get_csi(const struct spdk_nvme_ns *ns) {
435 : : const uint8_t *csi;
436 : 488 : size_t csi_size;
437 : :
438 : 1668 : csi = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_CSI, &csi_size);
439 [ + + - + ]: 1668 : if (csi && csi_size != sizeof(*csi))
440 : : {
441 : 0 : SPDK_WARNLOG("Invalid NIDT_CSI descriptor length reported: %zu (expected: %zu)\n",
442 : : csi_size, sizeof(*csi));
443 : 0 : return SPDK_NVME_CSI_NVM;
444 : : }
445 [ + + ]: 1668 : if (!csi)
446 : : {
447 [ + + ]: 866 : if (ns->ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS) {
448 : 6 : SPDK_WARNLOG("CSI not reported for NSID: %" PRIu32 "\n", ns->id);
449 : : }
450 : 866 : return SPDK_NVME_CSI_NVM;
451 : : }
452 : :
453 : 802 : return *csi;
454 : : }
455 : :
456 : : void
457 : 1644 : nvme_ns_set_id_desc_list_data(struct spdk_nvme_ns *ns)
458 : : {
459 : 1644 : ns->csi = nvme_ns_get_csi(ns);
460 : 1644 : }
461 : :
462 : : enum spdk_nvme_csi
463 : 1645 : spdk_nvme_ns_get_csi(const struct spdk_nvme_ns *ns) {
464 : 1645 : return ns->csi;
465 : : }
466 : :
467 : : void
468 : 1718 : nvme_ns_free_zns_specific_data(struct spdk_nvme_ns *ns)
469 : : {
470 [ - + ]: 1718 : if (!ns->id) {
471 : 0 : return;
472 : : }
473 : :
474 [ + + ]: 1718 : if (ns->nsdata_zns) {
475 : 8 : spdk_free(ns->nsdata_zns);
476 : 8 : ns->nsdata_zns = NULL;
477 : : }
478 : : }
479 : :
480 : : void
481 : 1706 : nvme_ns_free_iocs_specific_data(struct spdk_nvme_ns *ns)
482 : : {
483 : 1706 : nvme_ns_free_zns_specific_data(ns);
484 : 1706 : }
485 : :
486 : : bool
487 : 808 : nvme_ns_has_supported_iocs_specific_data(struct spdk_nvme_ns *ns)
488 : : {
489 [ + + + ]: 808 : switch (ns->csi) {
490 : 794 : case SPDK_NVME_CSI_NVM:
491 : : /*
492 : : * NVM Command Set Specific Identify Namespace data structure
493 : : * is currently all-zeroes, reserved for future use.
494 : : */
495 : 794 : return false;
496 : 8 : case SPDK_NVME_CSI_ZNS:
497 : 8 : return true;
498 : 6 : default:
499 : 6 : SPDK_WARNLOG("Unsupported CSI: %u for NSID: %u\n", ns->csi, ns->id);
500 : 6 : return false;
501 : : }
502 : : }
503 : :
504 : : uint32_t
505 : 6 : spdk_nvme_ns_get_ana_group_id(const struct spdk_nvme_ns *ns)
506 : : {
507 : 6 : return ns->ana_group_id;
508 : : }
509 : :
510 : : enum spdk_nvme_ana_state
511 : 6 : spdk_nvme_ns_get_ana_state(const struct spdk_nvme_ns *ns) {
512 : 6 : return ns->ana_state;
513 : : }
514 : :
515 : : int
516 : 223 : nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id,
517 : : struct spdk_nvme_ctrlr *ctrlr)
518 : : {
519 : : int rc;
520 : :
521 [ - + ]: 223 : assert(id > 0);
522 : :
523 : 223 : ns->ctrlr = ctrlr;
524 : 223 : ns->id = id;
525 : : /* This will be overwritten when reading ANA log page. */
526 : 223 : ns->ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
527 : :
528 : 223 : rc = nvme_ctrlr_identify_ns(ns);
529 [ - + ]: 223 : if (rc != 0) {
530 : 0 : return rc;
531 : : }
532 : :
533 : : /* skip Identify NS ID Descriptor List for inactive NS */
534 [ + + ]: 223 : if (!spdk_nvme_ns_is_active(ns)) {
535 : 60 : return 0;
536 : : }
537 : :
538 : 163 : rc = nvme_ctrlr_identify_id_desc(ns);
539 [ - + ]: 163 : if (rc != 0) {
540 : 0 : return rc;
541 : : }
542 : :
543 [ + + - + ]: 169 : if (nvme_ctrlr_multi_iocs_enabled(ctrlr) &&
544 : 6 : nvme_ns_has_supported_iocs_specific_data(ns)) {
545 : 0 : rc = nvme_ctrlr_identify_ns_iocs_specific(ns);
546 [ # # ]: 0 : if (rc != 0) {
547 : 0 : return rc;
548 : : }
549 : : }
550 : :
551 : 163 : return 0;
552 : : }
553 : :
554 : : void
555 : 1566 : nvme_ns_destruct(struct spdk_nvme_ns *ns)
556 : : {
557 : : struct spdk_nvme_ns_data *nsdata;
558 : :
559 [ - + ]: 1566 : if (!ns->id) {
560 : 0 : return;
561 : : }
562 : :
563 : 1566 : nsdata = _nvme_ns_get_data(ns);
564 [ - + ]: 1566 : memset(nsdata, 0, sizeof(*nsdata));
565 [ - + ]: 1566 : memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
566 : 1566 : nvme_ns_free_iocs_specific_data(ns);
567 : 1566 : ns->sector_size = 0;
568 : 1566 : ns->extended_lba_size = 0;
569 : 1566 : ns->md_size = 0;
570 : 1566 : ns->pi_type = 0;
571 : 1566 : ns->sectors_per_max_io = 0;
572 : 1566 : ns->sectors_per_max_io_no_md = 0;
573 : 1566 : ns->sectors_per_stripe = 0;
574 : 1566 : ns->flags = 0;
575 : 1566 : ns->csi = SPDK_NVME_CSI_NVM;
576 : : }
|