Skip to content
Merged
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
122 changes: 78 additions & 44 deletions nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -7175,6 +7175,66 @@ static void get_pif_sts(struct nvme_id_ns *ns, struct nvme_nvm_id_ns *nvm_ns,
*pif = (elbaf & NVME_NVM_ELBAF_QPIF_MASK) >> 9;
}

static int get_pi_info(struct nvme_transport_handle *hdl,
__u32 nsid, __u8 prinfo, __u64 ilbrt, __u64 lbst,
unsigned int *logical_block_size, __u16 *metadata_size)
{
_cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
_cleanup_free_ struct nvme_id_ns *ns = NULL;
__u8 sts = 0, pif = 0;
unsigned int lbs = 0;
__u8 lba_index;
int pi_size;
__u16 ms;
int err;

ns = nvme_alloc(sizeof(*ns));
if (!ns)
return -ENOMEM;

err = nvme_identify_ns(hdl, nsid, ns);
if (err > 0) {
nvme_show_status(err);
return err;
} else if (err < 0) {
nvme_show_error("identify namespace: %s", nvme_strerror(err));
return err;
}

nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
lbs = 1 << ns->lbaf[lba_index].ds;
ms = le16_to_cpu(ns->lbaf[lba_index].ms);

nvm_ns = nvme_alloc(sizeof(*nvm_ns));
if (!nvm_ns)
return -ENOMEM;

err = nvme_identify_csi_ns(hdl, nsid, NVME_CSI_NVM, 0,
nvm_ns);
if (err)
return -ENAVAIL;

get_pif_sts(ns, nvm_ns, &pif, &sts);
pi_size = (pif == NVME_NVM_PIF_16B_GUARD) ? 8 : 16;
if (NVME_FLBAS_META_EXT(ns->flbas)) {
/*
* No meta data is transferred for PRACT=1 and MD=PI size:
* 5.2.2.1 Protection Information and Write Commands
* 5.2.2.2 Protection Information and Read Commands
*/
if (!((prinfo & 0x8) != 0 && ms == pi_size))
logical_block_size += ms;
}

if (invalid_tags(lbst, ilbrt, sts, pif))
return -EINVAL;

*logical_block_size = lbs;
*metadata_size = ms;

return 0;
}

static int init_pi_tags(struct nvme_transport_handle *hdl,
struct nvme_passthru_cmd *cmd, __u32 nsid, __u64 ilbrt, __u64 lbst,
__u16 lbat, __u16 lbatm)
Expand Down Expand Up @@ -8073,14 +8133,15 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
struct timeval start_time, end_time;
_cleanup_free_ void *mbuffer = NULL;
_cleanup_fd_ int dfd = -1, mfd = -1;
__u8 lba_index, sts = 0, pif = 0;
__u16 control = 0, nblocks = 0;
struct nvme_passthru_cmd cmd;
int flags, pi_size;
__u8 sts = 0, pif = 0;
bool pi_available;
__u32 dsmgmt = 0;
int mode = 0644;
void *buffer;
int err = 0;
int flags;
__u16 ms;

const char *start_block_addr = "64-bit addr of first block to access";
Expand Down Expand Up @@ -8255,46 +8316,17 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
if (cfg.block_size) {
logical_block_size = cfg.block_size;
ms = cfg.metadata_size;
pi_available = true;
} else {
ns = nvme_alloc(sizeof(*ns));
if (!ns)
return -ENOMEM;

err = nvme_identify_ns(hdl, cfg.nsid, ns);
if (err > 0) {
nvme_show_status(err);
return err;
} else if (err < 0) {
nvme_show_error("identify namespace: %s", nvme_strerror(err));
return err;
}

nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
logical_block_size = 1 << ns->lbaf[lba_index].ds;
ms = le16_to_cpu(ns->lbaf[lba_index].ms);

nvm_ns = nvme_alloc(sizeof(*nvm_ns));
if (!nvm_ns)
return -ENOMEM;

err = nvme_identify_csi_ns(hdl, cfg.nsid, NVME_CSI_NVM, 0,
nvm_ns);
if (!err)
get_pif_sts(ns, nvm_ns, &pif, &sts);

pi_size = (pif == NVME_NVM_PIF_16B_GUARD) ? 8 : 16;
if (NVME_FLBAS_META_EXT(ns->flbas)) {
/*
* No meta data is transferred for PRACT=1 and MD=PI size:
* 5.2.2.1 Protection Information and Write Commands
* 5.2.2.2 Protection Information and Read Commands
*/
if (!((cfg.prinfo & 0x8) != 0 && ms == pi_size))
logical_block_size += ms;
err = get_pi_info(hdl, cfg.nsid, cfg.prinfo,
cfg.ilbrt, cfg.lbst, &logical_block_size, &ms);
if (err) {
logical_block_size = 0;
ms = 0;
pi_available = false;
} else {
pi_available = true;
}

if (invalid_tags(cfg.lbst, cfg.ilbrt, sts, pif))
return -EINVAL;
}

buffer_size = ((long long)cfg.block_count + 1) * logical_block_size;
Expand Down Expand Up @@ -8387,10 +8419,12 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
NVME_FIELD_ENCODE(cfg.dsmgmt,
NVME_IOCS_COMMON_CDW13_DSM_SHIFT,
NVME_IOCS_COMMON_CDW13_DSM_MASK);
err = init_pi_tags(hdl, &cmd, cfg.nsid, cfg.ilbrt, cfg.lbst,
cfg.lbat, cfg.lbatm);
if (err)
return err;
if (pi_available) {
err = init_pi_tags(hdl, &cmd, cfg.nsid, cfg.ilbrt, cfg.lbst,
cfg.lbat, cfg.lbatm);
if (err)
return err;
}
gettimeofday(&start_time, NULL);
err = nvme_submit_io_passthru(hdl, &cmd);
gettimeofday(&end_time, NULL);
Expand Down