On 7/26/22 4:52 AM, Ankit Kumar wrote: > Add bare minimum structures and helper functions required for > io_uring passthrough commands. This will enable the follow up > patch to add tests for nvme-ns generic character device. > > Signed-off-by: Ankit Kumar <ankit.kumar@xxxxxxxxxxx> > --- > test/nvme.h | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 168 insertions(+) > create mode 100644 test/nvme.h > > diff --git a/test/nvme.h b/test/nvme.h > new file mode 100644 > index 0000000..866a7e6 > --- /dev/null > +++ b/test/nvme.h > @@ -0,0 +1,168 @@ > +/* SPDX-License-Identifier: MIT */ > +/* > + * Description: Helpers for NVMe uring passthrough commands > + */ > +#ifndef LIBURING_NVME_H > +#define LIBURING_NVME_H > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include <sys/ioctl.h> > +#include <linux/nvme_ioctl.h> > + > +/* > + * If the uapi headers installed on the system lacks nvme uring command > + * support, use the local version to prevent compilation issues. > + */ > +#ifndef CONFIG_HAVE_NVME_URING > +struct nvme_uring_cmd { > + __u8 opcode; > + __u8 flags; > + __u16 rsvd1; > + __u32 nsid; > + __u32 cdw2; > + __u32 cdw3; > + __u64 metadata; > + __u64 addr; > + __u32 metadata_len; > + __u32 data_len; > + __u32 cdw10; > + __u32 cdw11; > + __u32 cdw12; > + __u32 cdw13; > + __u32 cdw14; > + __u32 cdw15; > + __u32 timeout_ms; > + __u32 rsvd2; > +}; > + > +#define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd) > +#define NVME_URING_CMD_IO_VEC _IOWR('N', 0x81, struct nvme_uring_cmd) > +#endif /* CONFIG_HAVE_NVME_URING */ > + > +#define NVME_DEFAULT_IOCTL_TIMEOUT 0 > +#define NVME_IDENTIFY_DATA_SIZE 4096 > +#define NVME_IDENTIFY_CSI_SHIFT 24 > +#define NVME_IDENTIFY_CNS_NS 0 > +#define NVME_CSI_NVM 0 > + > +enum nvme_admin_opcode { > + nvme_admin_identify = 0x06, > +}; > + > +enum nvme_io_opcode { > + nvme_cmd_write = 0x01, > + nvme_cmd_read = 0x02, > +}; > + > +int nsid; > +__u32 lba_shift; > + > +struct nvme_lbaf { > + __le16 ms; > + __u8 ds; > + __u8 rp; > +}; > + > +struct nvme_id_ns { > + __le64 nsze; > + __le64 ncap; > + __le64 nuse; > + __u8 nsfeat; > + __u8 nlbaf; > + __u8 flbas; > + __u8 mc; > + __u8 dpc; > + __u8 dps; > + __u8 nmic; > + __u8 rescap; > + __u8 fpi; > + __u8 dlfeat; > + __le16 nawun; > + __le16 nawupf; > + __le16 nacwu; > + __le16 nabsn; > + __le16 nabo; > + __le16 nabspf; > + __le16 noiob; > + __u8 nvmcap[16]; > + __le16 npwg; > + __le16 npwa; > + __le16 npdg; > + __le16 npda; > + __le16 nows; > + __le16 mssrl; > + __le32 mcl; > + __u8 msrc; > + __u8 rsvd81[11]; > + __le32 anagrpid; > + __u8 rsvd96[3]; > + __u8 nsattr; > + __le16 nvmsetid; > + __le16 endgid; > + __u8 nguid[16]; > + __u8 eui64[8]; > + struct nvme_lbaf lbaf[16]; > + __u8 rsvd192[192]; > + __u8 vs[3712]; > +}; > + > +static inline int ilog2(uint32_t i) > +{ > + int log = -1; > + > + while (i) { > + i >>= 1; > + log++; > + } > + return log; > +} > + > +int fio_nvme_get_info(const char *file) > +{ > + struct nvme_id_ns ns; > + int fd, err; > + __u32 lba_size; > + > + fd = open(file, O_RDONLY); > + if (fd < 0) > + return -errno; > + > + nsid = ioctl(fd, NVME_IOCTL_ID); > + if (nsid < 0) { > + fprintf(stderr, "failed to fetch namespace-id\n"); > + close(fd); > + return -errno; > + } > + > + struct nvme_passthru_cmd cmd = { > + .opcode = nvme_admin_identify, > + .nsid = nsid, > + .addr = (__u64)(uintptr_t)&ns, > + .data_len = NVME_IDENTIFY_DATA_SIZE, > + .cdw10 = NVME_IDENTIFY_CNS_NS, > + .cdw11 = NVME_CSI_NVM << NVME_IDENTIFY_CSI_SHIFT, > + .timeout_ms = NVME_DEFAULT_IOCTL_TIMEOUT, > + }; > + > + err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd); > + if (err) { > + fprintf(stderr, "failed to fetch identify namespace\n"); > + close(fd); > + return err; > + } > + > + lba_size = 1 << ns.lbaf[(ns.flbas & 0x0f)].ds; > + lba_shift = ilog2(lba_size); > + > + close(fd); > + return 0; > +} Too much copy pasting I think? Probably should not prefix this one with fio? -- Jens Axboe