Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create-ns: align the namespaces to 1Mib boundaries when using SI suffixes #2095

Merged
merged 1 commit into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Documentation/nvme-create-ns.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,15 @@ OPTIONS

-S::
--nsze-si::
The namespace size (NSZE) in standard SI units.
The namespace size (NSZE) in standard SI units (aligned on 1Mib boundaries,
unless the controller recommends a smaller value).
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.
The namespace capacity (NCAP) in standard SI units (aligned on 1Mib boundaries,
unless the controller recommends a smaller value).
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.

Expand Down Expand Up @@ -155,4 +157,4 @@ EXAMPLES

NVME
----
Part of the nvme-user suite
Part of the nvme-user suite
62 changes: 59 additions & 3 deletions nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -2833,12 +2833,13 @@ 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)
const char *val, __u8 flbas, __u64 *num, __u32 align)
{
_cleanup_free_ struct nvme_ns_list *ns_list = NULL;
_cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
_cleanup_free_ struct nvme_id_ns *ns = NULL;
__u32 nsid = 1;
unsigned int remainder;
char *endptr;
int err = -EINVAL;
int i;
Expand Down Expand Up @@ -2916,6 +2917,12 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
return -errno;
}

if (endptr[0]) {
remainder = *num % align;
if (remainder)
*num += align - remainder;
}

if (endptr[0] != '\0')
*num /= lbas;

Expand Down Expand Up @@ -2958,6 +2965,10 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
__u32 nsid;
uint16_t num_phandle;
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;

struct config {
__u64 nsze;
Expand Down Expand Up @@ -3075,11 +3086,56 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
return -EINVAL;
}

err = parse_lba_num_si(dev, "nsze", cfg.nsze_si, cfg.flbas, &cfg.nsze);
id = nvme_alloc(sizeof(*id));
maurizio-lombardi marked this conversation as resolved.
Show resolved Hide resolved
if (!id)
return -ENOMEM;
maurizio-lombardi marked this conversation as resolved.
Show resolved Hide resolved

err = nvme_identify_ctrl(dev_fd(dev), id);
if (err) {
if (err < 0) {
nvme_show_error("identify-controller: %s", nvme_strerror(errno));
} else {
fprintf(stderr, "identify controller failed\n");
nvme_show_status(err);
}
return err;
}

if (id->ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) {
gr_list = nvme_alloc(sizeof(*gr_list));
maurizio-lombardi marked this conversation as resolved.
Show resolved Hide resolved
if (!gr_list)
return -ENOMEM;
maurizio-lombardi marked this conversation as resolved.
Show resolved Hide resolved

if (!nvme_identify_ns_granularity(dev_fd(dev), gr_list)) {
struct nvme_id_ns_granularity_desc *desc;
int index = cfg.flbas;

/* FIXME: add a proper bitmask to libnvme */
if (!(gr_list->attributes & 1)) {
/* Only the first descriptor is valid */
index = 0;
} else if (index > gr_list->num_descriptors) {
/*
* The descriptor will contain only zeroes
* so we don't need to read it.
*/
goto parse_lba;
}
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;
}
}

parse_lba:
err = parse_lba_num_si(dev, "nsze", cfg.nsze_si, cfg.flbas, &cfg.nsze, align_nsze);
if (err)
return err;

err = parse_lba_num_si(dev, "ncap", cfg.ncap_si, cfg.flbas, &cfg.ncap);
err = parse_lba_num_si(dev, "ncap", cfg.ncap_si, cfg.flbas, &cfg.ncap, align_ncap);
if (err)
return err;

Expand Down
Loading