diff options
author | Klaus Jensen | 2020-11-23 11:24:55 +0100 |
---|---|---|
committer | Klaus Jensen | 2021-03-18 12:34:51 +0100 |
commit | bc3a65e99254cfe001bd16a569a5aa7d20f930e8 (patch) | |
tree | 7a8af71f3ea29be60d657c2e1209bedf248298bf /hw/block/nvme-ns.c | |
parent | hw/block/nvme: fix zone management receive reporting too many zones (diff) | |
download | qemu-bc3a65e99254cfe001bd16a569a5aa7d20f930e8.tar.gz qemu-bc3a65e99254cfe001bd16a569a5aa7d20f930e8.tar.xz qemu-bc3a65e99254cfe001bd16a569a5aa7d20f930e8.zip |
hw/block/nvme: add metadata support
Add support for metadata in the form of extended logical blocks as well
as a separate buffer of data. The new `ms` nvme-ns device parameter
specifies the size of metadata per logical block in bytes. The `mset`
nvme-ns device parameter controls whether metadata is transfered as part
of an extended lba (set to '1') or in a separate buffer (set to '0',
the default).
Regardsless of the scheme chosen with `mset`, metadata is stored at the
end of the namespace backing block device. This requires the user
provided PRP/SGLs to be walked and "split" into data and metadata
scatter/gather lists if the extended logical block scheme is used, but
has the advantage of not breaking the deallocated blocks support.
Co-authored-by: Gollu Appalanaidu <anaidu.gollu@samsung.com>
Signed-off-by: Gollu Appalanaidu <anaidu.gollu@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Diffstat (limited to 'hw/block/nvme-ns.c')
-rw-r--r-- | hw/block/nvme-ns.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c index eda6a0c003..2e6bffc8e6 100644 --- a/hw/block/nvme-ns.c +++ b/hw/block/nvme-ns.c @@ -37,13 +37,25 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp) BlockDriverInfo bdi; NvmeIdNs *id_ns = &ns->id_ns; int lba_index = NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas); - int npdg; + int npdg, nlbas; ns->id_ns.dlfeat = 0x9; id_ns->lbaf[lba_index].ds = 31 - clz32(ns->blkconf.logical_block_size); + id_ns->lbaf[lba_index].ms = ns->params.ms; - id_ns->nsze = cpu_to_le64(nvme_ns_nlbas(ns)); + if (ns->params.ms) { + id_ns->mc = 0x3; + + if (ns->params.mset) { + id_ns->flbas |= 0x10; + } + } + + nlbas = nvme_ns_nlbas(ns); + + id_ns->nsze = cpu_to_le64(nlbas); + ns->mdata_offset = nvme_l2b(ns, nlbas); ns->csi = NVME_CSI_NVM; @@ -140,7 +152,7 @@ static int nvme_ns_zoned_check_calc_geometry(NvmeNamespace *ns, Error **errp) */ ns->zone_size = zone_size / lbasz; ns->zone_capacity = zone_cap / lbasz; - ns->num_zones = ns->size / lbasz / ns->zone_size; + ns->num_zones = nvme_ns_nlbas(ns) / ns->zone_size; /* Do a few more sanity checks of ZNS properties */ if (!ns->num_zones) { @@ -402,6 +414,8 @@ static Property nvme_ns_props[] = { DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false), DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0), DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid), + DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0), + DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0), DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128), DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128), DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 127), |