Skip to content

Commit 0358361

Browse files
hreineckedwsuse
authored andcommitted
Use argument structure for NVMe I/O commands
Use an argument structure for NVMe I/O commands like nvme_read() or nvme_write() instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke <[email protected]>
1 parent db91866 commit 0358361

3 files changed

Lines changed: 208 additions & 217 deletions

File tree

src/nvme/ioctl.c

Lines changed: 18 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,23 +1552,20 @@ int nvme_flush(int fd, __u32 nsid)
15521552
return nvme_submit_io_passthru(fd, &cmd, NULL);
15531553
}
15541554

1555-
static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb,
1556-
__u16 control, __u32 flags, __u32 reftag, __u16 apptag, __u16 appmask,
1557-
__u64 storage_tag, __u32 data_len, void *data, __u32 metadata_len,
1558-
void *metadata, __u32 timeout)
1555+
int nvme_io(struct nvme_io_args *args, __u8 opcode)
15591556
{
1560-
__u32 cdw2 = storage_tag & 0xffffffff;
1561-
__u32 cdw3 = (storage_tag >> 32) & 0xffff;
1562-
__u32 cdw10 = slba & 0xffffffff;
1563-
__u32 cdw11 = slba >> 32;
1564-
__u32 cdw12 = nlb | (control << 16);
1565-
__u32 cdw13 = flags;
1566-
__u32 cdw14 = reftag;
1567-
__u32 cdw15 = apptag | (appmask << 16);
1557+
__u32 cdw2 = args->storage_tag & 0xffffffff;
1558+
__u32 cdw3 = (args->storage_tag >> 32) & 0xffff;
1559+
__u32 cdw10 = args->slba & 0xffffffff;
1560+
__u32 cdw11 = args->slba >> 32;
1561+
__u32 cdw12 = args->nlb | (args->control << 16);
1562+
__u32 cdw13 = args->dsm | (args->dspec << 16);
1563+
__u32 cdw14 = args->reftag;
1564+
__u32 cdw15 = args->apptag | (args->appmask << 16);
15681565

15691566
struct nvme_passthru_cmd cmd = {
15701567
.opcode = opcode,
1571-
.nsid = nsid,
1568+
.nsid = args->nsid,
15721569
.cdw2 = cdw2,
15731570
.cdw3 = cdw3,
15741571
.cdw10 = cdw10,
@@ -1577,69 +1574,16 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb,
15771574
.cdw13 = cdw13,
15781575
.cdw14 = cdw14,
15791576
.cdw15 = cdw15,
1580-
.data_len = data_len,
1581-
.metadata_len = metadata_len,
1582-
.addr = (__u64)(uintptr_t)data,
1583-
.metadata = (__u64)(uintptr_t)metadata,
1584-
.timeout_ms = timeout,
1577+
.data_len = args->data_len,
1578+
.metadata_len = args->metadata_len,
1579+
.addr = (__u64)(uintptr_t)args->data,
1580+
.metadata = (__u64)(uintptr_t)args->metadata,
1581+
.timeout_ms = args->timeout,
15851582
};
15861583

1587-
return nvme_submit_io_passthru(fd, &cmd, NULL);
1588-
}
1589-
1590-
int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
1591-
__u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask,
1592-
__u64 storage_tag, __u32 data_len, void *data,
1593-
__u32 metadata_len, void *metadata, __u32 timeout)
1594-
{
1595-
return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm,
1596-
reftag, apptag, appmask, storage_tag, data_len, data,
1597-
metadata_len, metadata, timeout);
1598-
}
1599-
1600-
int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
1601-
__u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag,
1602-
__u16 appmask, __u64 storage_tag, __u32 data_len, void *data,
1603-
__u32 metadata_len, void *metadata, __u32 timeout)
1604-
{
1605-
__u32 flags = dsm | dspec << 16;
1606-
1607-
return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags,
1608-
reftag, apptag, appmask, storage_tag, data_len, data,
1609-
metadata_len, metadata, timeout);
1610-
}
1611-
1612-
int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
1613-
__u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len,
1614-
void *data, __u32 metadata_len, void *metadata, __u32 timeout)
1615-
{
1616-
return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0,
1617-
reftag, apptag, appmask, 0, data_len, data, metadata_len,
1618-
metadata, timeout);
1619-
}
1620-
1621-
int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
1622-
__u32 reftag, __u16 apptag, __u16 appmask,
1623-
__u64 storage_tag, __u32 timeout)
1624-
{
1625-
return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0,
1626-
reftag, apptag, appmask, storage_tag, 0, NULL, 0, NULL,
1627-
timeout);
1628-
}
1629-
1630-
int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
1631-
__u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag,
1632-
__u32 timeout)
1633-
{
1634-
return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0,
1635-
reftag, apptag, appmask, 0, 0, NULL, 0, NULL, timeout);
1636-
}
1637-
1638-
int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb,
1639-
__u32 timeout)
1640-
{
1641-
return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0,
1642-
0, 0, 0, NULL, 0, NULL, timeout);
1584+
if (args->args_size < sizeof(*args))
1585+
return -EINVAL;
1586+
return nvme_submit_io_passthru(args->fd, &cmd, args->result);
16431587
}
16441588

