Skip to content

Commit bd51e0f

Browse files
committed
ioctl: rework nvme_copy command
Replace the struct args approach by providing init function for initializing the passthru commands. This reduces the dependency between callside and library. Signed-off-by: Daniel Wagner <[email protected]> [ikegmi.t: - added switch case break statement missed] Signed-off-by: Tokunori Ikegami <[email protected]>
1 parent 9a666c0 commit bd51e0f

5 files changed

Lines changed: 132 additions & 113 deletions

File tree

libnvme/src/libnvme.map

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ LIBNVME_2_0 {
1616
nvme_admin_passthru64;
1717
nvme_admin_passthru;
1818
nvme_close;
19-
nvme_copy;
2019
nvme_create_ctrl;
2120
nvme_create_global_ctx;
2221
nvme_ctrl_config_match;

libnvme/src/nvme/api-types.h

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#define _LIBNVME_API_TYPES_H
1515

1616
#include <stdio.h>
17-
#include <stdbool.h>
1817

1918
#include <nvme/types.h>
2019

@@ -38,47 +37,4 @@ struct nvme_global_ctx *nvme_create_global_ctx(FILE *fp, int log_level);
3837
*/
3938
void nvme_free_global_ctx(struct nvme_global_ctx *ctx);
4039

41-
/**
42-
* struct nvme_copy_args - Arguments for the NVMe Copy command
43-
* @sdlba: Start destination LBA
44-
* @result: The command completion result from CQE dword0
45-
* @copy: Range description
46-
* @args_size: Size of &struct nvme_copy_args
47-
* @timeout: Timeout in ms
48-
* @nsid: Namespace identifier
49-
* @ilbrt: Initial logical block reference tag
50-
* @lr: Limited retry
51-
* @fua: Force unit access
52-
* @nr: Number of ranges
53-
* @dspec: Directive specific value
54-
* @lbatm: Logical block application tag mask
55-
* @lbat: Logical block application tag
56-
* @prinfor: Protection information field for read
57-
* @prinfow: Protection information field for write
58-
* @dtype: Directive type
59-
* @format: Descriptor format
60-
* @ilbrt_u64: Initial logical block reference tag - 8 byte
61-
* version required for enhanced protection info
62-
*/
63-
struct nvme_copy_args {
64-
__u64 sdlba;
65-
__u32 *result;
66-
struct nvme_copy_range *copy;
67-
int args_size;
68-
__u32 timeout;
69-
__u32 nsid;
70-
__u32 ilbrt;
71-
int lr;
72-
int fua;
73-
__u16 nr;
74-
__u16 dspec;
75-
__u16 lbatm;
76-
__u16 lbat;
77-
__u8 prinfor;
78-
__u8 prinfow;
79-
__u8 dtype;
80-
__u8 format;
81-
__u64 ilbrt_u64;
82-
};
83-
8440
#endif /* _LIBNVME_API_TYPES_H */

libnvme/src/nvme/ioctl.c

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -655,41 +655,3 @@ int nvme_io_passthru(struct nvme_transport_handle *hdl, __u8 opcode, __u8 flags,
655655
cdw15, data_len, data, metadata_len, metadata,
656656
timeout_ms, result);
657657
}
658-
659-
int nvme_copy(struct nvme_transport_handle *hdl, struct nvme_copy_args *args)
660-
{
661-
__u32 cdw3, cdw12, cdw14, data_len;
662-
663-
cdw12 = ((args->nr - 1) & 0xff) | ((args->format & 0xf) << 8) |
664-
((args->prinfor & 0xf) << 12) | ((args->dtype & 0xf) << 20) |
665-
((args->prinfow & 0xf) << 26) | ((args->fua & 0x1) << 30) |
666-
((args->lr & 0x1) << 31);
667-
cdw3 = (args->ilbrt_u64 >> 32) & 0xffffffff;
668-
cdw14 = args->ilbrt_u64 & 0xffffffff;
669-
670-
if (args->format == 1)
671-
data_len = args->nr * sizeof(struct nvme_copy_range_f1);
672-
else if (args->format == 2)
673-
data_len = args->nr * sizeof(struct nvme_copy_range_f2);
674-
else if (args->format == 3)
675-
data_len = args->nr * sizeof(struct nvme_copy_range_f3);
676-
else
677-
data_len = args->nr * sizeof(struct nvme_copy_range);
678-
679-
struct nvme_passthru_cmd cmd = {
680-
.opcode = nvme_cmd_copy,
681-
.nsid = args->nsid,
682-
.addr = (__u64)(uintptr_t)args->copy,
683-
.data_len = data_len,
684-
.cdw3 = cdw3,
685-
.cdw10 = args->sdlba & 0xffffffff,
686-
.cdw11 = args->sdlba >> 32,
687-
.cdw12 = cdw12,
688-
.cdw13 = (args->dspec & 0xffff) << 16,
689-
.cdw14 = cdw14,
690-
.cdw15 = (args->lbatm << 16) | args->lbat,
691-
.timeout_ms = args->timeout,
692-
};
693-
694-
return nvme_submit_io_passthru(hdl, &cmd, args->result);
695-
}

