mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 03:04:34 +01:00
nvmecontrol: Use active nslist to enumerate namespaces
Rather than probing all namespace IDs up to cdata.nn for the devlist command, fetch the active namespace list and iterate over that. This can be much quicker on Fabrics controllers which often advertise a large cdata.nn value to support adding additional namespaces at runtime. Reviewed by: chuck Reported by: Neven Z <nevenzfr@gmail.com> Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D47355
This commit is contained in:
parent
326e20fc12
commit
9e1db51d4b
@ -116,9 +116,10 @@ static bool
|
||||
scan_controller(int ctrlr)
|
||||
{
|
||||
struct nvme_controller_data cdata;
|
||||
struct nvme_ns_list nslist;
|
||||
char name[64];
|
||||
uint8_t mn[64];
|
||||
uint32_t i;
|
||||
uint32_t nsid;
|
||||
int fd, ret;
|
||||
|
||||
snprintf(name, sizeof(name), "%s%d", NVME_CTRLR_PREFIX, ctrlr);
|
||||
@ -139,8 +140,20 @@ scan_controller(int ctrlr)
|
||||
nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH);
|
||||
printf("%6s: %s\n", name, mn);
|
||||
|
||||
for (i = 0; i < cdata.nn; i++) {
|
||||
scan_namespace(fd, ctrlr, i + 1);
|
||||
nsid = 0;
|
||||
for (;;) {
|
||||
if (read_active_namespaces(fd, nsid, &nslist) != 0)
|
||||
break;
|
||||
for (u_int i = 0; i < nitems(nslist.ns); i++) {
|
||||
nsid = nslist.ns[i];
|
||||
if (nsid == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
scan_namespace(fd, ctrlr, nsid);
|
||||
}
|
||||
if (nsid == 0 || nsid >= NVME_GLOBAL_NAMESPACE_TAG - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
@ -142,6 +142,30 @@ read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
read_active_namespaces(int fd, uint32_t nsid, struct nvme_ns_list *nslist)
|
||||
{
|
||||
struct nvme_pt_command pt;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
pt.cmd.nsid = htole32(nsid);
|
||||
pt.cmd.cdw10 = htole32(2);
|
||||
pt.buf = nslist;
|
||||
pt.len = sizeof(*nslist);
|
||||
pt.is_read = 1;
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
return (errno);
|
||||
|
||||
/* Convert data to host endian */
|
||||
nvme_ns_list_swapbytes(nslist);
|
||||
|
||||
if (nvme_completion_is_error(&pt.cpl))
|
||||
return (EIO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
open_dev(const char *str, int *fd, int write, int exit_on_error)
|
||||
{
|
||||
|
@ -81,6 +81,7 @@ int open_dev(const char *str, int *fd, int write, int exit_on_error);
|
||||
void get_nsid(int fd, char **ctrlr_str, uint32_t *nsid);
|
||||
int read_controller_data(int fd, struct nvme_controller_data *cdata);
|
||||
int read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata);
|
||||
int read_active_namespaces(int fd, uint32_t nsid, struct nvme_ns_list *nslist);
|
||||
void print_hex(void *data, uint32_t length);
|
||||
void print_namespace(struct nvme_namespace_data *nsdata);
|
||||
void read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp,
|
||||
|
Loading…
Reference in New Issue
Block a user