16451589
int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges,

src/nvme/ioctl.h

Lines changed: 64 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,7 @@ int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args);
35703570
int nvme_flush(int fd, __u32 nsid);
35713571

35723572
/**
3573-
* nvme_read() - Submit an nvme user read command
3573+
* nvme_io_args - Arguments for NVMe I/O commands
35743574
* @fd: File descriptor of nvme device
35753575
* @nsid: Namespace ID
35763576
* @slba: Starting logical block
@@ -3594,99 +3594,76 @@ int nvme_flush(int fd, __u32 nsid);
35943594
* @metadata_len:Length of user buffer, @metadata, in bytes
35953595
* @metadata: Pointer to user address of the metadata buffer
35963596
* @timeout: Timeout in ms
3597+
*/
3598+
struct nvme_io_args {
3599+
int args_size;
3600+
int fd;
3601+
__u32 nsid;
3602+
__u64 slba;
3603+
__u16 nlb;
3604+
__u16 control;
3605+
__u8 dsm;
3606+
__u8 dspec;
3607+
__u32 reftag;
3608+
__u16 apptag;
3609+
__u16 appmask;
3610+
__u64 storage_tag;
3611+
__u32 data_len;
3612+
void *data;
3613+
__u32 metadata_len;
3614+
void *metadata;
3615+
__u32 timeout;
3616+
__u32 *result;
3617+
};
3618+
3619+
/**
3620+
* nvme_io() - Submit an nvme user I/O command
3621+
* @args: &struct nvme_io_args argument structure
3622+
*
3623+
* Return: The nvme command status if a response was received (see
3624+
* &enum nvme_status_field) or -1 with errno set otherwise.
3625+
*/
3626+
int nvme_io(struct nvme_io_args *args, __u8 opcode);
3627+
3628+
/**
3629+
* nvme_read() - Submit an nvme user read command
3630+
* @args: &struct nvme_io_args argument structure
35973631
*
35983632
* Return: The nvme command status if a response was received (see
35993633
* &enum nvme_status_field) or -1 with errno set otherwise.
36003634
*/
3601-
int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
3602-
__u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask,
3603-
__u64 storage_tag, __u32 data_len, void *data,
3604-
__u32 metadata_len, void *metadata, __u32 timeout);
3635+
static inline int nvme_read(struct nvme_io_args *args)
3636+
{
3637+
return nvme_io(args, nvme_cmd_read);
3638+
}
36053639

