Skip to content

Commit

Permalink
linux: add nvme_get_ana_log_len_from_id_ctrl()
Browse files Browse the repository at this point in the history
The existing function nvme_get_ana_log_len() returns the maximum length
of the ANA log page but has a few restrictions:
- It doesn't work with NVMe-MI controllers, only file descriptors
- It combines calculating the ANA log length from Identify Controller
  with issuing the Identify Controller command
- It always returns a maximum length for the ANA log page with NSIDs.
  If the ANA log page is going to be fetched with the RGO bit set,
  the max length may be much lower, so a smaller buffer could be used.

nvme_get_ana_log_len_from_id_ctrl() is more flexible: it uses an
existing Identify Controller response and accepts a rgo parameter.
This allows it to work with Identify Controller reponses
from MI devices or to reuse existing Identify Controller results.
And it can return a tighter length bound when the RGO bit will be set.
This makes it suitable for use in nvme-cli.

Signed-off-by: Caleb Sander Mateos <[email protected]>
  • Loading branch information
calebsander authored and igaw committed Jun 25, 2024
1 parent 166a144 commit 3120b49
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/libnvme.map
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ LIBNVME_1.10 {
global:
nvme_free_uri;
nvme_get_ana_log_atomic;
nvme_get_ana_log_len_from_id_ctrl;
nvme_init_default_logging;
nvme_parse_uri;
nvme_root_skip_namespaces;
Expand Down
14 changes: 11 additions & 3 deletions src/nvme/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,16 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
NVME_DEFAULT_IOCTL_TIMEOUT);
}

size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,
bool rgo)
{
__u32 nanagrpid = le32_to_cpu(id_ctrl->nanagrpid);
size_t size = sizeof(struct nvme_ana_log) +
nanagrpid * sizeof(struct nvme_ana_group_desc);

return rgo ? size : size + le32_to_cpu(id_ctrl->mnan) * sizeof(__le32);
}

int nvme_get_ana_log_len(int fd, size_t *analen)
{
_cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
Expand All @@ -400,9 +410,7 @@ int nvme_get_ana_log_len(int fd, size_t *analen)
if (ret)
return ret;

*analen = sizeof(struct nvme_ana_log) +
le32_to_cpu(ctrl->nanagrpid) * sizeof(struct nvme_ana_group_desc) +
le32_to_cpu(ctrl->mnan) * sizeof(__le32);
*analen = nvme_get_ana_log_len_from_id_ctrl(ctrl, false);
return 0;
}

Expand Down
10 changes: 10 additions & 0 deletions src/nvme/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log,
int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log,
enum nvme_telemetry_da da, size_t *size);

/**
* nvme_get_ana_log_len_from_id_ctrl() - Retrieve maximum possible ANA log size
* @id_ctrl: Controller identify data
* @rgo: If true, return maximum log page size without NSIDs
*
* Return: A byte limit on the size of the controller's ANA log page
*/
size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,
bool rgo);

/**
* nvme_get_ana_log_len() - Retrieve size of the current ANA log
* @fd: File descriptor of nvme device
Expand Down

0 comments on commit 3120b49

Please sign in to comment.