Skip to content

Commit 3120b49

Browse files
calebsanderigaw
authored andcommitted
linux: add nvme_get_ana_log_len_from_id_ctrl()
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]>
1 parent 166a144 commit 3120b49

3 files changed

Lines changed: 22 additions & 3 deletions

File tree

src/libnvme.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ LIBNVME_1.10 {
33
global:
44
nvme_free_uri;
55
nvme_get_ana_log_atomic;
6+
nvme_get_ana_log_len_from_id_ctrl;
67
nvme_init_default_logging;
78
nvme_parse_uri;
89
nvme_root_skip_namespaces;

src/nvme/linux.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,16 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls,
386386
NVME_DEFAULT_IOCTL_TIMEOUT);
387387
}
388388

389+
size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,
390+
bool rgo)
391+
{
392+
__u32 nanagrpid = le32_to_cpu(id_ctrl->nanagrpid);
393+
size_t size = sizeof(struct nvme_ana_log) +
394+
nanagrpid * sizeof(struct nvme_ana_group_desc);
395+
396+
return rgo ? size : size + le32_to_cpu(id_ctrl->mnan) * sizeof(__le32);
397+
}
398+
389399
int nvme_get_ana_log_len(int fd, size_t *analen)
390400
{
391401
_cleanup_free_ struct nvme_id_ctrl *ctrl = NULL;
@@ -400,9 +410,7 @@ int nvme_get_ana_log_len(int fd, size_t *analen)
400410
if (ret)
401411
return ret;
402412

403-
*analen = sizeof(struct nvme_ana_log) +
404-
le32_to_cpu(ctrl->nanagrpid) * sizeof(struct nvme_ana_group_desc) +
405-
le32_to_cpu(ctrl->mnan) * sizeof(__le32);
413+
*analen = nvme_get_ana_log_len_from_id_ctrl(ctrl, false);
406414
return 0;
407415
}
408416

src/nvme/linux.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log,
128128
int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log,
129129
enum nvme_telemetry_da da, size_t *size);
130130

131+
/**
132+
* nvme_get_ana_log_len_from_id_ctrl() - Retrieve maximum possible ANA log size
133+
* @id_ctrl: Controller identify data
134+
* @rgo: If true, return maximum log page size without NSIDs
135+
*
136+
* Return: A byte limit on the size of the controller's ANA log page
137+
*/
138+
size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,
139+
bool rgo);
140+
131141
/**
132142
* nvme_get_ana_log_len() - Retrieve size of the current ANA log
133143
* @fd: File descriptor of nvme device

0 commit comments

Comments
 (0)