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 : 85440 : _nvme_ns_get_data(struct spdk_nvme_ns *ns)
10 : : {
11 [ + - ]: 85440 : 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 : 2824 : nvme_ns_set_identify_data(struct spdk_nvme_ns *ns)
22 : : {
23 : 13 : struct spdk_nvme_ns_data *nsdata;
24 : 13 : uint32_t format_index;
25 : :
26 : 2824 : nsdata = _nvme_ns_get_data(ns);
27 : :
28 [ + - + - ]: 2824 : ns->flags = 0x0000;
29 : 2824 : format_index = spdk_nvme_ns_get_format_index(nsdata);
30 : :
31 [ + + + - : 2824 : ns->sector_size = 1 << nsdata->lbaf[format_index].lbads;
+ - + - -
+ + - + -
+ - ]
32 [ + - + - : 2824 : ns->extended_lba_size = ns->sector_size;
+ - + - ]
33 : :
34 [ + - + - : 2824 : ns->md_size = nsdata->lbaf[format_index].ms;
+ - + - +
- + - ]
35 [ + + + - : 2824 : if (nsdata->flbas.extended) {
+ + ]
36 [ + - + - ]: 12 : ns->flags |= SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED;
37 [ + - + - : 12 : ns->extended_lba_size += ns->md_size;
+ - + - ]
38 : 2 : }
39 : :
40 [ + + + - : 2824 : ns->sectors_per_max_io = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->extended_lba_size;
+ - + - +
- ]
41 [ + + + - : 2824 : ns->sectors_per_max_io_no_md = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->sector_size;
+ - + - +
- ]
42 [ + + + - : 2824 : if (ns->ctrlr->quirks & NVME_QUIRK_MDTS_EXCLUDE_MD) {
+ - + - +
+ ]
43 [ + - + - : 6 : ns->sectors_per_max_io = ns->sectors_per_max_io_no_md;
+ - + - ]
44 : 1 : }
45 : :
46 [ + + + - : 2824 : if (nsdata->noiob) {
+ + ]
47 [ + - + - : 83 : ns->sectors_per_stripe = nsdata->noiob;
+ - + - ]
48 [ + + + + : 83 : SPDK_DEBUGLOG(nvme, "ns %u optimal IO boundary %" PRIu32 " blocks\n",
+ - # # #
# # # #
# ]
49 : : ns->id, ns->sectors_per_stripe);
50 [ + + + - : 2745 : } else if (ns->ctrlr->quirks & NVME_INTEL_QUIRK_STRIPING &&
+ - + - +
+ - + ]
51 [ + - + - : 100 : ns->ctrlr->cdata.vs[3] != 0) {
+ - + - +
- + - ]
52 [ + + + + : 102 : 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 : 2 : } else {
57 [ + - + - ]: 2641 : ns->sectors_per_stripe = 0;
58 : : }
59 : :
60 [ + + + - : 2824 : if (ns->ctrlr->cdata.oncs.dsm) {
+ - + - +
- + + ]
61 [ + - + - ]: 2363 : ns->flags |= SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
62 : 1044 : }
63 : :
64 [ + + + - : 2824 : if (ns->ctrlr->cdata.oncs.compare) {
+ - + - +
- + + ]
65 [ + - + - ]: 2643 : ns->flags |= SPDK_NVME_NS_COMPARE_SUPPORTED;
66 : 1042 : }
67 : :
68 [ + + + - : 2824 : if (ns->ctrlr->cdata.vwc.present) {
+ - + - +
- + + ]
69 [ + - + - ]: 2630 : ns->flags |= SPDK_NVME_NS_FLUSH_SUPPORTED;
70 : 1042 : }
71 : :
72 [ + + + - : 2824 : if (ns->ctrlr->cdata.oncs.write_zeroes) {
+ - + - +
- + + ]
73 [ + - + - ]: 2653 : ns->flags |= SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
74 : 1042 : }
75 : :
76 [ + + + - : 2824 : if (ns->ctrlr->cdata.oncs.write_unc) {
+ - + - +
- + + ]
77 [ + - + - ]: 140 : ns->flags |= SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED;
78 : 4 : }
79 : :
80 [ + + + - : 2824 : if (nsdata->nsrescap.raw) {
+ - + + ]
81 [ + - + - ]: 1857 : ns->flags |= SPDK_NVME_NS_RESERVATION_SUPPORTED;
82 : 1042 : }
83 : :
84 [ + - + - ]: 2824 : ns->pi_type = SPDK_NVME_FMT_NVM_PROTECTION_DISABLE;
85 [ + + + + : 2824 : 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 : 2 : }
89 : 2824 : }
90 : :
91 : : static int
92 : 211 : nvme_ctrlr_identify_ns(struct spdk_nvme_ns *ns)
93 : : {
94 : 11 : struct nvme_completion_poll_status *status;
95 : 11 : struct spdk_nvme_ns_data *nsdata;
96 : 11 : int rc;
97 : :
98 : 211 : status = calloc(1, sizeof(*status));
99 [ + + ]: 211 : if (!status) {
100 : 0 : SPDK_ERRLOG("Failed to allocate status tracker\n");
101 : 0 : return -ENOMEM;
102 : : }
103 : :
104 : 211 : nsdata = _nvme_ns_get_data(ns);
105 [ + - + - : 211 : rc = nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS, 0, ns->id, 0,
+ - + - ]
106 : 11 : nsdata, sizeof(*nsdata),
107 : 11 : nvme_completion_poll_cb, status);
108 [ - + ]: 211 : if (rc != 0) {
109 : 0 : free(status);
110 : 0 : return rc;
111 : : }
112 : :
113 [ + + + - : 222 : if (nvme_wait_for_completion_robust_lock(ns->ctrlr->adminq, status,
+ - + - -
+ ]
114 [ + - + - : 211 : &ns->ctrlr->ctrlr_lock)) {
+ - ]
115 [ # # # # : 0 : if (!status->timed_out) {
# # # # ]
116 : 0 : free(status);
117 : 0 : }
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 : 211 : free(status);
124 : :
125 : 211 : nvme_ns_set_identify_data(ns);
126 : :
127 : 211 : return 0;
128 : 11 : }
129 : :
130 : : static int
131 : 6 : nvme_ctrlr_identify_ns_iocs_specific(struct spdk_nvme_ns *ns)
132 : : {
133 : 1 : struct nvme_completion_poll_status *status;
134 [ + - + - ]: 6 : struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr;
135 : 1 : struct spdk_nvme_zns_ns_data *nsdata_zns;
136 : 1 : int rc;
137 : :
138 [ + - + - : 6 : switch (ns->csi) {
+ - ]
139 : 5 : 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 : 1 : nsdata_zns, sizeof(*nsdata_zns),
167 : 1 : 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 : 0 : }
180 : 0 : return -ENXIO;
181 : : }
182 : 6 : free(status);
183 [ + - + - ]: 6 : ns->nsdata_zns = nsdata_zns;
184 : :
185 : 6 : return 0;
186 : 1 : }
187 : :
188 : : static int
189 : 163 : nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns)
190 : : {
191 : 3 : struct nvme_completion_poll_status *status;
192 : 3 : int rc;
193 : :
194 [ + + + - ]: 163 : memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
195 : :
196 [ + + + - : 166 : if ((ns->ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) &&
+ - + - +
- + - + -
+ + + + ]
197 [ + + + - : 12 : !(ns->ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS)) ||
+ - + - +
- + - ]
198 [ + + + - : 153 : (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 : 151 : status = calloc(1, sizeof(*status));
204 [ + + ]: 151 : if (!status) {
205 : 0 : SPDK_ERRLOG("Failed to allocate status tracker\n");
206 : 0 : return -ENOMEM;
207 : : }
208 : :
209 [ + + + + : 151 : SPDK_DEBUGLOG(nvme, "Attempting to retrieve NS ID Descriptor List\n");
+ - ]
210 [ + - + - : 151 : rc = nvme_ctrlr_cmd_identify(ns->ctrlr, SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST, 0, ns->id,
+ - + - ]
211 [ + - ]: 151 : 0, ns->id_desc_list, sizeof(ns->id_desc_list),
212 : 1 : nvme_completion_poll_cb, status);
213 [ + + ]: 151 : if (rc < 0) {
214 : 0 : free(status);
215 : 0 : return rc;
216 : : }
217 : :
218 [ + - + - : 151 : rc = nvme_wait_for_completion_robust_lock(ns->ctrlr->adminq, status, &ns->ctrlr->ctrlr_lock);
+ - + - +
- + - +
- ]
219 [ + + ]: 151 : 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 : 0 : }
223 : :
224 [ + + + - : 151 : if (!status->timed_out) {
+ - - + ]
225 : 151 : free(status);
226 : 1 : }
227 : :
228 : 151 : nvme_ns_set_id_desc_list_data(ns);
229 : :
230 : 151 : return rc;
231 : 3 : }
232 : :
233 : : uint32_t
234 : 3292 : spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns)
235 : : {
236 [ + - + - ]: 3292 : return ns->id;
237 : : }
238 : :
239 : : bool
240 : 610 : spdk_nvme_ns_is_active(struct spdk_nvme_ns *ns)
241 : : {
242 : 610 : const struct spdk_nvme_ns_data *nsdata = NULL;
243 : :
244 : : /*
245 : : * According to the spec, valid NS has non-zero id.
246 : : */
247 [ + + + - : 610 : if (ns->id == 0) {
+ + ]
248 : 6 : return false;
249 : : }
250 : :
251 : 604 : 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 [ + - + - ]: 604 : return nsdata->ncap != 0;
259 : 16 : }
260 : :
261 : : struct spdk_nvme_ctrlr *
262 : 2670675 : spdk_nvme_ns_get_ctrlr(struct spdk_nvme_ns *ns)
263 : : {
264 [ + - + - ]: 2670675 : return ns->ctrlr;
265 : : }
266 : :
267 : : uint32_t
268 : 5977 : spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns)
269 : : {
270 [ + - + - : 5977 : return ns->ctrlr->max_xfer_size;
+ - + - ]
271 : : }
272 : :
273 : : uint32_t
274 : 2317 : spdk_nvme_ns_get_sector_size(struct spdk_nvme_ns *ns)
275 : : {
276 [ + - + - ]: 2317 : return ns->sector_size;
277 : : }
278 : :
279 : : uint32_t
280 : 1897775 : spdk_nvme_ns_get_extended_sector_size(struct spdk_nvme_ns *ns)
281 : : {
282 [ + - + - ]: 1897775 : return ns->extended_lba_size;
283 : : }
284 : :
285 : : uint64_t
286 : 76700 : spdk_nvme_ns_get_num_sectors(struct spdk_nvme_ns *ns)
287 : : {
288 [ + - + - ]: 76700 : 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 : 1897193 : spdk_nvme_ns_get_flags(struct spdk_nvme_ns *ns)
299 : : {
300 [ + - + - ]: 1897193 : 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 : 3482 : spdk_nvme_ns_supports_compare(struct spdk_nvme_ns *ns)
316 : : {
317 [ + - + - ]: 3482 : return (ns->flags & SPDK_NVME_NS_COMPARE_SUPPORTED) ? true : false;
318 : : }
319 : :
320 : : uint32_t
321 : 1897745 : spdk_nvme_ns_get_md_size(struct spdk_nvme_ns *ns)
322 : : {
323 [ + - + - ]: 1897745 : return ns->md_size;
324 : : }
325 : :
326 : : uint32_t
327 : 6484 : spdk_nvme_ns_get_format_index(const struct spdk_nvme_ns_data *nsdata)
328 : : {
329 [ + - + - : 6484 : if (nsdata->nlbaf < 16) {
+ - ]
330 [ + - + - ]: 6484 : return nsdata->flbas.format;
331 : : } else {
332 [ # # # # : 0 : return ((nsdata->flbas.msb_format << 4) + nsdata->flbas.format);
# # # # #
# # # #
# ]
333 : : }
334 : 2095 : }
335 : :
336 : : const struct spdk_nvme_ns_data *
337 : 2538 : spdk_nvme_ns_get_data(struct spdk_nvme_ns *ns)
338 : : {
339 : 2538 : 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 : 80 : spdk_nvme_ns_get_dealloc_logical_block_read_value(
348 : : struct spdk_nvme_ns *ns)
349 : : {
350 [ + - + - ]: 80 : struct spdk_nvme_ctrlr *ctrlr = ns->ctrlr;
351 : 80 : const struct spdk_nvme_ns_data *data = spdk_nvme_ns_get_data(ns);
352 : :
353 [ + + + - : 80 : if (ctrlr->quirks & NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE) {
+ + ]
354 : 12 : return SPDK_NVME_DEALLOC_READ_00;
355 : : } else {
356 [ + - + - : 68 : return data->dlfeat.bits.read_value;
+ - ]
357 : : }
358 : 2 : }
359 : :
360 : : uint32_t
361 : 891 : spdk_nvme_ns_get_optimal_io_boundary(struct spdk_nvme_ns *ns)
362 : : {
363 [ + - + - ]: 891 : return ns->sectors_per_stripe;
364 : : }
365 : :
366 : : static const void *
367 : 4309 : nvme_ns_find_id_desc(const struct spdk_nvme_ns *ns, enum spdk_nvme_nidt type, size_t *length)
368 : : {
369 : 13 : const struct spdk_nvme_ns_id_desc *desc;
370 : 13 : size_t offset;
371 : :
372 : 4309 : offset = 0;
373 [ + - ]: 9249 : while (offset + 4 < sizeof(ns->id_desc_list)) {
374 [ + - + - : 9249 : desc = (const struct spdk_nvme_ns_id_desc *)&ns->id_desc_list[offset];
+ - ]
375 : :
376 [ + + + - : 9249 : if (desc->nidl == 0) {
+ + ]
377 : : /* End of list */
378 : 3161 : 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 [ + + + - : 6088 : 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 [ + + + - : 6088 : if (desc->nidt == type) {
+ + ]
391 [ - + - + : 1148 : *length = desc->nidl;
- + ]
392 [ - + - + ]: 1148 : return &desc->nid[0];
393 : : }
394 : :
395 [ + - + - : 4940 : offset += 4 + desc->nidl;
+ - ]
396 : : }
397 : :
398 : 0 : return NULL;
399 : 1055 : }
400 : :
401 : : const uint8_t *
402 : 879 : spdk_nvme_ns_get_nguid(const struct spdk_nvme_ns *ns)
403 : : {
404 : 0 : const uint8_t *nguid;
405 : 337 : size_t size;
406 : :
407 : 879 : nguid = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_NGUID, &size);
408 [ + + - + ]: 879 : 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 : 879 : return nguid;
415 : 1 : }
416 : :
417 : : const struct spdk_uuid *
418 : 752 : spdk_nvme_ns_get_uuid(const struct spdk_nvme_ns *ns)
419 : : {
420 : 5 : const struct spdk_uuid *uuid;
421 : 346 : size_t uuid_size;
422 : :
423 : 752 : uuid = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_UUID, &uuid_size);
424 [ + + - + ]: 752 : 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 : 752 : return uuid;
431 : 6 : }
432 : :
433 : : static enum spdk_nvme_csi
434 : 2660 : nvme_ns_get_csi(const struct spdk_nvme_ns *ns) {
435 : 5 : const uint8_t *csi;
436 : 456 : size_t csi_size;
437 : :
438 : 2660 : csi = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_CSI, &csi_size);
439 [ + + + + ]: 2660 : 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 [ + + ]: 2660 : if (!csi)
446 : : {
447 [ + + + - : 1891 : 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 : 1 : }
450 : 1891 : return SPDK_NVME_CSI_NVM;
451 : : }
452 : :
453 [ + - ]: 769 : return *csi;
454 : 1045 : }
455 : :
456 : : void
457 : 2636 : nvme_ns_set_id_desc_list_data(struct spdk_nvme_ns *ns)
458 : : {
459 [ + - + - ]: 2636 : ns->csi = nvme_ns_get_csi(ns);
460 : 2636 : }
461 : :
462 : : enum spdk_nvme_csi
463 : 1608 : spdk_nvme_ns_get_csi(const struct spdk_nvme_ns *ns) {
464 [ + - + - ]: 1608 : return ns->csi;
465 : : }
466 : :
467 : : void
468 : 2714 : nvme_ns_free_zns_specific_data(struct spdk_nvme_ns *ns)
469 : : {
470 [ + + + - : 2714 : if (!ns->id) {
+ - ]
471 : 0 : return;
472 : : }
473 : :
474 [ + + + - : 2714 : if (ns->nsdata_zns) {
+ + ]
475 [ + - + - ]: 8 : spdk_free(ns->nsdata_zns);
476 [ + - + - ]: 8 : ns->nsdata_zns = NULL;
477 : 1 : }
478 : 1054 : }
479 : :
480 : : void
481 : 2702 : nvme_ns_free_iocs_specific_data(struct spdk_nvme_ns *ns)
482 : : {
483 : 2702 : nvme_ns_free_zns_specific_data(ns);
484 : 2702 : }
485 : :
486 : : bool
487 : 775 : nvme_ns_has_supported_iocs_specific_data(struct spdk_nvme_ns *ns)
488 : : {
489 [ + + + - : 775 : switch (ns->csi) {
+ + + ]
490 : 759 : 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 : 761 : return false;
496 : 7 : case SPDK_NVME_CSI_ZNS:
497 : 8 : return true;
498 : 5 : default:
499 [ - + - + : 6 : SPDK_WARNLOG("Unsupported CSI: %u for NSID: %u\n", ns->csi, ns->id);
- + - + ]
500 : 6 : return false;
501 : : }
502 : 4 : }
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 : 211 : nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id,
517 : : struct spdk_nvme_ctrlr *ctrlr)
518 : : {
519 : 11 : int rc;
520 : :
521 [ + + # # ]: 211 : assert(id > 0);
522 : :
523 [ + - + - ]: 211 : ns->ctrlr = ctrlr;
524 [ + - + - ]: 211 : ns->id = id;
525 : : /* This will be overwritten when reading ANA log page. */
526 [ + - + - ]: 211 : ns->ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
527 : :
528 : 211 : rc = nvme_ctrlr_identify_ns(ns);
529 [ - + ]: 211 : if (rc != 0) {
530 : 0 : return rc;
531 : : }
532 : :
533 : : /* skip Identify NS ID Descriptor List for inactive NS */
534 [ + + ]: 211 : if (!spdk_nvme_ns_is_active(ns)) {
535 : 60 : return 0;
536 : : }
537 : :
538 : 151 : rc = nvme_ctrlr_identify_id_desc(ns);
539 [ - + ]: 151 : if (rc != 0) {
540 : 0 : return rc;
541 : : }
542 : :
543 [ + + + + ]: 156 : 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 : 0 : }
550 : :
551 : 151 : return 0;
552 : 11 : }
553 : :
554 : : void
555 : 2563 : nvme_ns_destruct(struct spdk_nvme_ns *ns)
556 : : {
557 : 10 : struct spdk_nvme_ns_data *nsdata;
558 : :
559 [ + + + - : 2563 : if (!ns->id) {
+ - ]
560 : 0 : return;
561 : : }
562 : :
563 : 2563 : nsdata = _nvme_ns_get_data(ns);
564 [ + + ]: 2563 : memset(nsdata, 0, sizeof(*nsdata));
565 [ + + + + ]: 2563 : memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
566 : 2563 : nvme_ns_free_iocs_specific_data(ns);
567 [ + + + + ]: 2563 : ns->sector_size = 0;
568 [ + + + + ]: 2563 : ns->extended_lba_size = 0;
569 [ + + + + ]: 2563 : ns->md_size = 0;
570 [ + + + + ]: 2563 : ns->pi_type = 0;
571 [ + + + + ]: 2563 : ns->sectors_per_max_io = 0;
572 [ + + + + ]: 2563 : ns->sectors_per_max_io_no_md = 0;
573 [ + + + + ]: 2563 : ns->sectors_per_stripe = 0;
574 [ + + + + ]: 2563 : ns->flags = 0;
575 [ + + + + ]: 2563 : ns->csi = SPDK_NVME_CSI_NVM;
576 [ - + ]: 1052 : }
|