libnvme/src/nvme/ioctl.h

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,38 @@ enum nvme_cmd_dword_fields {
455455
NVME_IOCS_COMMON_CDW15_ELBAT_MASK = 0xffff,
456456
NVME_IOCS_COMMON_CDW15_ELBATM_SHIFT = 16,
457457
NVME_IOCS_COMMON_CDW15_ELBATM_MASK = 0xffff,
458+
NVME_COPY_CDW3_LBTU_SHIFT = 0,
459+
NVME_COPY_CDW3_LBTU_MASK = 0xffffffff,
460+
NVME_COPY_CDW10_SDLBAL_SHIFT = 0,
461+
NVME_COPY_CDW10_SDLBAL_MASK = 0xffffffff,
462+
NVME_COPY_CDW11_SDLBAU_SHIFT = 0,
463+
NVME_COPY_CDW11_SDLBAU_MASK = 0xffffffff,
464+
NVME_COPY_CDW12_NR_SHIFT = 0,
465+
NVME_COPY_CDW12_NR_MASK = 0xff,
466+
NVME_COPY_CDW12_DESFMT_SHIFT = 8,
467+
NVME_COPY_CDW12_DESFMT_MASK = 0xf,
468+
NVME_COPY_CDW12_PRINFOR_SHIFT = 12,
469+
NVME_COPY_CDW12_PRINFOR_MASK = 0xf,
470+
NVME_COPY_CDW12_CETYPE_SHIFT = 16,
471+
NVME_COPY_CDW12_CETYPE_MASK = 0xf,
472+
NVME_COPY_CDW12_DTYPE_SHIFT = 20,
473+
NVME_COPY_CDW12_DTYPE_MASK = 0xf,
474+
NVME_COPY_CDW12_STCW_SHIFT = 24,
475+
NVME_COPY_CDW12_STCW_MASK = 0x1,
476+
NVME_COPY_CDW12_STCR_SHIFT = 25,
477+
NVME_COPY_CDW12_STCR_MASK = 0x1,
478+
NVME_COPY_CDW12_PRINFOW_SHIFT = 26,
479+
NVME_COPY_CDW12_PRINFOW_MASK = 0xf,
480+
NVME_COPY_CDW12_FUA_SHIFT = 30,
481+
NVME_COPY_CDW12_FUA_MASK = 0x1,
482+
NVME_COPY_CDW12_LR_SHIFT = 31,
483+
NVME_COPY_CDW12_LR_MASK = 0x1,
484+
NVME_COPY_CDW14_LBTL_SHIFT = 0,
485+
NVME_COPY_CDW14_LBTL_MASK = 0xffffffff,
486+
NVME_COPY_CDW15_LBAT_SHIFT = 0,
487+
NVME_COPY_CDW15_LBAT_MASK = 0xffff,
488+
NVME_COPY_CDW15_LBATM_SHIFT = 16,
489+
NVME_COPY_CDW15_LBATM_MASK = 0xffff,
458490
};
459491

460492
#define NVME_FIELD_ENCODE(value, shift, mask) \
@@ -4764,15 +4796,89 @@ nvme_init_verify(struct nvme_passthru_cmd *cmd, __u32 nsid, __u64 slba,
47644796
}
47654797

