diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index af73eba745..36aed293d1 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -45,6 +45,7 @@ #include "spdk/json.h" #include "spdk/queue.h" #include "spdk/histogram_data.h" +#include "spdk/dif.h" #ifdef __cplusplus extern "C" { @@ -425,6 +426,25 @@ uint32_t spdk_bdev_get_md_size(const struct spdk_bdev *bdev); */ bool spdk_bdev_is_md_interleaved(const struct spdk_bdev *bdev); +/** + * Get DIF type of the block device. + * + * \param bdev Block device to query. + * \return DIF type of the block device. + */ +enum spdk_dif_type spdk_bdev_get_dif_type(const struct spdk_bdev *bdev); + +/** + * Check whether DIF is set in the first 8 bytes or the last 8 bytes of metadata. + * + * \param bdev Block device to query. + * \return true if DIF is set in the first 8 bytes of metadata, or false + * if DIF is set in the last 8 bytes of metadata. + * + * Note that this function is valid only if DIF type is not SPDK_DIF_DISABLE. + */ +bool spdk_bdev_is_dif_head_of_md(const struct spdk_bdev *bdev); + /** * Get the most recently measured queue depth from a bdev. * diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index b68c89b177..3ca567b2cb 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -303,6 +303,23 @@ struct spdk_bdev { */ bool md_interleave; + /** + * DIF type for this bdev. + * + * Note that this field is valid only if there is metadata. + */ + enum spdk_dif_type dif_type; + + /* + * DIF location. + * + * Set to true if DIF is set in the first 8 bytes of metadata or false + * if DIF is set in the last 8 bytes of metadata. + * + * Note that this field is valid only if DIF is enabled. + */ + bool dif_is_head_of_md; + /** * Pointer to the bdev module that registered this bdev. */ diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index fa92bf1020..bf38f6272d 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -2331,6 +2331,25 @@ spdk_bdev_is_md_interleaved(const struct spdk_bdev *bdev) return (bdev->md_len != 0) && bdev->md_interleave; } +enum spdk_dif_type spdk_bdev_get_dif_type(const struct spdk_bdev *bdev) +{ + if (bdev->md_len != 0) { + return bdev->dif_type; + } else { + return SPDK_DIF_DISABLE; + } +} + +bool +spdk_bdev_is_dif_head_of_md(const struct spdk_bdev *bdev) +{ + if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) { + return bdev->dif_is_head_of_md; + } else { + return false; + } +} + uint64_t spdk_bdev_get_qd(const struct spdk_bdev *bdev) { diff --git a/lib/bdev/rpc/bdev_rpc.c b/lib/bdev/rpc/bdev_rpc.c index 6f88c551af..6cbf5cfeb7 100644 --- a/lib/bdev/rpc/bdev_rpc.c +++ b/lib/bdev/rpc/bdev_rpc.c @@ -248,6 +248,10 @@ spdk_rpc_dump_bdev_info(struct spdk_json_write_ctx *w, if (spdk_bdev_get_md_size(bdev) != 0) { spdk_json_write_named_uint32(w, "md_size", spdk_bdev_get_md_size(bdev)); spdk_json_write_named_bool(w, "md_interleave", spdk_bdev_is_md_interleaved(bdev)); + spdk_json_write_named_uint32(w, "dif_type", spdk_bdev_get_dif_type(bdev)); + if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) { + spdk_json_write_named_bool(w, "dif_is_head_of_md", spdk_bdev_is_dif_head_of_md(bdev)); + } } spdk_json_write_named_object_begin(w, "assigned_rate_limits");