diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index 51830f445..f6e9fe060 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -125,13 +125,13 @@ static int bdev_nvme_library_init(void); static void bdev_nvme_library_fini(void); static int bdev_nvme_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba); + struct iovec *iov, int iovcnt, void *md, uint64_t lba_count, uint64_t lba); static int bdev_nvme_no_pi_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba); + struct iovec *iov, int iovcnt, void *md, uint64_t lba_count, uint64_t lba); static int bdev_nvme_writev(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba); + struct iovec *iov, int iovcnt, void *md, uint64_t lba_count, uint64_t lba); static int bdev_nvme_admin_passthru(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, struct nvme_bdev_io *bio, struct spdk_nvme_cmd *cmd, void *buf, size_t nbytes); @@ -368,6 +368,7 @@ bdev_nvme_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, (struct nvme_bdev_io *)bdev_io->driver_ctx, bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, + bdev_io->u.bdev.md_buf, bdev_io->u.bdev.num_blocks, bdev_io->u.bdev.offset_blocks); @@ -404,6 +405,7 @@ _bdev_nvme_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_ nbdev_io, bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, + bdev_io->u.bdev.md_buf, bdev_io->u.bdev.num_blocks, bdev_io->u.bdev.offset_blocks); @@ -737,13 +739,6 @@ nvme_ctrlr_create_bdev(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, uint32_t nsid) if (bdev->disk.md_len != 0) { nsdata = spdk_nvme_ns_get_data(ns); bdev->disk.md_interleave = nsdata->flbas.extended; - if (!bdev->disk.md_interleave) { - SPDK_ERRLOG("Bdev doesn't support metadata not intereleaved with block data\n"); - free(bdev->disk.name); - nvme_bdev_ctrlr->ref--; - memset(bdev, 0, sizeof(*bdev)); - return -EINVAL; - } bdev->disk.dif_type = (enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns); if (bdev->disk.dif_type != SPDK_DIF_DISABLE) { bdev->disk.dif_is_head_of_md = nsdata->dps.md_start; @@ -1642,8 +1637,19 @@ bdev_nvme_verify_pi_error(struct spdk_bdev_io *bdev_io) return; } - rc = spdk_dif_verify(bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, - bdev_io->u.bdev.num_blocks, &dif_ctx, &err_blk); + if (bdev->md_interleave) { + rc = spdk_dif_verify(bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, + bdev_io->u.bdev.num_blocks, &dif_ctx, &err_blk); + } else { + struct iovec md_iov = { + .iov_base = bdev_io->u.bdev.md_buf, + .iov_len = bdev_io->u.bdev.num_blocks * bdev->md_len, + }; + + rc = spdk_dix_verify(bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, + &md_iov, bdev_io->u.bdev.num_blocks, &dif_ctx, &err_blk); + } + if (rc != 0) { SPDK_ERRLOG("DIF error detected. type=%d, offset=%" PRIu32 "\n", err_blk.err_type, err_blk.err_offset); @@ -1688,6 +1694,7 @@ bdev_nvme_readv_done(void *ref, const struct spdk_nvme_cpl *cpl) bio, bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt, + bdev_io->u.bdev.md_buf, bdev_io->u.bdev.num_blocks, bdev_io->u.bdev.offset_blocks); if (ret == 0) { @@ -1787,8 +1794,8 @@ bdev_nvme_queued_next_sge(void *ref, void **address, uint32_t *length) static int bdev_nvme_no_pi_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, - struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba) + struct nvme_bdev_io *bio, struct iovec *iov, int iovcnt, + void *md, uint64_t lba_count, uint64_t lba) { struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch); int rc; @@ -1801,9 +1808,10 @@ bdev_nvme_no_pi_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, bio->iovpos = 0; bio->iov_offset = 0; - rc = spdk_nvme_ns_cmd_readv(nbdev->ns, nvme_ch->qpair, lba, lba_count, - bdev_nvme_no_pi_readv_done, bio, 0, - bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge); + rc = spdk_nvme_ns_cmd_readv_with_md(nbdev->ns, nvme_ch->qpair, lba, lba_count, + bdev_nvme_no_pi_readv_done, bio, 0, + bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge, + md, 0, 0); if (rc != 0 && rc != -ENOMEM) { SPDK_ERRLOG("no_pi_readv failed: rc = %d\n", rc); @@ -1813,8 +1821,8 @@ bdev_nvme_no_pi_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, static int bdev_nvme_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, - struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba) + struct nvme_bdev_io *bio, struct iovec *iov, int iovcnt, + void *md, uint64_t lba_count, uint64_t lba) { struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch); int rc; @@ -1827,9 +1835,10 @@ bdev_nvme_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, bio->iovpos = 0; bio->iov_offset = 0; - rc = spdk_nvme_ns_cmd_readv(nbdev->ns, nvme_ch->qpair, lba, lba_count, - bdev_nvme_readv_done, bio, nbdev->disk.dif_check_flags, - bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge); + rc = spdk_nvme_ns_cmd_readv_with_md(nbdev->ns, nvme_ch->qpair, lba, lba_count, + bdev_nvme_readv_done, bio, nbdev->disk.dif_check_flags, + bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge, + md, 0, 0); if (rc != 0 && rc != -ENOMEM) { SPDK_ERRLOG("readv failed: rc = %d\n", rc); @@ -1840,7 +1849,7 @@ bdev_nvme_readv(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, static int bdev_nvme_writev(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, struct nvme_bdev_io *bio, - struct iovec *iov, int iovcnt, uint64_t lba_count, uint64_t lba) + struct iovec *iov, int iovcnt, void *md, uint64_t lba_count, uint64_t lba) { struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(ch); int rc; @@ -1853,9 +1862,10 @@ bdev_nvme_writev(struct nvme_bdev *nbdev, struct spdk_io_channel *ch, bio->iovpos = 0; bio->iov_offset = 0; - rc = spdk_nvme_ns_cmd_writev(nbdev->ns, nvme_ch->qpair, lba, lba_count, - bdev_nvme_writev_done, bio, nbdev->disk.dif_check_flags, - bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge); + rc = spdk_nvme_ns_cmd_writev_with_md(nbdev->ns, nvme_ch->qpair, lba, lba_count, + bdev_nvme_writev_done, bio, nbdev->disk.dif_check_flags, + bdev_nvme_queued_reset_sgl, bdev_nvme_queued_next_sge, + md, 0, 0); if (rc != 0 && rc != -ENOMEM) { SPDK_ERRLOG("writev failed: rc = %d\n", rc);