Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nvme-copy: add cross-namespace copy formats, status codes, ONCS bits #733

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/libnvme.map
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ LIBNVME_1_6 {
nvme_set_root;
nvme_subsystem_get_iopolicy;
nvme_subsystem_release_fds;
nvme_init_copy_range_f2;
nvme_init_copy_range_f3;
};

LIBNVME_1_5 {
Expand Down
4 changes: 4 additions & 0 deletions src/nvme/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1976,6 +1976,10 @@ int nvme_copy(struct nvme_copy_args *args)

if (args->format == 1)
data_len = args->nr * sizeof(struct nvme_copy_range_f1);
else if (args->format == 2)
data_len = args->nr * sizeof(struct nvme_copy_range_f2);
else if (args->format == 3)
data_len = args->nr * sizeof(struct nvme_copy_range_f3);
else
data_len = args->nr * sizeof(struct nvme_copy_range);

Expand Down
95 changes: 94 additions & 1 deletion src/nvme/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,14 @@ enum nvme_id_ctrl_cqes {
* the Verify command.
* @NVME_CTRL_ONCS_COPY: If set, then the controller supports
* the copy command.
* @NVME_CTRL_ONCS_COPY_SINGLE_ATOMICITY: If set, then the write portion of a
jgu-pure marked this conversation as resolved.
Show resolved Hide resolved
* Copy command is performed as a single
* write command to which the same
* atomicity requirements that apply to
* a write command apply.
* @NVME_CTRL_ONCS_ALL_FAST_COPY: If set, then all copy operations for
* the Copy command are fast copy
* operations.
*/
enum nvme_id_ctrl_oncs {
NVME_CTRL_ONCS_COMPARE = 1 << 0,
Expand All @@ -1517,6 +1525,8 @@ enum nvme_id_ctrl_oncs {
NVME_CTRL_ONCS_TIMESTAMP = 1 << 6,
NVME_CTRL_ONCS_VERIFY = 1 << 7,
NVME_CTRL_ONCS_COPY = 1 << 8,
NVME_CTRL_ONCS_COPY_SINGLE_ATOMICITY = 1 << 9,
NVME_CTRL_ONCS_ALL_FAST_COPY = 1 << 10,
};

/**
Expand Down Expand Up @@ -4734,10 +4744,14 @@ struct nvme_plm_config {
* struct nvme_feat_host_behavior - Host Behavior Support - Data Structure
* @acre: Advanced Command Retry Enable
* @rsvd1: Reserved
* @cdfe: Copy Descriptor Formats Enable
* @rsvd6: Reserved
*/
struct nvme_feat_host_behavior {
__u8 acre;
__u8 rsvd1[511];
__u8 rsvd1[3];
__u16 cdfe;
__u8 rsvd6[506];
};

/**
Expand Down Expand Up @@ -4802,6 +4816,66 @@ struct nvme_copy_range_f1 {
__le16 elbatm;
};

/**
* enum nvme_copy_range_sopt - NVMe Copy Range Source Options
* @NVME_COPY_SOPT_FCO: NVMe Copy Source Option Fast Copy Only
*/
enum nvme_copy_range_sopt {
NVME_COPY_SOPT_FCO = 1 << 15,
};

/**
* struct nvme_copy_range_f2 - Copy - Source Range Entries Descriptor Format 2h
* @snsid: Source Namespace Identifier
* @rsvd4: Reserved
* @slba: Starting LBA
* @nlb: Number of Logical Blocks
* @rsvd18: Reserved
* @sopt: Source Options
* @eilbrt: Expected Initial Logical Block Reference Tag /
* Expected Logical Block Storage Tag
* @elbatm: Expected Logical Block Application Tag Mask
* @elbat: Expected Logical Block Application Tag
*/
struct nvme_copy_range_f2 {
__le32 snsid;
__u8 rsvd4[4];
__le64 slba;
__le16 nlb;
__u8 rsvd18[4];
__le16 sopt;
jgu-pure marked this conversation as resolved.
Show resolved Hide resolved
__le32 eilbrt;
__le16 elbat;
__le16 elbatm;
};

/**
* struct nvme_copy_range_f3 - Copy - Source Range Entries Descriptor Format 3h
* @snsid: Source Namespace Identifier
* @rsvd4: Reserved
* @slba: Starting LBA
* @nlb: Number of Logical Blocks
* @rsvd18: Reserved
* @sopt: Source Options
* @rsvd24: Reserved
* @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
*/
struct nvme_copy_range_f3 {
__le32 snsid;
__u8 rsvd4[4];
__le64 slba;
__le16 nlb;
__u8 rsvd18[4];
__le16 sopt;
jgu-pure marked this conversation as resolved.
Show resolved Hide resolved
__u8 rsvd24[2];
__u8 elbt[10];
__le16 elbat;
__le16 elbatm;
};

/**
* struct nvme_registered_ctrl - Registered Controller Data Structure
* @cntlid: Controller ID
Expand Down Expand Up @@ -6254,6 +6328,21 @@ struct nvme_mi_vpd_hdr {
* @NVME_SC_INVALID_PI: Invalid Protection Information
* @NVME_SC_READ_ONLY: Attempted Write to Read Only Range
* @NVME_SC_CMD_SIZE_LIMIT_EXCEEDED: Command Size Limit Exceeded
* @NVME_SC_INCOMPATIBLE_NS: Incompatible Namespace or Format: At
* least one source namespace and the
* destination namespace have incompatible
* formats.
* @NVME_SC_FAST_COPY_NOT_POSSIBLE: Fast Copy Not Possible: The Fast Copy
* Only (FCO) bit was set to ‘1’ in a Source
* Range entry and the controller was not
* able to use fast copy operations to copy
* the specified data.
* @NVME_SC_OVERLAPPING_IO_RANGE: Overlapping I/O Range: A source logical
* block range overlaps the destination
* logical block range.
* @NVME_SC_INSUFFICIENT_RESOURCES: Insufficient Resources: A resource
* shortage prevented the controller from
* performing the requested copy.
* @NVME_SC_CONNECT_FORMAT: Incompatible Format: The NVM subsystem
* does not support the record format
* specified by the host.
Expand Down Expand Up @@ -6499,6 +6588,10 @@ enum nvme_status_field {
NVME_SC_INVALID_PI = 0x81,
NVME_SC_READ_ONLY = 0x82,
NVME_SC_CMD_SIZE_LIMIT_EXCEEDED = 0x83,
NVME_SC_INCOMPATIBLE_NS = 0x85,
NVME_SC_FAST_COPY_NOT_POSSIBLE = 0x86,
NVME_SC_OVERLAPPING_IO_RANGE = 0x87,
NVME_SC_INSUFFICIENT_RESOURCES = 0x89,

/*
* I/O Command Set Specific - Fabrics commands:
Expand Down
56 changes: 51 additions & 5 deletions src/nvme/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ static const char * const nvm_status[] = {
[NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format",
[NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks",
[NVME_SC_CMD_SIZE_LIMIT_EXCEEDED] = "Command Size Limit Exceeded",
[NVME_SC_INCOMPATIBLE_NS] = "Incompatible Namespace or Format",
[NVME_SC_FAST_COPY_NOT_POSSIBLE] = "Fast Copy Not Possible",
[NVME_SC_OVERLAPPING_IO_RANGE] = "Overlapping I/O Range",
[NVME_SC_INSUFFICIENT_RESOURCES] = "Insufficient Resources",
[NVME_SC_ZNS_INVALID_OP_REQUEST] = "Invalid Zone Operation Request: The operation requested is invalid",
[NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE] = "ZRWA Resources Unavailable: No ZRWAs are available",
[NVME_SC_ZNS_BOUNDARY_ERROR] = "Zoned Boundary Error: Invalid Zone Boundary crossing",
Expand Down Expand Up @@ -386,6 +390,15 @@ const char *nvme_status_to_string(int status, bool fabrics)
return s;
}

static inline void nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt)
{
int i;
for (i = 0; i < 8; i++)
elbt[9 - i] = (eilbrt >> (8 * i)) & 0xff;
elbt[1] = 0;
elbt[0] = 0;
}

void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs,
__u64 *slbas, __u32 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr)
Expand All @@ -405,20 +418,53 @@ void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs,
__u64 *slbas, __u64 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr)
{
int i, j;
int i;

for (i = 0; i < nr; i++) {
copy[i].nlb = cpu_to_le16(nlbs[i]);
copy[i].slba = cpu_to_le64(slbas[i]);
copy[i].elbatm = cpu_to_le16(elbatms[i]);
copy[i].elbat = cpu_to_le16(elbats[i]);
for (j = 0; j < 8; j++)
copy[i].elbt[9 - j] = (eilbrts[i] >> (8 * j)) & 0xff;
copy[i].elbt[1] = 0;
copy[i].elbt[0] = 0;
nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]);
}
jgu-pure marked this conversation as resolved.
Show resolved Hide resolved
}

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,
__u16 nr)
{
int i;

for (i = 0; i < nr; i++) {
copy[i].snsid = cpu_to_le32(snsids[i]);
copy[i].nlb = cpu_to_le16(nlbs[i]);
copy[i].slba = cpu_to_le64(slbas[i]);
copy[i].sopt = cpu_to_le16(sopts[i]);
copy[i].eilbrt = cpu_to_le32(eilbrts[i]);
copy[i].elbatm = cpu_to_le16(elbatms[i]);
copy[i].elbat = cpu_to_le16(elbats[i]);
}
}

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,
__u16 nr)
{
int i;

for (i = 0; i < nr; i++) {
copy[i].snsid = cpu_to_le32(snsids[i]);
copy[i].nlb = cpu_to_le16(nlbs[i]);
copy[i].slba = cpu_to_le64(slbas[i]);
copy[i].sopt = cpu_to_le16(sopts[i]);
copy[i].elbatm = cpu_to_le16(elbatms[i]);
copy[i].elbat = cpu_to_le16(elbats[i]);
nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]);
}
}

void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs,
__u32 *llbas, __u64 *slbas, __u16 nr_ranges)
{
Expand Down
34 changes: 34 additions & 0 deletions src/nvme/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,40 @@ void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs,
__u64 *slbas, __u64 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr);

/**
* nvme_init_copy_range_f2() - Constructs a copy range f2 structure
* @copy: Copy range array
* @snsids: Source namespace identifier
* @nlbs: Number of logical blocks
* @slbas: Starting LBA
* @sopts: Source options
* @eilbrts: 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
*/
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,
jgu-pure marked this conversation as resolved.
Show resolved Hide resolved
__u16 nr);

/**
* nvme_init_copy_range_f3() - Constructs a copy range f3 structure
* @copy: Copy range array
* @snsids: Source namespace identifier
* @nlbs: Number of logical blocks
* @slbas: Starting LBA
* @sopts: Source options
* @eilbrts: 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
*/
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,
__u16 nr);

/**
* nvme_get_feature_length() - Retreive the command payload length for a
* specific feature identifier
Expand Down
Loading