Lines Matching full:ns

30 void nvme_ns_init_format(NvmeNamespace *ns)  in nvme_ns_init_format()  argument
32 NvmeIdNs *id_ns = &ns->id_ns; in nvme_ns_init_format()
33 NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm; in nvme_ns_init_format()
38 ns->lbaf = id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)]; in nvme_ns_init_format()
39 ns->lbasz = 1 << ns->lbaf.ds; in nvme_ns_init_format()
41 nlbas = ns->size / (ns->lbasz + ns->lbaf.ms); in nvme_ns_init_format()
49 ns->moff = nlbas << ns->lbaf.ds; in nvme_ns_init_format()
51 npdg = ns->blkconf.discard_granularity / ns->lbasz; in nvme_ns_init_format()
53 ret = bdrv_get_info(blk_bs(ns->blkconf.blk), &bdi); in nvme_ns_init_format()
54 if (ret >= 0 && bdi.cluster_size > ns->blkconf.discard_granularity) { in nvme_ns_init_format()
55 npdg = bdi.cluster_size / ns->lbasz; in nvme_ns_init_format()
63 static int nvme_ns_init(NvmeNamespace *ns, Error **errp) in nvme_ns_init() argument
66 NvmeIdNs *id_ns = &ns->id_ns; in nvme_ns_init()
67 NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm; in nvme_ns_init()
68 NvmeIdNsInd *id_ns_ind = &ns->id_ns_ind; in nvme_ns_init()
73 ns->csi = NVME_CSI_NVM; in nvme_ns_init()
74 ns->status = 0x0; in nvme_ns_init()
76 ns->id_ns.dlfeat = 0x1; in nvme_ns_init()
81 if (ns->params.shared) { in nvme_ns_init()
89 if (!ns->params.eui64 && ns->params.eui64_default) { in nvme_ns_init()
90 ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT; in nvme_ns_init()
94 id_ns->mssrl = cpu_to_le16(ns->params.mssrl); in nvme_ns_init()
95 id_ns->mcl = cpu_to_le32(ns->params.mcl); in nvme_ns_init()
96 id_ns->msrc = ns->params.msrc; in nvme_ns_init()
97 id_ns->eui64 = cpu_to_be64(ns->params.eui64); in nvme_ns_init()
98 memcpy(&id_ns->nguid, &ns->params.nguid.data, sizeof(id_ns->nguid)); in nvme_ns_init()
100 ds = 31 - clz32(ns->blkconf.logical_block_size); in nvme_ns_init()
101 ms = ns->params.ms; in nvme_ns_init()
105 if (ms && ns->params.mset) { in nvme_ns_init()
110 id_ns->dps = ns->params.pi; in nvme_ns_init()
111 if (ns->params.pi && ns->params.pil) { in nvme_ns_init()
115 ns->pif = ns->params.pif; in nvme_ns_init()
128 ns->nlbaf = 8; in nvme_ns_init()
132 for (i = 0; i < ns->nlbaf; i++) { in nvme_ns_init()
143 id_ns->lbaf[ns->nlbaf].ds = ds; in nvme_ns_init()
144 id_ns->lbaf[ns->nlbaf].ms = ms; in nvme_ns_init()
145 ns->nlbaf++; in nvme_ns_init()
151 id_ns_nvm->elbaf[i] = (ns->pif & 0x3) << 7; in nvme_ns_init()
152 id_ns->nlbaf = ns->nlbaf - 1; in nvme_ns_init()
153 nvme_ns_init_format(ns); in nvme_ns_init()
158 static int nvme_ns_init_blk(NvmeNamespace *ns, Error **errp) in nvme_ns_init_blk() argument
162 if (!blkconf_blocksizes(&ns->blkconf, errp)) { in nvme_ns_init_blk()
166 read_only = !blk_supports_write_perm(ns->blkconf.blk); in nvme_ns_init_blk()
167 if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) { in nvme_ns_init_blk()
171 if (ns->blkconf.discard_granularity == -1) { in nvme_ns_init_blk()
172 ns->blkconf.discard_granularity = in nvme_ns_init_blk()
173 MAX(ns->blkconf.logical_block_size, MIN_DISCARD_GRANULARITY); in nvme_ns_init_blk()
176 ns->size = blk_getlength(ns->blkconf.blk); in nvme_ns_init_blk()
177 if (ns->size < 0) { in nvme_ns_init_blk()
178 error_setg_errno(errp, -ns->size, "could not get blockdev size"); in nvme_ns_init_blk()
185 static int nvme_ns_zoned_check_calc_geometry(NvmeNamespace *ns, Error **errp) in nvme_ns_zoned_check_calc_geometry() argument
190 if (ns->params.zone_size_bs) { in nvme_ns_zoned_check_calc_geometry()
191 zone_size = ns->params.zone_size_bs; in nvme_ns_zoned_check_calc_geometry()
195 if (ns->params.zone_cap_bs) { in nvme_ns_zoned_check_calc_geometry()
196 zone_cap = ns->params.zone_cap_bs; in nvme_ns_zoned_check_calc_geometry()
205 if (zone_size < ns->lbasz) { in nvme_ns_zoned_check_calc_geometry()
207 "must be at least %zuB", zone_size, ns->lbasz); in nvme_ns_zoned_check_calc_geometry()
210 if (zone_cap < ns->lbasz) { in nvme_ns_zoned_check_calc_geometry()
212 "must be at least %zuB", zone_cap, ns->lbasz); in nvme_ns_zoned_check_calc_geometry()
220 ns->zone_size = zone_size / ns->lbasz; in nvme_ns_zoned_check_calc_geometry()
221 ns->zone_capacity = zone_cap / ns->lbasz; in nvme_ns_zoned_check_calc_geometry()
222 ns->num_zones = le64_to_cpu(ns->id_ns.nsze) / ns->zone_size; in nvme_ns_zoned_check_calc_geometry()
225 if (!ns->num_zones) { in nvme_ns_zoned_check_calc_geometry()
235 static void nvme_ns_zoned_init_state(NvmeNamespace *ns) in nvme_ns_zoned_init_state() argument
237 uint64_t start = 0, zone_size = ns->zone_size; in nvme_ns_zoned_init_state()
238 uint64_t capacity = ns->num_zones * zone_size; in nvme_ns_zoned_init_state()
242 ns->zone_array = g_new0(NvmeZone, ns->num_zones); in nvme_ns_zoned_init_state()
243 if (ns->params.zd_extension_size) { in nvme_ns_zoned_init_state()
244 ns->zd_extensions = g_malloc0(ns->params.zd_extension_size * in nvme_ns_zoned_init_state()
245 ns->num_zones); in nvme_ns_zoned_init_state()
248 QTAILQ_INIT(&ns->exp_open_zones); in nvme_ns_zoned_init_state()
249 QTAILQ_INIT(&ns->imp_open_zones); in nvme_ns_zoned_init_state()
250 QTAILQ_INIT(&ns->closed_zones); in nvme_ns_zoned_init_state()
251 QTAILQ_INIT(&ns->full_zones); in nvme_ns_zoned_init_state()
253 zone = ns->zone_array; in nvme_ns_zoned_init_state()
254 for (i = 0; i < ns->num_zones; i++, zone++) { in nvme_ns_zoned_init_state()
261 zone->d.zcap = ns->zone_capacity; in nvme_ns_zoned_init_state()
268 ns->zone_size_log2 = 0; in nvme_ns_zoned_init_state()
269 if (is_power_of_2(ns->zone_size)) { in nvme_ns_zoned_init_state()
270 ns->zone_size_log2 = 63 - clz64(ns->zone_size); in nvme_ns_zoned_init_state()
274 static void nvme_ns_init_zoned(NvmeNamespace *ns) in nvme_ns_init_zoned() argument
279 nvme_ns_zoned_init_state(ns); in nvme_ns_init_zoned()
284 id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1); in nvme_ns_init_zoned()
285 id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1); in nvme_ns_init_zoned()
287 id_ns_z->ozcs = ns->params.cross_zone_read ? in nvme_ns_init_zoned()
290 for (i = 0; i <= ns->id_ns.nlbaf; i++) { in nvme_ns_init_zoned()
291 id_ns_z->lbafe[i].zsze = cpu_to_le64(ns->zone_size); in nvme_ns_init_zoned()
293 ns->params.zd_extension_size >> 6; /* Units of 64B */ in nvme_ns_init_zoned()
296 if (ns->params.zrwas) { in nvme_ns_init_zoned()
297 ns->zns.numzrwa = ns->params.numzrwa ? in nvme_ns_init_zoned()
298 ns->params.numzrwa : ns->num_zones; in nvme_ns_init_zoned()
300 ns->zns.zrwas = ns->params.zrwas >> ns->lbaf.ds; in nvme_ns_init_zoned()
301 ns->zns.zrwafg = ns->params.zrwafg >> ns->lbaf.ds; in nvme_ns_init_zoned()
306 id_ns_z->numzrwa = cpu_to_le32(ns->params.numzrwa); in nvme_ns_init_zoned()
307 id_ns_z->zrwas = cpu_to_le16(ns->zns.zrwas); in nvme_ns_init_zoned()
308 id_ns_z->zrwafg = cpu_to_le16(ns->zns.zrwafg); in nvme_ns_init_zoned()
313 ns->csi = NVME_CSI_ZONED; in nvme_ns_init_zoned()
314 ns->id_ns.nsze = cpu_to_le64(ns->num_zones * ns->zone_size); in nvme_ns_init_zoned()
315 ns->id_ns.ncap = ns->id_ns.nsze; in nvme_ns_init_zoned()
316 ns->id_ns.nuse = ns->id_ns.ncap; in nvme_ns_init_zoned()
325 if (ns->zone_size % (ns->id_ns.npdg + 1)) { in nvme_ns_init_zoned()
329 ns->zone_size, ns->id_ns.npdg + 1); in nvme_ns_init_zoned()
331 ns->id_ns.nsfeat &= ~0x4; in nvme_ns_init_zoned()
334 ns->id_ns_zoned = id_ns_z; in nvme_ns_init_zoned()
337 static void nvme_clear_zone(NvmeNamespace *ns, NvmeZone *zone) in nvme_clear_zone() argument
349 nvme_aor_inc_active(ns); in nvme_clear_zone()
350 QTAILQ_INSERT_HEAD(&ns->closed_zones, zone, entry); in nvme_clear_zone()
355 ns->zns.numzrwa++; in nvme_clear_zone()
364 static void nvme_zoned_ns_shutdown(NvmeNamespace *ns) in nvme_zoned_ns_shutdown() argument
368 QTAILQ_FOREACH_SAFE(zone, &ns->closed_zones, entry, next) { in nvme_zoned_ns_shutdown()
369 QTAILQ_REMOVE(&ns->closed_zones, zone, entry); in nvme_zoned_ns_shutdown()
370 nvme_aor_dec_active(ns); in nvme_zoned_ns_shutdown()
371 nvme_clear_zone(ns, zone); in nvme_zoned_ns_shutdown()
373 QTAILQ_FOREACH_SAFE(zone, &ns->imp_open_zones, entry, next) { in nvme_zoned_ns_shutdown()
374 QTAILQ_REMOVE(&ns->imp_open_zones, zone, entry); in nvme_zoned_ns_shutdown()
375 nvme_aor_dec_open(ns); in nvme_zoned_ns_shutdown()
376 nvme_aor_dec_active(ns); in nvme_zoned_ns_shutdown()
377 nvme_clear_zone(ns, zone); in nvme_zoned_ns_shutdown()
379 QTAILQ_FOREACH_SAFE(zone, &ns->exp_open_zones, entry, next) { in nvme_zoned_ns_shutdown()
380 QTAILQ_REMOVE(&ns->exp_open_zones, zone, entry); in nvme_zoned_ns_shutdown()
381 nvme_aor_dec_open(ns); in nvme_zoned_ns_shutdown()
382 nvme_aor_dec_active(ns); in nvme_zoned_ns_shutdown()
383 nvme_clear_zone(ns, zone); in nvme_zoned_ns_shutdown()
386 assert(ns->nr_open_zones == 0); in nvme_zoned_ns_shutdown()
404 static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp) in nvme_ns_init_fdp() argument
406 NvmeEnduranceGroup *endgrp = ns->endgrp; in nvme_ns_init_fdp()
408 uint8_t lbafi = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); in nvme_ns_init_fdp()
415 if (!ns->params.fdp.ruhs) { in nvme_ns_init_fdp()
416 ns->fdp.nphs = 1; in nvme_ns_init_fdp()
417 ph = ns->fdp.phs = g_new(uint16_t, 1); in nvme_ns_init_fdp()
429 ruh->ruamw = endgrp->fdp.runs >> ns->lbaf.ds; in nvme_ns_init_fdp()
445 r = p = strdup(ns->params.fdp.ruhs); in nvme_ns_init_fdp()
475 if (ns->fdp.nphs++ == endgrp->fdp.nruh) { in nvme_ns_init_fdp()
488 for (unsigned int i = 0; i < ns->fdp.nphs; i++) { in nvme_ns_init_fdp()
489 for (unsigned int j = i + 1; j < ns->fdp.nphs; j++) { in nvme_ns_init_fdp()
498 ph = ns->fdp.phs = g_new(uint16_t, ns->fdp.nphs); in nvme_ns_init_fdp()
503 for (unsigned int i = 0; i < ns->fdp.nphs; i++, ruhid++, ph++) { in nvme_ns_init_fdp()
515 ruh->ruamw = endgrp->fdp.runs >> ns->lbaf.ds; in nvme_ns_init_fdp()
547 static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp) in nvme_ns_check_constraints() argument
551 if (!ns->blkconf.blk) { in nvme_ns_check_constraints()
556 if (ns->params.pi) { in nvme_ns_check_constraints()
557 if (ns->params.pi > NVME_ID_NS_DPS_TYPE_3) { in nvme_ns_check_constraints()
562 switch (ns->params.pif) { in nvme_ns_check_constraints()
574 if (ns->params.ms < pi_size) { in nvme_ns_check_constraints()
581 if (ns->params.nsid > NVME_MAX_NAMESPACES) { in nvme_ns_check_constraints()
587 if (ns->params.zoned && ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_check_constraints()
592 if (ns->params.zoned) { in nvme_ns_check_constraints()
593 if (ns->params.max_active_zones) { in nvme_ns_check_constraints()
594 if (ns->params.max_open_zones > ns->params.max_active_zones) { in nvme_ns_check_constraints()
596 "max_active_zones (%u)", ns->params.max_open_zones, in nvme_ns_check_constraints()
597 ns->params.max_active_zones); in nvme_ns_check_constraints()
601 if (!ns->params.max_open_zones) { in nvme_ns_check_constraints()
602 ns->params.max_open_zones = ns->params.max_active_zones; in nvme_ns_check_constraints()
606 if (ns->params.zd_extension_size) { in nvme_ns_check_constraints()
607 if (ns->params.zd_extension_size & 0x3f) { in nvme_ns_check_constraints()
612 if ((ns->params.zd_extension_size >> 6) > 0xff) { in nvme_ns_check_constraints()
619 if (ns->params.zrwas) { in nvme_ns_check_constraints()
620 if (ns->params.zrwas % ns->blkconf.logical_block_size) { in nvme_ns_check_constraints()
624 ns->params.zrwas, ns->blkconf.logical_block_size); in nvme_ns_check_constraints()
628 if (ns->params.zrwafg == -1) { in nvme_ns_check_constraints()
629 ns->params.zrwafg = ns->blkconf.logical_block_size; in nvme_ns_check_constraints()
632 if (ns->params.zrwas % ns->params.zrwafg) { in nvme_ns_check_constraints()
636 "%"PRIu64")", ns->params.zrwas, ns->params.zrwafg); in nvme_ns_check_constraints()
640 if (ns->params.max_active_zones) { in nvme_ns_check_constraints()
641 if (ns->params.numzrwa > ns->params.max_active_zones) { in nvme_ns_check_constraints()
646 ns->params.numzrwa, in nvme_ns_check_constraints()
647 ns->params.max_active_zones); in nvme_ns_check_constraints()
657 int nvme_ns_setup(NvmeNamespace *ns, Error **errp) in nvme_ns_setup() argument
659 if (nvme_ns_check_constraints(ns, errp)) { in nvme_ns_setup()
663 if (nvme_ns_init_blk(ns, errp)) { in nvme_ns_setup()
667 if (nvme_ns_init(ns, errp)) { in nvme_ns_setup()
670 if (ns->params.zoned) { in nvme_ns_setup()
671 if (nvme_ns_zoned_check_calc_geometry(ns, errp) != 0) { in nvme_ns_setup()
674 nvme_ns_init_zoned(ns); in nvme_ns_setup()
677 if (ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_setup()
678 if (!nvme_ns_init_fdp(ns, errp)) { in nvme_ns_setup()
686 void nvme_ns_drain(NvmeNamespace *ns) in nvme_ns_drain() argument
688 blk_drain(ns->blkconf.blk); in nvme_ns_drain()
691 void nvme_ns_shutdown(NvmeNamespace *ns) in nvme_ns_shutdown() argument
693 blk_flush(ns->blkconf.blk); in nvme_ns_shutdown()
694 if (ns->params.zoned) { in nvme_ns_shutdown()
695 nvme_zoned_ns_shutdown(ns); in nvme_ns_shutdown()
699 void nvme_ns_cleanup(NvmeNamespace *ns) in nvme_ns_cleanup() argument
701 if (ns->params.zoned) { in nvme_ns_cleanup()
702 g_free(ns->id_ns_zoned); in nvme_ns_cleanup()
703 g_free(ns->zone_array); in nvme_ns_cleanup()
704 g_free(ns->zd_extensions); in nvme_ns_cleanup()
707 if (ns->endgrp && ns->endgrp->fdp.enabled) { in nvme_ns_cleanup()
708 g_free(ns->fdp.phs); in nvme_ns_cleanup()
714 NvmeNamespace *ns = NVME_NS(dev); in nvme_ns_unrealize() local
716 nvme_ns_drain(ns); in nvme_ns_unrealize()
717 nvme_ns_shutdown(ns); in nvme_ns_unrealize()
718 nvme_ns_cleanup(ns); in nvme_ns_unrealize()
723 NvmeNamespace *ns = NVME_NS(dev); in nvme_ns_realize() local
727 uint32_t nsid = ns->params.nsid; in nvme_ns_realize()
731 /* If no subsys, the ns cannot be attached to more than one ctrl. */ in nvme_ns_realize()
732 ns->params.shared = false; in nvme_ns_realize()
733 if (ns->params.detached) { in nvme_ns_realize()
746 ns->subsys = subsys; in nvme_ns_realize()
747 ns->endgrp = &subsys->endgrp; in nvme_ns_realize()
750 if (nvme_ns_setup(ns, errp)) { in nvme_ns_realize()
760 nsid = ns->params.nsid = i; in nvme_ns_realize()
776 subsys->namespaces[nsid] = ns; in nvme_ns_realize()
778 ns->id_ns.endgid = cpu_to_le16(0x1); in nvme_ns_realize()
779 ns->id_ns_ind.endgrpid = cpu_to_le16(0x1); in nvme_ns_realize()
781 if (ns->params.detached) { in nvme_ns_realize()
785 if (ns->params.shared) { in nvme_ns_realize()
790 nvme_attach_ns(ctrl, ns); in nvme_ns_realize()
799 nvme_attach_ns(n, ns); in nvme_ns_realize()
855 NvmeNamespace *ns = NVME_NS(obj); in nvme_ns_instance_init() local
856 char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid); in nvme_ns_instance_init()
858 device_add_bootindex_property(obj, &ns->bootindex, "bootindex", in nvme_ns_instance_init()