From 06b7c376ccbafa4878d1240d2231853e6b61244d Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Wed, 18 Mar 2026 00:01:14 +0900 Subject: [PATCH 1/9] libnvme/cmds: change copy desc format 0h and 2h elbt to big-endian Since the format 1h and 3h elbt values are set as big-endian. Also change the field name eilbrt to elbt as following spec. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/cmds.h | 12 ++++++------ libnvme/src/nvme/types.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libnvme/src/nvme/cmds.h b/libnvme/src/nvme/cmds.h index 6396703d9b..25d9e2595e 100644 --- a/libnvme/src/nvme/cmds.h +++ b/libnvme/src/nvme/cmds.h @@ -5256,14 +5256,14 @@ nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt) * @copy: Copy range array * @nlbs: Number of logical blocks * @slbas: Starting LBA - * @eilbrts: Expected initial logical block reference tag + * @elbts: Expected initial logical block reference tag * @elbatms: Expected logical block application tag mask * @elbats: Expected logical block application tag * @nr: Number of descriptors to construct */ static inline void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, - __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, + __u64 *slbas, __u32 *elbts, __u32 *elbatms, __u32 *elbats, __u16 nr) { int i; @@ -5271,7 +5271,7 @@ nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, for (i = 0; i < nr; i++) { copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); - copy[i].eilbrt = htole32(eilbrts[i]); + copy[i].elbt = htobe32(elbts[i]); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); } @@ -5310,7 +5310,7 @@ nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, * @nlbs: Number of logical blocks * @slbas: Starting LBA * @sopts: Source options - * @eilbrts: Expected initial logical block reference tag + * @elbts: Expected initial logical block reference tag * @elbatms: Expected logical block application tag mask * @elbats: Expected logical block application tag * @nr: Number of descriptors to construct @@ -5318,7 +5318,7 @@ nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, static inline void nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, __u32 *snsids, __u16 *nlbs, __u64 *slbas, __u16 *sopts, - __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, + __u32 *elbts, __u32 *elbatms, __u32 *elbats, __u16 nr) { int i; @@ -5328,7 +5328,7 @@ nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); copy[i].sopt = htole16(sopts[i]); - copy[i].eilbrt = htole32(eilbrts[i]); + copy[i].elbt = htobe32(elbts[i]); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); } diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index ff478d0f71..e70be94593 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6441,7 +6441,7 @@ struct nvme_dsm_range { * @slba: Starting LBA * @nlb: Number of Logical Blocks * @rsvd18: Reserved - * @eilbrt: Expected Initial Logical Block Reference Tag / + * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag * @elbatm: Expected Logical Block Application Tag Mask * @elbat: Expected Logical Block Application Tag @@ -6451,7 +6451,7 @@ struct nvme_copy_range { __le64 slba; __le16 nlb; __u8 rsvd18[6]; - __le32 eilbrt; + __be32 elbt; __le16 elbat; __le16 elbatm; }; @@ -6493,7 +6493,7 @@ enum nvme_copy_range_sopt { * @nlb: Number of Logical Blocks * @rsvd18: Reserved * @sopt: Source Options - * @eilbrt: Expected Initial Logical Block Reference Tag / + * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag * @elbatm: Expected Logical Block Application Tag Mask * @elbat: Expected Logical Block Application Tag @@ -6505,7 +6505,7 @@ struct nvme_copy_range_f2 { __le16 nlb; __u8 rsvd18[4]; __le16 sopt; - __le32 eilbrt; + __be32 elbt; __le16 elbat; __le16 elbatm; }; From 1bacd4cdab027d74da78aa9a87e7f5c345dfa4d3 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Mon, 16 Mar 2026 23:04:38 +0900 Subject: [PATCH 2/9] libnvme/test: change copy desc format 0h expected data Since the elbt field changed to big-endian. Signed-off-by: Tokunori Ikegami --- libnvme/test/ioctl/misc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libnvme/test/ioctl/misc.c b/libnvme/test/ioctl/misc.c index b6dc618dd3..2c39637321 100644 --- a/libnvme/test/ioctl/misc.c +++ b/libnvme/test/ioctl/misc.c @@ -995,11 +995,11 @@ static void test_copy(void) __u32 elbats[TEST_COPY_NR] = { 0x111, 0x222, 0x333 }; __u8 expected_data[sizeof(struct nvme_copy_range) * TEST_COPY_NR] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, - 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0x11, 1, 0xff, 1, + 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0x11, 1, 0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, - 0xb, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0x22, 2, 0xff, 3, + 0xb, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0x22, 2, 0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0x30, 0, 0, - 0xc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0x33, 3, 0xff, 3 + 0xc, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0x33, 3, 0xff, 3 }; _cleanup_free_ struct nvme_copy_range *copy = NULL; From 4d456e9069c301d313c8bc471125c7c17f95c727 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Wed, 18 Mar 2026 00:07:08 +0900 Subject: [PATCH 3/9] libnvme: change copy_range name to copy_range_f0 Change both the struct name and the init API names. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/cmds.h | 6 +++--- libnvme/src/nvme/types.h | 4 ++-- libnvme/test/ioctl/misc.c | 11 ++++++----- nvme.c | 6 +++--- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libnvme/src/nvme/cmds.h b/libnvme/src/nvme/cmds.h index 25d9e2595e..f1c3e14af6 100644 --- a/libnvme/src/nvme/cmds.h +++ b/libnvme/src/nvme/cmds.h @@ -4383,7 +4383,7 @@ nvme_init_copy(struct nvme_passthru_cmd *cmd, __u32 nsid, __u64 sdlba, data_len = nr * sizeof(struct nvme_copy_range_f3); break; default: - data_len = nr * sizeof(struct nvme_copy_range); + data_len = nr * sizeof(struct nvme_copy_range_f0); break; } @@ -5252,7 +5252,7 @@ nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt) } /** - * nvme_init_copy_range() - Constructs a copy range structure + * nvme_init_copy_range_f0() - Constructs a copy range structure * @copy: Copy range array * @nlbs: Number of logical blocks * @slbas: Starting LBA @@ -5262,7 +5262,7 @@ nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt) * @nr: Number of descriptors to construct */ static inline void -nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, +nvme_init_copy_range_f0(struct nvme_copy_range_f0 *copy, __u16 *nlbs, __u64 *slbas, __u32 *elbts, __u32 *elbatms, __u32 *elbats, __u16 nr) { diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index e70be94593..1ea9352eef 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6436,7 +6436,7 @@ struct nvme_dsm_range { }; /** - * struct nvme_copy_range - Copy - Source Range Entries Descriptor Format + * struct nvme_copy_range_f0 - Copy - Source Range Entries Descriptor Format * @rsvd0: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks @@ -6446,7 +6446,7 @@ struct nvme_dsm_range { * @elbatm: Expected Logical Block Application Tag Mask * @elbat: Expected Logical Block Application Tag */ -struct nvme_copy_range { +struct nvme_copy_range_f0 { __u8 rsvd0[8]; __le64 slba; __le16 nlb; diff --git a/libnvme/test/ioctl/misc.c b/libnvme/test/ioctl/misc.c index 2c39637321..f7969931c0 100644 --- a/libnvme/test/ioctl/misc.c +++ b/libnvme/test/ioctl/misc.c @@ -983,7 +983,7 @@ static void test_dsm(void) static void test_copy(void) { __u16 nr = TEST_COPY_NR, cev = 0, dspec = 0; - int copy_size = sizeof(struct nvme_copy_range) * nr, err; + int copy_size = sizeof(struct nvme_copy_range_f0) * nr, err; bool prinfor = false, prinfow = false, stcw = false, stcr = false, fua = false, lr = false; __u8 cetype = 0, dtype = 0, desfmt = 0xf; @@ -993,7 +993,7 @@ static void test_copy(void) __u32 short_pi[TEST_COPY_NR] = { 0x1000, 0x20000000, 0x40000000 }; __u32 elbatms[TEST_COPY_NR] = { 0x1ff, 0x3ff, 0x3ff }; __u32 elbats[TEST_COPY_NR] = { 0x111, 0x222, 0x333 }; - __u8 expected_data[sizeof(struct nvme_copy_range) * TEST_COPY_NR] = { + __u8 expected_data[sizeof(struct nvme_copy_range_f0) * TEST_COPY_NR] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0x11, 1, 0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, @@ -1002,7 +1002,7 @@ static void test_copy(void) 0xc, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0x33, 3, 0xff, 3 }; - _cleanup_free_ struct nvme_copy_range *copy = NULL; + _cleanup_free_ struct nvme_copy_range_f0 *copy = NULL; copy = calloc(1, copy_size); check(copy, "copy: ENOMEM"); @@ -1017,13 +1017,14 @@ static void test_copy(void) ((dtype & 0xf) << 20) | ((prinfow & 0xf) << 26) | ((fua & 0x1) << 30) | ((lr & 0x1) << 31), - .data_len = nr * sizeof(struct nvme_copy_range), + .data_len = nr * sizeof(struct nvme_copy_range_f0), .in_data = expected_data, }; struct nvme_passthru_cmd cmd; set_mock_io_cmds(&mock_io_cmd, 1); - nvme_init_copy_range(copy, nlbs, slbas, short_pi, elbatms, elbats, nr); + nvme_init_copy_range_f0(copy, nlbs, slbas, short_pi, elbatms, elbats, + nr); nvme_init_copy(&cmd, TEST_NSID, sdlba, nr, desfmt, prinfor, prinfow, cetype, dtype, stcw, stcr, fua, lr, cev, dspec, (void *)copy); diff --git a/nvme.c b/nvme.c index 08fb9f8363..b198f3fbed 100644 --- a/nvme.c +++ b/nvme.c @@ -7770,7 +7770,7 @@ static int copy_cmd(int argc, char **argv, struct command *acmd, struct plugin * __u32 elbats[256] = { 0 }; _cleanup_free_ union { - struct nvme_copy_range f0[256]; + struct nvme_copy_range_f0 f0[256]; struct nvme_copy_range_f1 f1[256]; struct nvme_copy_range_f2 f2[256]; struct nvme_copy_range_f3 f3[256]; @@ -7922,8 +7922,8 @@ static int copy_cmd(int argc, char **argv, struct command *acmd, struct plugin * eilbrts.long_pi, elbatms, elbats, nr); break; default: - nvme_init_copy_range(copy->f0, nlbs, slbas, eilbrts.short_pi, - elbatms, elbats, nr); + nvme_init_copy_range_f0(copy->f0, nlbs, slbas, eilbrts.short_pi, + elbatms, elbats, nr); break; } From a90cb15cce666ff209b70649a2c961774c8e0e70 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Tue, 17 Mar 2026 00:22:01 +0900 Subject: [PATCH 4/9] libnvme/types: add nvme_copy_range_f0 new feilds Just followed NVMe command set spec revision 1.2. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/types.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index 1ea9352eef..af501b1e4d 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6436,11 +6436,14 @@ struct nvme_dsm_range { }; /** - * struct nvme_copy_range_f0 - Copy - Source Range Entries Descriptor Format + * struct nvme_copy_range_f0 - Copy - Source Range Entries Descriptor Format 0h * @rsvd0: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks - * @rsvd18: Reserved + * @cetype: Bits 3-0: Command Extension Type + * @rsvd19: Reserved + * @cev: Command Extension Value + * @rsvd22: Reserved * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag * @elbatm: Expected Logical Block Application Tag Mask @@ -6450,7 +6453,10 @@ struct nvme_copy_range_f0 { __u8 rsvd0[8]; __le64 slba; __le16 nlb; - __u8 rsvd18[6]; + __u8 cetype; + __u8 rsvd19; + __le16 cev; + __u8 rsvd22[2]; __be32 elbt; __le16 elbat; __le16 elbatm; From dc5c0547e56674353512b9f66910388debe09b5d Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Wed, 18 Mar 2026 01:28:23 +0900 Subject: [PATCH 5/9] libnvme/types: add nvme_copy_range_f2 new feilds Just followed NVMe command set spec revision 1.2. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/types.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index af501b1e4d..e09e9671b5 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6497,7 +6497,9 @@ enum nvme_copy_range_sopt { * @rsvd4: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks - * @rsvd18: Reserved + * @cetype: Bits 3-0: Command Extension Type + * @rsvd19: Reserved + * @cev: Command Extension Value * @sopt: Source Options * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag @@ -6509,7 +6511,9 @@ struct nvme_copy_range_f2 { __u8 rsvd4[4]; __le64 slba; __le16 nlb; - __u8 rsvd18[4]; + __u8 cetype; + __u8 rsvd19; + __le16 cev; __le16 sopt; __be32 elbt; __le16 elbat; From f5f526c19749c8c1ad4619400bb4d83c4be9337f Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Wed, 18 Mar 2026 01:38:09 +0900 Subject: [PATCH 6/9] libnvme/types: add nvme_copy_range_f1/f3 new feilds Just followed NVMe command set spec revision 1.2. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/types.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index e09e9671b5..7fdb850aba 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6467,7 +6467,10 @@ struct nvme_copy_range_f0 { * @rsvd0: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks - * @rsvd18: Reserved + * @cetype: Bits 3-0: Command Extension Type + * @rsvd19: Reserved + * @cev: Command Extension Value + * @rsvd22: Reserved * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag * @elbatm: Expected Logical Block Application Tag Mask @@ -6477,7 +6480,10 @@ struct nvme_copy_range_f1 { __u8 rsvd0[8]; __le64 slba; __le16 nlb; - __u8 rsvd18[8]; + __u8 cetype; + __u8 rsvd19; + __le16 cev; + __u8 rsvd22[4]; __u8 elbt[10]; __le16 elbat; __le16 elbatm; @@ -6526,8 +6532,10 @@ struct nvme_copy_range_f2 { * @rsvd4: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks - * @rsvd18: Reserved + * @cetype: Bits 3-0: Command Extension Type + * @rsvd19: Reserved * @sopt: Source Options + * @cev: Command Extension Value * @rsvd24: Reserved * @elbt: Expected Initial Logical Block Reference Tag / * Expected Logical Block Storage Tag @@ -6539,7 +6547,9 @@ struct nvme_copy_range_f3 { __u8 rsvd4[4]; __le64 slba; __le16 nlb; - __u8 rsvd18[4]; + __u8 cetype; + __u8 rsvd19; + __le16 cev; __le16 sopt; __u8 rsvd24[2]; __u8 elbt[10]; From 4fe3b3edd9d97b426c83c794af205fe507440a92 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Thu, 19 Mar 2026 02:31:48 +0900 Subject: [PATCH 7/9] libnvme/types: change copy desc format 0h and 2h elbt to array Change odd big-endian field as same with the format 1h and 2h. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/cmds.h | 29 ++++++++++++++++++----------- libnvme/src/nvme/types.h | 4 ++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libnvme/src/nvme/cmds.h b/libnvme/src/nvme/cmds.h index f1c3e14af6..6f188a0374 100644 --- a/libnvme/src/nvme/cmds.h +++ b/libnvme/src/nvme/cmds.h @@ -5237,18 +5237,17 @@ nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, /** * nvme_init_copy_range_elbt() - Constructs a copy range elbt structure - * @elbt: - * @eilbrts: Expected initial logical block reference tag + * @elbt: Expected logical block tags + * @eilbrt: Expected initial logical block reference tag + * @size: eilbrts size */ static inline void -nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt) +nvme_init_copy_range_elbt(__u8 *elbt, __u8 *eilbrt, int size) { int i; - for (i = 0; i < 8; i++) - elbt[9 - i] = (eilbrt >> (8 * i)) & 0xff; - elbt[1] = 0; - elbt[0] = 0; + for (i = 0; i < size; i++) + elbt[size - 1 - i] = eilbrt[i]; } /** @@ -5271,7 +5270,8 @@ nvme_init_copy_range_f0(struct nvme_copy_range_f0 *copy, __u16 *nlbs, for (i = 0; i < nr; i++) { copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); - copy[i].elbt = htobe32(elbts[i]); + nvme_init_copy_range_elbt(copy[i].elbt, (__u8 *)&elbts[i], + sizeof(elbts[i])); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); } @@ -5294,12 +5294,15 @@ nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, { int i; + memset(copy, 0, sizeof(*copy) * nr); + for (i = 0; i < nr; i++) { copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); - nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]); + nvme_init_copy_range_elbt(©[i].elbt[2], (__u8 *)&eilbrts[i], + sizeof(eilbrts[i])); } } @@ -5328,7 +5331,8 @@ nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); copy[i].sopt = htole16(sopts[i]); - copy[i].elbt = htobe32(elbts[i]); + nvme_init_copy_range_elbt(copy[i].elbt, (__u8 *)&elbts[i], + sizeof(elbts[i])); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); } @@ -5354,6 +5358,8 @@ nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids, { int i; + memset(copy, 0, sizeof(*copy) * nr); + for (i = 0; i < nr; i++) { copy[i].snsid = htole32(snsids[i]); copy[i].nlb = htole16(nlbs[i]); @@ -5361,7 +5367,8 @@ nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids, copy[i].sopt = htole16(sopts[i]); copy[i].elbatm = htole16(elbatms[i]); copy[i].elbat = htole16(elbats[i]); - nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]); + nvme_init_copy_range_elbt(©[i].elbt[2], (__u8 *)&eilbrts[i], + sizeof(eilbrts[i])); } } diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index 7fdb850aba..0da0ab5a1f 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6457,7 +6457,7 @@ struct nvme_copy_range_f0 { __u8 rsvd19; __le16 cev; __u8 rsvd22[2]; - __be32 elbt; + __u8 elbt[4]; __le16 elbat; __le16 elbatm; }; @@ -6521,7 +6521,7 @@ struct nvme_copy_range_f2 { __u8 rsvd19; __le16 cev; __le16 sopt; - __be32 elbt; + __u8 elbt[4]; __le16 elbat; __le16 elbatm; }; From 612a752b2aaf8e316e4cf9be875a910d4d02e6af Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sat, 21 Mar 2026 21:31:11 +0900 Subject: [PATCH 8/9] libnvme/cmds: change copy desc format elbatm and elbat to big-endian Since the format elbt values are set as big-endian then follow it. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/cmds.h | 36 ++++++++++++++++++++++-------------- libnvme/src/nvme/types.h | 16 ++++++++-------- libnvme/test/ioctl/misc.c | 10 +++++----- nvme.c | 8 ++++---- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/libnvme/src/nvme/cmds.h b/libnvme/src/nvme/cmds.h index 6f188a0374..dc23955723 100644 --- a/libnvme/src/nvme/cmds.h +++ b/libnvme/src/nvme/cmds.h @@ -5262,8 +5262,8 @@ nvme_init_copy_range_elbt(__u8 *elbt, __u8 *eilbrt, int size) */ static inline void nvme_init_copy_range_f0(struct nvme_copy_range_f0 *copy, __u16 *nlbs, - __u64 *slbas, __u32 *elbts, __u32 *elbatms, - __u32 *elbats, __u16 nr) + __u64 *slbas, __u32 *elbts, __u16 *elbatms, + __u16 *elbats, __u16 nr) { int i; @@ -5272,8 +5272,10 @@ nvme_init_copy_range_f0(struct nvme_copy_range_f0 *copy, __u16 *nlbs, copy[i].slba = htole64(slbas[i]); nvme_init_copy_range_elbt(copy[i].elbt, (__u8 *)&elbts[i], sizeof(elbts[i])); - copy[i].elbatm = htole16(elbatms[i]); - copy[i].elbat = htole16(elbats[i]); + nvme_init_copy_range_elbt(copy[i].elbatm, (__u8 *)&elbatms[i], + sizeof(copy[i].elbatm)); + nvme_init_copy_range_elbt(copy[i].elbat, (__u8 *)&elbats[i], + sizeof(copy[i].elbat)); } } @@ -5289,8 +5291,8 @@ nvme_init_copy_range_f0(struct nvme_copy_range_f0 *copy, __u16 *nlbs, */ static inline void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, - __u64 *slbas, __u64 *eilbrts, __u32 *elbatms, - __u32 *elbats, __u16 nr) + __u64 *slbas, __u64 *eilbrts, __u16 *elbatms, + __u16 *elbats, __u16 nr) { int i; @@ -5299,10 +5301,12 @@ nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, for (i = 0; i < nr; i++) { copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); - copy[i].elbatm = htole16(elbatms[i]); - copy[i].elbat = htole16(elbats[i]); nvme_init_copy_range_elbt(©[i].elbt[2], (__u8 *)&eilbrts[i], sizeof(eilbrts[i])); + nvme_init_copy_range_elbt(copy[i].elbatm, (__u8 *)&elbatms[i], + sizeof(copy[i].elbatm)); + nvme_init_copy_range_elbt(copy[i].elbat, (__u8 *)&elbats[i], + sizeof(copy[i].elbat)); } } @@ -5321,7 +5325,7 @@ nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, static inline void nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, __u32 *snsids, __u16 *nlbs, __u64 *slbas, __u16 *sopts, - __u32 *elbts, __u32 *elbatms, __u32 *elbats, + __u32 *elbts, __u16 *elbatms, __u16 *elbats, __u16 nr) { int i; @@ -5333,8 +5337,10 @@ nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, copy[i].sopt = htole16(sopts[i]); nvme_init_copy_range_elbt(copy[i].elbt, (__u8 *)&elbts[i], sizeof(elbts[i])); - copy[i].elbatm = htole16(elbatms[i]); - copy[i].elbat = htole16(elbats[i]); + nvme_init_copy_range_elbt(copy[i].elbatm, (__u8 *)&elbatms[i], + sizeof(copy[i].elbatm)); + nvme_init_copy_range_elbt(copy[i].elbat, (__u8 *)&elbats[i], + sizeof(copy[i].elbat)); } } @@ -5353,7 +5359,7 @@ nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, static inline void nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids, __u16 *nlbs, __u64 *slbas, __u16 *sopts, - __u64 *eilbrts, __u32 *elbatms, __u32 *elbats, + __u64 *eilbrts, __u16 *elbatms, __u16 *elbats, __u16 nr) { int i; @@ -5365,10 +5371,12 @@ nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids, copy[i].nlb = htole16(nlbs[i]); copy[i].slba = htole64(slbas[i]); copy[i].sopt = htole16(sopts[i]); - copy[i].elbatm = htole16(elbatms[i]); - copy[i].elbat = htole16(elbats[i]); nvme_init_copy_range_elbt(©[i].elbt[2], (__u8 *)&eilbrts[i], sizeof(eilbrts[i])); + nvme_init_copy_range_elbt(copy[i].elbatm, (__u8 *)&elbatms[i], + sizeof(copy[i].elbatm)); + nvme_init_copy_range_elbt(copy[i].elbat, (__u8 *)&elbats[i], + sizeof(copy[i].elbat)); } } diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index 0da0ab5a1f..0cb380a193 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -6458,8 +6458,8 @@ struct nvme_copy_range_f0 { __le16 cev; __u8 rsvd22[2]; __u8 elbt[4]; - __le16 elbat; - __le16 elbatm; + __u8 elbat[2]; + __u8 elbatm[2]; }; /** @@ -6485,8 +6485,8 @@ struct nvme_copy_range_f1 { __le16 cev; __u8 rsvd22[4]; __u8 elbt[10]; - __le16 elbat; - __le16 elbatm; + __u8 elbat[2]; + __u8 elbatm[2]; }; /** @@ -6522,8 +6522,8 @@ struct nvme_copy_range_f2 { __le16 cev; __le16 sopt; __u8 elbt[4]; - __le16 elbat; - __le16 elbatm; + __u8 elbat[2]; + __u8 elbatm[2]; }; /** @@ -6553,8 +6553,8 @@ struct nvme_copy_range_f3 { __le16 sopt; __u8 rsvd24[2]; __u8 elbt[10]; - __le16 elbat; - __le16 elbatm; + __u8 elbat[2]; + __u8 elbatm[2]; }; /** diff --git a/libnvme/test/ioctl/misc.c b/libnvme/test/ioctl/misc.c index f7969931c0..3749c5959a 100644 --- a/libnvme/test/ioctl/misc.c +++ b/libnvme/test/ioctl/misc.c @@ -991,15 +991,15 @@ static void test_copy(void) __u16 nlbs[TEST_COPY_NR] = { 0xa, 0xb, 0xc }; __u64 slbas[TEST_COPY_NR] = { 0x1000, 0x20000000, 0x300040000000 }; __u32 short_pi[TEST_COPY_NR] = { 0x1000, 0x20000000, 0x40000000 }; - __u32 elbatms[TEST_COPY_NR] = { 0x1ff, 0x3ff, 0x3ff }; - __u32 elbats[TEST_COPY_NR] = { 0x111, 0x222, 0x333 }; + __u16 elbatms[TEST_COPY_NR] = { 0x1ff, 0x3ff, 0x3ff }; + __u16 elbats[TEST_COPY_NR] = { 0x111, 0x222, 0x333 }; __u8 expected_data[sizeof(struct nvme_copy_range_f0) * TEST_COPY_NR] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, - 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0x11, 1, 0xff, 1, + 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 1, 0x11, 1, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, - 0xb, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0x22, 2, 0xff, 3, + 0xb, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 2, 0x22, 3, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0x30, 0, 0, - 0xc, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0x33, 3, 0xff, 3 + 0xc, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 3, 0x33, 3, 0xff }; _cleanup_free_ struct nvme_copy_range_f0 *copy = NULL; diff --git a/nvme.c b/nvme.c index b198f3fbed..040ad6d171 100644 --- a/nvme.c +++ b/nvme.c @@ -7766,8 +7766,8 @@ static int copy_cmd(int argc, char **argv, struct command *acmd, struct plugin * __u64 long_pi[256]; } eilbrts; - __u32 elbatms[256] = { 0 }; - __u32 elbats[256] = { 0 }; + __u16 elbatms[256] = { 0 }; + __u16 elbats[256] = { 0 }; _cleanup_free_ union { struct nvme_copy_range_f0 f0[256]; @@ -7876,9 +7876,9 @@ static int copy_cmd(int argc, char **argv, struct command *acmd, struct plugin * return -EINVAL; } - natms = argconfig_parse_comma_sep_array_u32(cfg.elbatms, elbatms, + natms = argconfig_parse_comma_sep_array_u16(cfg.elbatms, elbatms, ARRAY_SIZE(elbatms)); - nats = argconfig_parse_comma_sep_array_u32(cfg.elbats, elbats, + nats = argconfig_parse_comma_sep_array_u16(cfg.elbats, elbats, ARRAY_SIZE(elbats)); nr = max(nb, max(ns, max(nrts, max(natms, nats)))); From b1898b771ca960bbc25f650f251a781f03d2cab8 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sat, 21 Mar 2026 22:54:48 +0900 Subject: [PATCH 9/9] libnvme/cmds: fix nvme_init_copy_range_elbt for big endian build Since the function just depended on the little endian build. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/cmds.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libnvme/src/nvme/cmds.h b/libnvme/src/nvme/cmds.h index dc23955723..8e23c4d87f 100644 --- a/libnvme/src/nvme/cmds.h +++ b/libnvme/src/nvme/cmds.h @@ -5247,7 +5247,11 @@ nvme_init_copy_range_elbt(__u8 *elbt, __u8 *eilbrt, int size) int i; for (i = 0; i < size; i++) +#if __BYTE_ORDER == __LITTLE_ENDIAN elbt[size - 1 - i] = eilbrt[i]; +#else /* __BYTE_ORDER == __LITTLE_ENDIAN */ + elbt[i] = eilbrt[i]; +#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ } /**