diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index fb6d7312e..abcc2b594 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -761,6 +761,12 @@ bdev_nvme_unmap(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t offset_blocks, uint64_t num_blocks); +static int +bdev_nvme_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, + struct nvme_bdev_io *bio, + uint64_t offset_blocks, + uint64_t num_blocks); + static void bdev_nvme_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success) @@ -876,6 +882,12 @@ bdev_nvme_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_i bdev_io->u.bdev.offset_blocks, bdev_io->u.bdev.num_blocks); break; + case SPDK_BDEV_IO_TYPE_WRITE_ZEROES: + rc = bdev_nvme_write_zeroes(ns, qpair, + nbdev_io, + bdev_io->u.bdev.offset_blocks, + bdev_io->u.bdev.num_blocks); + break; case SPDK_BDEV_IO_TYPE_RESET: rc = bdev_nvme_reset(io_path, bdev_io); break; @@ -989,13 +1001,8 @@ bdev_nvme_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type) return cdata->oncs.dsm; case SPDK_BDEV_IO_TYPE_WRITE_ZEROES: - /* - * The NVMe controller write_zeroes function is currently not used by our driver. - * NVMe write zeroes is limited to 16-bit block count, and the bdev layer currently - * has no mechanism for reporting a max write zeroes block count, nor ability to - * split a write zeroes request. - */ - return false; + cdata = spdk_nvme_ctrlr_get_data(ctrlr); + return cdata->oncs.write_zeroes; case SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE: if (spdk_nvme_ctrlr_get_flags(ctrlr) & @@ -1390,6 +1397,9 @@ nvme_disk_create(struct spdk_bdev *disk, const char *base_name, /* Enable if the Volatile Write Cache exists */ disk->write_cache = 1; } + if (cdata->oncs.write_zeroes) { + disk->max_write_zeroes = UINT16_MAX + 1; + } disk->blocklen = spdk_nvme_ns_get_extended_sector_size(ns); disk->blockcnt = spdk_nvme_ns_get_num_sectors(ns); disk->optimal_io_boundary = spdk_nvme_ns_get_optimal_io_boundary(ns); @@ -3230,6 +3240,23 @@ bdev_nvme_unmap(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, return rc; } +static int +bdev_nvme_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, + struct nvme_bdev_io *bio, + uint64_t offset_blocks, + uint64_t num_blocks) +{ + if (num_blocks > UINT16_MAX + 1) { + SPDK_ERRLOG("NVMe write zeroes is limited to 16-bit block count\n"); + return -EINVAL; + } + + return spdk_nvme_ns_cmd_write_zeroes(ns, qpair, + offset_blocks, num_blocks, + bdev_nvme_queued_done, bio, + 0); +} + static int bdev_nvme_get_zone_info(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, struct nvme_bdev_io *bio, uint64_t zone_id, uint32_t num_zones, diff --git a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c index da190a7fe..a549b69f7 100644 --- a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c +++ b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c @@ -811,6 +811,15 @@ spdk_nvme_ns_cmd_dataset_management(struct spdk_nvme_ns *ns, struct spdk_nvme_qp return ut_submit_nvme_request(ns, qpair, SPDK_NVME_OPC_DATASET_MANAGEMENT, cb_fn, cb_arg); } +int +spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, + uint64_t lba, uint32_t lba_count, + spdk_nvme_cmd_cb cb_fn, void *cb_arg, + uint32_t io_flags) +{ + return ut_submit_nvme_request(ns, qpair, SPDK_NVME_OPC_WRITE_ZEROES, cb_fn, cb_arg); +} + struct spdk_nvme_poll_group * spdk_nvme_poll_group_create(void *ctx, struct spdk_nvme_accel_fn_table *table) {