On Thu, Feb 16, 2023 at 05:48:06PM +0100, Jesper Devantier wrote: > +static bool nvme_ns_init_fdp(NvmeNamespace *ns, Error **errp) > +{ > + NvmeEnduranceGroup *endgrp = ns->endgrp; > + NvmeRuHandle *ruh; > + uint8_t lbafi = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); > + unsigned int *ruhid, *ruhids; > + char *r, *p, *token; > + uint16_t *ph; > + > + if (!ns->params.fdp.ruhs) { > + ns->fdp.nphs = 1; > + ph = ns->fdp.phs = g_new(uint16_t, 1); > + > + ruh = nvme_find_ruh_by_attr(endgrp, NVME_RUHA_CTRL, ph); > + if (!ruh) { > + ruh = nvme_find_ruh_by_attr(endgrp, NVME_RUHA_UNUSED, ph); > + if (!ruh) { > + error_setg(errp, "no unused reclaim unit handles left"); > + return false; > + } > + > + ruh->ruha = NVME_RUHA_CTRL; > + ruh->lbafi = lbafi; > + ruh->ruamw = endgrp->fdp.runs >> ns->lbaf.ds; > + > + for (uint16_t rg = 0; rg < endgrp->fdp.nrg; rg++) { > + ruh->rus[rg].ruamw = ruh->ruamw; > + } > + } else if (ruh->lbafi != lbafi) { > + error_setg(errp, "lba format index of controller assigned " > + "reclaim unit handle does not match namespace lba " > + "format index"); > + return false; > + } > + > + return true; > + } > + > + ruhid = ruhids = g_new0(unsigned int, endgrp->fdp.nruh); > + r = p = strdup(ns->params.fdp.ruhs); > + > + /* parse the reclaim unit handle identifiers */ > + while ((token = qemu_strsep(&p, ";")) != NULL) { > + if (++ns->fdp.nphs == endgrp->fdp.nruh) {
Since a namespace can't have more than 128 placement handles, and the endurance group can have more, I think the 128 limit needs to be checked here. > + error_setg(errp, "too many placement handles"); > + free(r); > + return false; > + } > + > + if (qemu_strtoui(token, NULL, 0, ruhid++) < 0) { > + error_setg(errp, "cannot parse reclaim unit handle identifier"); > + free(r); > + return false; > + } > + }