summaryrefslogtreecommitdiffstats
path: root/src/nvme/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvme/ioctl.c')
-rw-r--r--src/nvme/ioctl.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c
index 2b5e09d..b9710b3 100644
--- a/src/nvme/ioctl.c
+++ b/src/nvme/ioctl.c
@@ -434,7 +434,7 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
{
__u64 offset = 0, xfer, data_len = args->len;
__u64 start = args->lpo;
- bool retain = true;
+ bool retain = args->rae;
void *ptr = args->log;
int ret;
@@ -454,13 +454,10 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
* last portion of this log page so the data remains latched
* during the fetch sequence.
*/
- if (offset + xfer == data_len)
- retain = args->rae;
-
args->lpo = start + offset;
args->len = xfer;
args->log = ptr;
- args->rae = retain;
+ args->rae = offset + xfer < data_len || retain;
ret = nvme_get_log(args);
if (ret)
return ret;
@@ -1235,9 +1232,15 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args)
int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args)
{
+ const size_t size_v1 = sizeof_args(struct nvme_ns_mgmt_args, csi, __u64);
+ const size_t size_v2 = sizeof_args(struct nvme_ns_mgmt_args, data, __u64);
__u32 cdw10 = NVME_SET(args->sel, NAMESPACE_MGMT_CDW10_SEL);
__u32 cdw11 = NVME_SET(args->csi, NAMESPACE_MGMT_CDW11_CSI);
- __u32 data_len = args->ns ? sizeof(*args->ns) : 0;
+
+ if (args->args_size < size_v1 || args->args_size > size_v2) {
+ errno = EINVAL;
+ return -1;
+ }
struct nvme_passthru_cmd cmd = {
.nsid = args->nsid,
@@ -1245,13 +1248,19 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args)
.cdw10 = cdw10,
.cdw11 = cdw11,
.timeout_ms = args->timeout,
- .data_len = data_len,
- .addr = (__u64)(uintptr_t)args->ns,
};
- if (args->args_size < sizeof(*args)) {
- errno = EINVAL;
- return -1;
+ if (args->args_size == size_v2) {
+ if (args->data) {
+ cmd.data_len = sizeof(*args->data);
+ cmd.addr = (__u64)(uintptr_t)args->data;
+ }
+ }
+ else {
+ if (args->ns) {
+ cmd.data_len = sizeof(*args->ns);
+ cmd.addr = (__u64)(uintptr_t)args->ns;
+ }
}
return nvme_submit_admin_passthru(args->fd, &cmd, args->result);
}
@@ -1901,7 +1910,7 @@ int nvme_resv_report(struct nvme_resv_report_args *args)
int nvme_io_mgmt_recv(struct nvme_io_mgmt_recv_args *args)
{
- __u32 cdw10 = (args->mo & 0xf) | (args->mos & 0xff << 16);
+ __u32 cdw10 = args->mo | (args->mos << 16);
__u32 cdw11 = (args->data_len >> 2) - 1;
struct nvme_passthru_cmd cmd = {
@@ -1924,7 +1933,7 @@ int nvme_io_mgmt_recv(struct nvme_io_mgmt_recv_args *args)
int nvme_io_mgmt_send(struct nvme_io_mgmt_send_args *args)
{
- __u32 cdw10 = (args->mo & 0xf) | ((args->mos & 0xff) << 16);
+ __u32 cdw10 = args->mo | (args->mos << 16);
struct nvme_passthru_cmd cmd = {
.opcode = nvme_cmd_io_mgmt_send,