diff --git a/include/spdk/blob.h b/include/spdk/blob.h index d496560bb..629d58320 100644 --- a/include/spdk/blob.h +++ b/include/spdk/blob.h @@ -197,6 +197,15 @@ struct spdk_bs_dev { bool (*is_zeroes)(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count); + /* Translate blob lba to lba on the underlying bdev. + * This operation recurses down the whole chain of bs_dev's. + * Returns true and initializes value of base_lba on success. + * Returns false on failure. + * The function may fail when blob lba is not backed by the bdev lba. + * For example, when we eventually hit zeroes device in the chain. + */ + bool (*translate_lba)(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba); + uint64_t blockcnt; uint32_t blocklen; /* In bytes */ }; diff --git a/lib/blob/Makefile b/lib/blob/Makefile index f87bdd838..e12216aba 100644 --- a/lib/blob/Makefile +++ b/lib/blob/Makefile @@ -6,7 +6,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 8 +SO_VER := 9 SO_MINOR := 0 C_SRCS = blobstore.c request.c zeroes.c blob_bs_dev.c diff --git a/lib/blob/blob_bs_dev.c b/lib/blob/blob_bs_dev.c index a189f54c3..eae2ae87f 100644 --- a/lib/blob/blob_bs_dev.c +++ b/lib/blob/blob_bs_dev.c @@ -136,6 +136,24 @@ blob_bs_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) bs_io_unit_to_back_dev_lba(blob, lba_count)); } +static bool +blob_bs_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba) +{ + struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev; + struct spdk_blob *blob = b->blob; + + assert(base_lba != NULL); + if (bs_io_unit_is_allocated(blob, lba)) { + *base_lba = bs_blob_io_unit_to_lba(blob, lba); + return true; + } + + assert(blob->back_bs_dev != NULL); + return blob->back_bs_dev->translate_lba(blob->back_bs_dev, + bs_io_unit_to_back_dev_lba(blob, lba), + base_lba); +} + struct spdk_bs_dev * bs_create_blob_bs_dev(struct spdk_blob *blob) { @@ -161,6 +179,7 @@ bs_create_blob_bs_dev(struct spdk_blob *blob) b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes; b->bs_dev.unmap = blob_bs_dev_unmap; b->bs_dev.is_zeroes = blob_bs_is_zeroes; + b->bs_dev.translate_lba = blob_bs_translate_lba; b->blob = blob; return &b->bs_dev; diff --git a/lib/blob/zeroes.c b/lib/blob/zeroes.c index 5fdf0b649..ad7305675 100644 --- a/lib/blob/zeroes.c +++ b/lib/blob/zeroes.c @@ -124,6 +124,12 @@ zeroes_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) return true; } +static bool +zeroes_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba) +{ + return false; +} + static struct spdk_bs_dev g_zeroes_bs_dev = { .blockcnt = UINT64_MAX, .blocklen = 512, @@ -139,6 +145,7 @@ static struct spdk_bs_dev g_zeroes_bs_dev = { .write_zeroes = zeroes_write_zeroes, .unmap = zeroes_unmap, .is_zeroes = zeroes_is_zeroes, + .translate_lba = zeroes_translate_lba, }; struct spdk_bs_dev * diff --git a/lib/blobfs/Makefile b/lib/blobfs/Makefile index e8d7e4a9e..fe21506ba 100644 --- a/lib/blobfs/Makefile +++ b/lib/blobfs/Makefile @@ -6,7 +6,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 7 +SO_VER := 8 SO_MINOR := 0 C_SRCS = blobfs.c tree.c diff --git a/lib/lvol/Makefile b/lib/lvol/Makefile index a3f9d2674..d92750237 100644 --- a/lib/lvol/Makefile +++ b/lib/lvol/Makefile @@ -6,7 +6,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 7 +SO_VER := 8 SO_MINOR := 0 C_SRCS = lvol.c diff --git a/module/blob/bdev/Makefile b/module/blob/bdev/Makefile index f8c9d598a..bffa660d0 100644 --- a/module/blob/bdev/Makefile +++ b/module/blob/bdev/Makefile @@ -6,7 +6,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -SO_VER := 8 +SO_VER := 9 SO_MINOR := 0 C_SRCS = blob_bdev.c diff --git a/module/blob/bdev/blob_bdev.c b/module/blob/bdev/blob_bdev.c index c12169368..a4e52b92b 100644 --- a/module/blob/bdev/blob_bdev.c +++ b/module/blob/bdev/blob_bdev.c @@ -360,6 +360,13 @@ bdev_blob_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count) return false; } +static bool +bdev_blob_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba) +{ + *base_lba = lba; + return true; +} + static void blob_bdev_init(struct blob_bdev *b, struct spdk_bdev_desc *desc) { @@ -385,6 +392,7 @@ blob_bdev_init(struct blob_bdev *b, struct spdk_bdev_desc *desc) b->bs_dev.unmap = bdev_blob_unmap; b->bs_dev.get_base_bdev = bdev_blob_get_base_bdev; b->bs_dev.is_zeroes = bdev_blob_is_zeroes; + b->bs_dev.translate_lba = bdev_blob_translate_lba; } int