diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index debd695a3..c30d17119 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -271,6 +271,9 @@ struct spdk_bdev { /** Number of blocks required for write */ uint32_t write_unit_size; + /** Atomic compare & write unit */ + uint16_t acwu; + /** * Specifies an alignment requirement for data buffers associated with an spdk_bdev_io. * 0 = no alignment requirement diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 38f526554..b4cd6a683 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -3657,6 +3657,10 @@ spdk_bdev_comparev_and_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io return -EINVAL; } + if (num_blocks > bdev->acwu) { + return -EINVAL; + } + bdev_io = bdev_channel_get_io(channel); if (!bdev_io) { return -ENOMEM; @@ -4750,6 +4754,11 @@ bdev_init(struct spdk_bdev *bdev) bdev->write_unit_size = 1; } + /* Set ACWU value to 1 if bdev module did not set it (does not support it natively) */ + if (bdev->acwu == 0) { + bdev->acwu = 1; + } + TAILQ_INIT(&bdev->internal.open_descs); TAILQ_INIT(&bdev->internal.locked_ranges); TAILQ_INIT(&bdev->internal.pending_locked_ranges); diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 32b2fd7bb..482744ea4 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -899,9 +899,10 @@ nvme_ctrlr_populate_standard_namespace(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, bdev->disk.uuid = *uuid; } + nsdata = spdk_nvme_ns_get_data(ns); + bdev->disk.md_len = spdk_nvme_ns_get_md_size(ns); if (bdev->disk.md_len != 0) { - nsdata = spdk_nvme_ns_get_data(ns); bdev->disk.md_interleave = nsdata->flbas.extended; bdev->disk.dif_type = (enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns); if (bdev->disk.dif_type != SPDK_DIF_DISABLE) { @@ -910,6 +911,14 @@ nvme_ctrlr_populate_standard_namespace(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, } } + if (!bdev_nvme_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_COMPARE_AND_WRITE)) { + bdev->disk.acwu = 0; + } else if (nsdata->nsfeat.ns_atomic_write_unit) { + bdev->disk.acwu = nsdata->nacwu; + } else { + bdev->disk.acwu = cdata->acwu; + } + bdev->disk.ctxt = bdev; bdev->disk.fn_table = &nvmelib_fn_table; bdev->disk.module = &nvme_if;