From 4851c9ba351f306abbe53ac6ef4e96d4be2bbd5f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 25 Feb 2025 09:44:38 +0100 Subject: [PATCH] nvme: enforce ns granularity on ns create When the device supports the namespace granularity feature, update the alignment requirements accordingly. Because this is likely to change the capacity of the namespace also issue a info what is going to happen. Signed-off-by: Daniel Wagner --- Documentation/nvme-create-ns.txt | 6 ++++-- nvme.c | 24 ++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Documentation/nvme-create-ns.txt b/Documentation/nvme-create-ns.txt index 95a514d521..74ca23725a 100644 --- a/Documentation/nvme-create-ns.txt +++ b/Documentation/nvme-create-ns.txt @@ -99,14 +99,16 @@ OPTIONS -S:: --nsze-si:: The namespace size (NSZE) in standard SI units (aligned on 1Mib boundaries, - unless the controller recommends a smaller value). + unless the controller recommends a different value, see namespace + granularity). The value SI suffixed is divided by the namespace LBA size to set as NSZE. If the value not suffixed it is set as same with the nsze option. -C:: --ncap-si:: The namespace capacity (NCAP) in standard SI units (aligned on 1Mib boundaries, - unless the controller recommends a smaller value). + unless the controller recommends a different value, see namespace + granularity). The value SI suffixed is divided by the namespace LBA size to set as NCAP. If the value not suffixed it is set as same with the ncap option. diff --git a/nvme.c b/nvme.c index 54ddcfe849..875a094bd7 100644 --- a/nvme.c +++ b/nvme.c @@ -3001,7 +3001,7 @@ static int detach_ns(int argc, char **argv, struct command *cmd, struct plugin * } static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, - const char *val, __u8 flbas, __u64 *num, __u32 align) + const char *val, __u8 flbas, __u64 *num, __u64 align) { _cleanup_free_ struct nvme_ns_list *ns_list = NULL; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; @@ -3134,8 +3134,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * uint16_t phndl[128] = { 0, }; _cleanup_free_ struct nvme_id_ctrl *id = NULL; _cleanup_free_ struct nvme_id_ns_granularity_list *gr_list = NULL; - __u32 align_nsze = 1 << 20; /* Default 1 MiB */ - __u32 align_ncap = align_nsze; + __u64 align_nsze = 1 << 20; /* Default 1 MiB */ + __u64 align_ncap = align_nsze; nvme_print_flags_t flags; struct config { @@ -3284,7 +3284,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * int index = cfg.flbas; /* FIXME: add a proper bitmask to libnvme */ - if (!(gr_list->attributes & 1)) { + if (!(le32_to_cpu(gr_list->attributes) & 1)) { /* Only the first descriptor is valid */ index = 0; } else if (index > gr_list->num_descriptors) { @@ -3296,10 +3296,18 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * } desc = &gr_list->entry[index]; - if (desc->nszegran && desc->nszegran < align_nsze) - align_nsze = desc->nszegran; - if (desc->ncapgran && desc->ncapgran < align_ncap) - align_ncap = desc->ncapgran; + if (desc->nszegran) { + print_info("enforce nsze alignment to %"PRIx64 + " because of namespace granularity requirements\n", + le64_to_cpu(desc->nszegran)); + align_nsze = le64_to_cpu(desc->nszegran); + } + if (desc->ncapgran) { + print_info("enforce ncap alignment to %"PRIx64 + " because of namespace granularity requirements\n", + le64_to_cpu(desc->ncapgran)); + align_ncap = le64_to_cpu(desc->ncapgran); + } } }