36063640
/**
36073641
* nvme_write() - Submit an nvme user write command
3608-
* @fd: File descriptor of nvme device
3609-
* @nsid: Namespace ID
3610-
* @slba: Starting logical block
3611-
* @nblocks: Number of logical blocks to send (0's based value)
3612-
* @control: Command control flags, see &enum nvme_io_control_flags.
3613-
* @dsm: Data set management attributes, see &enum nvme_io_dsm_flags
3614-
* @dspec: Directive specific command, eg: stream identifier
3615-
* @reftag: This field specifies the Initial Logical Block Reference Tag
3616-
* expected value. Used only if the namespace is formatted to use
3617-
* end-to-end protection information.
3618-
* @apptag: This field specifies the Application Tag Mask expected value.
3619-
* Used only if the namespace is formatted to use end-to-end
3620-
* protection information.
3621-
* @appmask: This field specifies the Application Tag expected value. Used
3622-
* only if the namespace is formatted to use end-to-end protection
3623-
* information.
3624-
* @storage_tag: This filed specifies Variable Sized Expected Logical Block
3625-
* Storage Tag (ELBST) and Expected Logical Block Reference
3626-
* Tag (ELBRT)
3627-
* @data_len: Length of user buffer, @data, in bytes
3628-
* @data: Pointer to user address of the data buffer
3629-
* @metadata_len:Length of user buffer, @metadata, in bytes
3630-
* @metadata: Pointer to user address of the metadata buffer
3631-
* @timeout: Timeout in ms
3642+
* @args: &struct nvme_io_args argument structure
36323643
*
36333644
* Return: The nvme command status if a response was received (see
36343645
* &enum nvme_status_field) or -1 with errno set otherwise.
36353646
*/
3636-
int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
3637-
__u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag,
3638-
__u16 appmask, __u64 storage_tag, __u32 data_len, void *data,
3639-
__u32 metadata_len, void *metadata, __u32 timeout);
3647+
static inline int nvme_write(struct nvme_io_args *args)
3648+
{
3649+
return nvme_io(args, nvme_cmd_write);
3650+
}
36403651

36413652
/**
36423653
* nvme_compare() - Submit an nvme user compare command
3643-
* @fd: File descriptor of nvme device
3644-
* @nsid: Namespace ID
3645-
* @slba: Starting logical block
3646-
* @nblocks: Number of logical blocks to send (0's based value)
3647-
* @control: Command control flags, see &enum nvme_io_control_flags.
3648-
* @reftag: This field specifies the Initial Logical Block Reference Tag
3649-
* expected value. Used only if the namespace is formatted to use
3650-
* end-to-end protection information.
3651-
* @apptag: This field specifies the Application Tag Mask expected value.
3652-
* Used only if the namespace is formatted to use end-to-end
3653-
* protection information.
3654-
* @appmask: This field specifies the Application Tag expected value. Used
3655-
* only if the namespace is formatted to use end-to-end protection
3656-
* information.
3657-
* @data_len: Length of user buffer, @data, in bytes
3658-
* @data: Pointer to user address of the data buffer
3659-
* @metadata_len:Length of user buffer, @metadata, in bytes
3660-
* @metadata: Pointer to user address of the metadata buffer
3661-
* @timeout: Timeout in ms
3654+
* @args: &struct nvme_io_args argument structure
36623655
*
36633656
* Return: The nvme command status if a response was received (see
36643657
* &enum nvme_status_field) or -1 with errno set otherwise.
36653658
*/
3666-
int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
3667-
__u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len,
3668-
void *data, __u32 metadata_len, void *metadata, __u32 timeout);
3659+
static inline int nvme_compare(struct nvme_io_args *args)
3660+
{
3661+
return nvme_io(args, nvme_cmd_compare);
3662+
}
36693663