47664798
/**
4767-
* nvme_copy() - Copy command
4768-
* @hdl: Transport handle
4769-
* @args: &struct nvme_copy_args argument structure
4799+
* nvme_init_copy() - Initialize passthru command for Copy command
4800+
* @cmd: Passthru command to use
4801+
* @nsid: Namespace identifier
4802+
* @sdlba: Start destination LBA
4803+
* @nr: Number of ranges (1-based, 0-based in command)
4804+
* @desfmt: Descriptor format
4805+
* @prinfor: Protection information field for read
4806+
* @prinfow: Protection information field for write
4807+
* @cetype: Command Extension Type
4808+
* @dtype: Directive Type
4809+
* @stcw: Storage Tag Check Write
4810+
* @stcr: Storage Tag Check Read
4811+
* @fua: Force unit access
4812+
* @lr: Limited retry
4813+
* @cev: Command Extension Value
4814+
* @dspec: Directive specific value
4815+
* @cpydsc: Range description buffer
47704816
*
4771-
* Return: 0 on success, the nvme command status if a response was
4772-
* received (see &enum nvme_status_field) or a negative error otherwise.
4817+
* Initializes the passthru command buffer for the Copy command by calculating
4818+
* the data length and calling the generic I/O initializer.
47734819
*/
4774-
int nvme_copy(struct nvme_transport_handle *hdl, struct nvme_copy_args *args);
4820+
static inline void
4821+
nvme_init_copy(struct nvme_passthru_cmd *cmd, __u32 nsid, __u64 sdlba,
4822+
__u16 nr, __u8 desfmt, __u8 prinfor, __u8 prinfow,
4823+
__u8 cetype, __u8 dtype, bool stcw, bool stcr, bool fua,
4824+
bool lr, __u16 cev, __u16 dspec, void *cpydsc)
4825+
{
4826+
__u32 data_len;
4827+
4828+
switch (desfmt) {
4829+
case 1:
4830+
data_len = nr * sizeof(struct nvme_copy_range_f1);
4831+
break;
4832+
case 2:
4833+
data_len = nr * sizeof(struct nvme_copy_range_f2);
4834+
break;
4835+
case 3:
4836+
data_len = nr * sizeof(struct nvme_copy_range_f3);
4837+
break;
4838+
default:
4839+
data_len = nr * sizeof(struct nvme_copy_range);
4840+
break;
4841+
}
47754842

4843+
nvme_init_io(cmd, nvme_cmd_copy, nsid, sdlba, cpydsc,
4844+
data_len, NULL, 0);
4845+
cmd->cdw12 = NVME_FIELD_ENCODE(nr - 1,
4846+
NVME_COPY_CDW12_NR_SHIFT,
4847+
NVME_COPY_CDW12_NR_MASK) |
4848+
NVME_FIELD_ENCODE(desfmt,
4849+
NVME_COPY_CDW12_DESFMT_SHIFT,
4850+
NVME_COPY_CDW12_DESFMT_MASK) |
4851+
NVME_FIELD_ENCODE(prinfor,
4852+
NVME_COPY_CDW12_PRINFOR_SHIFT,
4853+
NVME_COPY_CDW12_PRINFOR_MASK) |
4854+
NVME_FIELD_ENCODE(cetype,
4855+
NVME_COPY_CDW12_CETYPE_SHIFT,
4856+
NVME_COPY_CDW12_CETYPE_MASK) |
4857+
NVME_FIELD_ENCODE(dtype,
4858+
NVME_COPY_CDW12_DTYPE_SHIFT,
4859+
NVME_COPY_CDW12_DTYPE_MASK) |
4860+
NVME_FIELD_ENCODE(stcw,
4861+
NVME_COPY_CDW12_STCW_SHIFT,
4862+
NVME_COPY_CDW12_STCW_MASK) |
4863+
NVME_FIELD_ENCODE(stcr,
4864+
NVME_COPY_CDW12_STCR_SHIFT,
4865+
NVME_COPY_CDW12_STCR_MASK) |
4866+
NVME_FIELD_ENCODE(prinfow,
4867+
NVME_COPY_CDW12_PRINFOW_SHIFT,
4868+
NVME_COPY_CDW12_PRINFOW_MASK) |
4869+
NVME_FIELD_ENCODE(fua,
4870+
NVME_COPY_CDW12_FUA_SHIFT,
4871+
NVME_COPY_CDW12_FUA_MASK) |
4872+
NVME_FIELD_ENCODE(lr,
4873+
NVME_COPY_CDW12_LR_SHIFT,
4874+
NVME_COPY_CDW12_LR_MASK);
4875+
cmd->cdw13 = NVME_FIELD_ENCODE(cev,
4876+
NVME_IOCS_COMMON_CDW13_CEV_SHIFT,
4877+
NVME_IOCS_COMMON_CDW13_CEV_MASK) |
4878+
NVME_FIELD_ENCODE(dspec,
4879+
NVME_IOCS_COMMON_CDW13_DSPEC_SHIFT,
4880+
NVME_IOCS_COMMON_CDW13_DSPEC_MASK);
4881+
}
47764882