36703664
/**
36713665
* nvme_write_zeros() - Submit an nvme write zeroes command
3672-
* @fd: File descriptor of nvme device
3673-
* @nsid: Namespace identifier
3674-
* @slba: Starting logical block
3675-
* @nlb: Number of logical blocks to clear (0's based value)
3676-
* @control: Command control flags, see &enum nvme_io_control_flags.
3677-
* @reftag: This field specifies the Initial Logical Block Reference Tag
3678-
* expected value. Used only if the namespace is formatted to use
3679-
* end-to-end protection information.
3680-
* @apptag: This field specifies the Application Tag Mask expected value.
3681-
* Used only if the namespace is formatted to use end-to-end
3682-
* protection information.
3683-
* @appmask: This field specifies the Application Tag expected value. Used
3684-
* only if the namespace is formatted to use end-to-end protection
3685-
* information.
3686-
* @storage_tag: This filed specifies Variable Sized Expected Logical Block
3687-
* Storage Tag (ELBST) and Expected Logical Block Reference
3688-
* Tag (ELBRT)
3689-
* @timeout: Timeout in ms
3666+
* @args: &struct nvme_io_args argument structure
36903667
*
36913668
* The Write Zeroes command sets a range of logical blocks to zero. After
36923669
* successful completion of this command, the value returned by subsequent
@@ -3696,17 +3673,14 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
36963673
* Return: The nvme command status if a response was received (see
36973674
* &enum nvme_status_field) or -1 with errno set otherwise.
36983675
*/
3699-
int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
3700-
__u32 reftag, __u16 apptag, __u16 appmask,
3701-
__u64 storage_tag, __u32 timeout);
3676+
static inline int nvme_write_zeros(struct nvme_io_args *args)
3677+
{
3678+
return nvme_io(args, nvme_cmd_write_zeroes);
3679+
}
37023680

37033681
/**
37043682
* nvme_write_uncorrectable() - Submit an nvme write uncorrectable command
3705-
* @fd: File descriptor of nvme device
3706-
* @nsid: Namespace identifier
3707-
* @slba: Starting logical block
3708-
* @nlb: Number of logical blocks to invalidate (0's based value)
3709-
* @timeout: Timeout in ms
3683+
* @args: &struct nvme_io_args argument structure
37103684
*
37113685
* The Write Uncorrectable command marks a range of logical blocks as invalid.
37123686
* When the specified logical block(s) are read after this operation, a failure
@@ -3716,29 +3690,14 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
37163690
* Return: The nvme command status if a response was received (see
37173691
* &enum nvme_status_field) or -1 with errno set otherwise.
37183692
*/
3719-
int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb,
3720-
__u32 timeout);
3693+
static inline int nvme_write_uncorrectable(struct nvme_io_args *args)
3694+
{
3695+
return nvme_io(args, nvme_cmd_write_uncor);
3696+
}
37213697

37223698
/**
37233699
* nvme_verify() - Send an nvme verify command
3724-
* @fd: File descriptor of nvme device
3725-
* @nsid: Namespace identifier
3726-
* @slba: Starting logical block
3727-
* @nlb: Number of logical blocks to verify (0's based value)
3728-
* @control: Command control flags, see &enum nvme_io_control_flags.
3729-
* @reftag: This field specifies the Initial Logical Block Reference Tag
3730-
* expected value. Used only if the namespace is formatted to use
3731-
* end-to-end protection information.
3732-
* @apptag: This field specifies the Application Tag Mask expected value.
3733-
* Used only if the namespace is formatted to use end-to-end
3734-
* protection information.
3735-
* @appmask: This field specifies the Application Tag expected value. Used
3736-
* only if the namespace is formatted to use end-to-end protection
3737-
* information.
3738-
* @storage_tag: This filed specifies Variable Sized Expected Logical Block
3739-
* Storage Tag (ELBST) and Expected Logical Block Reference
3740-
* Tag (ELBRT)
3741-
* @timeout: Timeout in ms
3700+
* @args: &struct nvme_io_args argument structure
37423701
*
37433702
* The Verify command verifies integrity of stored information by reading data
37443703
* and metadata, if applicable, for the LBAs indicated without transferring any
@@ -3747,9 +3706,10 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb,
37473706
* Return: The nvme command status if a response was received (see
37483707
* &enum nvme_status_field) or -1 with errno set otherwise.
37493708
*/
3750-
int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control,
3751-
__u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag,
3752-
__u32 timeout);
3709+
static inline int nvme_verify(struct nvme_io_args *args)
3710+
{
3711+
return nvme_io(args, nvme_cmd_verify);
3712+
}
37533713

37543714
/**
37553715
* nvme_dsm() - Send an nvme data set management command

0 commit comments

Comments
 (0)