47774883
/**
47784884
* nvme_init_resv_acquire() - Initialize passthru command for

libnvme/test/ioctl/misc.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -999,43 +999,39 @@ static void test_dsm(void)
999999

10001000
static void test_copy(void)
10011001
{
1002+
__u16 nr = 0x12, cev = 0, dspec = 0;
1003+
int copy_size = sizeof(struct nvme_copy_range) * nr, err;
1004+
bool prinfor = false, prinfow = false, stcw = false,
1005+
stcr = false, fua = false, lr = false;
1006+
__u8 cetype = 0, dtype = 0, desfmt = 0xf;
1007+
__u64 sdlba = 0xfffff;
10021008
__u32 result = 0;
1003-
__u16 nr = 0x12;
1004-
int copy_size = sizeof(struct nvme_copy_range) * nr;
10051009

10061010
_cleanup_free_ struct nvme_copy_range *copy = NULL;
10071011

10081012
copy = malloc(copy_size);
10091013
check(copy, "copy: ENOMEM");
10101014

1011-
struct nvme_copy_args args = {
1012-
.sdlba = 0xfffff,
1013-
.result = &result,
1014-
.copy = copy,
1015-
.args_size = sizeof(args),
1016-
.nsid = TEST_NSID,
1017-
.nr = nr,
1018-
.format = 0xf,
1019-
};
1020-
10211015
struct mock_cmd mock_io_cmd = {
10221016
.opcode = nvme_cmd_copy,
10231017
.nsid = TEST_NSID,
1024-
.cdw10 = args.sdlba & 0xffffffff,
1025-
.cdw11 = args.sdlba >> 32,
1026-
.cdw12 = ((args.nr - 1) & 0xff) | ((args.format & 0xf) << 8) |
1027-
((args.prinfor & 0xf) << 12) |
1028-
((args.dtype & 0xf) << 20) |
1029-
((args.prinfow & 0xf) << 26) |
1030-
((args.fua & 0x1) << 30) | ((args.lr & 0x1) << 31),
1031-
.data_len = args.nr * sizeof(struct nvme_copy_range),
1032-
.in_data = args.copy,
1018+
.cdw10 = sdlba & 0xffffffff,
1019+
.cdw11 = sdlba >> 32,
1020+
.cdw12 = ((nr - 1) & 0xff) | ((desfmt & 0xf) << 8) |
1021+
((prinfor & 0xf) << 12) |
1022+
((dtype & 0xf) << 20) |
1023+
((prinfow & 0xf) << 26) |
1024+
((fua & 0x1) << 30) | ((lr & 0x1) << 31),
1025+
.data_len = nr * sizeof(struct nvme_copy_range),
1026+
.in_data = copy,
10331027
};
1034-
1035-
int err;
1028+
struct nvme_passthru_cmd cmd;
10361029

10371030
set_mock_io_cmds(&mock_io_cmd, 1);
1038-
err = nvme_copy(test_hdl, &args);
1031+
nvme_init_copy(&cmd, TEST_NSID, sdlba, nr, desfmt,
1032+
prinfor, prinfow, cetype, dtype, stcw, stcr,
1033+
fua, lr, cev, dspec, (void *)copy);
1034+
err = nvme_submit_io_passthru(test_hdl, &cmd, &result);
10391035
end_mock_cmds();
10401036
check(err == 0, "returned error %d", err);
10411037
check(result == 0, "returned result %u", result);

0 commit comments

Comments
 (0)