From b87080efa2b049d968e5dde0f6cee58bdc826721 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Mon, 16 Dec 2019 09:10:16 -0700 Subject: [PATCH] bdev: add lba_range and overlapping checks This will be used by upcoming patches for implementing LBA range locks. Signed-off-by: Jim Harris Change-Id: Ifa4ad8dcc0d09ccf20d35f010fcae19dcc17abc9 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478224 Tested-by: SPDK CI Jenkins Community-CI: Broadcom SPDK FC-NVMe CI Reviewed-by: Ben Walker Reviewed-by: Paul Luse Reviewed-by: Shuhei Matsumoto Reviewed-by: Maciej Szwed --- lib/bdev/bdev.c | 27 ++++++++++++++++ test/unit/lib/bdev/bdev.c/bdev_ut.c | 48 ++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 251972d5f..6061757a3 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -124,6 +124,12 @@ static struct spdk_bdev_mgr g_bdev_mgr = { .mutex = PTHREAD_MUTEX_INITIALIZER, }; +struct lba_range { + uint64_t offset; + uint64_t length; + struct spdk_bdev_channel *owner_ch; + TAILQ_ENTRY(lba_range) tailq; +}; static struct spdk_bdev_opts g_bdev_opts = { .bdev_io_pool_size = SPDK_BDEV_IO_POOL_SIZE, @@ -1894,6 +1900,27 @@ _bdev_io_submit(void *ctx) bdev_io->internal.in_submit_request = false; } +bool +bdev_lba_range_overlapped(struct lba_range *range1, struct lba_range *range2); + +bool +bdev_lba_range_overlapped(struct lba_range *range1, struct lba_range *range2) +{ + if (range1->length == 0 || range2->length == 0) { + return false; + } + + if (range1->offset + range1->length <= range2->offset) { + return false; + } + + if (range2->offset + range2->length <= range1->offset) { + return false; + } + + return true; +} + void bdev_io_submit(struct spdk_bdev_io *bdev_io) { diff --git a/test/unit/lib/bdev/bdev.c/bdev_ut.c b/test/unit/lib/bdev/bdev.c/bdev_ut.c index 625dc3c57..423a179cd 100644 --- a/test/unit/lib/bdev/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/bdev.c/bdev_ut.c @@ -2541,6 +2541,51 @@ bdev_set_io_timeout(void) poll_threads(); } +static void +lba_range_overlap(void) +{ + struct lba_range r1, r2; + + r1.offset = 100; + r1.length = 50; + + r2.offset = 0; + r2.length = 1; + CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 0; + r2.length = 100; + CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 0; + r2.length = 110; + CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 100; + r2.length = 10; + CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 110; + r2.length = 20; + CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 140; + r2.length = 150; + CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 130; + r2.length = 200; + CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 150; + r2.length = 100; + CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); + + r2.offset = 110; + r2.length = 0; + CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); +} + int main(int argc, char **argv) { @@ -2576,7 +2621,8 @@ main(int argc, char **argv) CU_add_test(suite, "bdev_open_while_hotremove", bdev_open_while_hotremove) == NULL || CU_add_test(suite, "bdev_close_while_hotremove", bdev_close_while_hotremove) == NULL || CU_add_test(suite, "bdev_open_ext", bdev_open_ext) == NULL || - CU_add_test(suite, "bdev_set_io_timeout", bdev_set_io_timeout) == NULL + CU_add_test(suite, "bdev_set_io_timeout", bdev_set_io_timeout) == NULL || + CU_add_test(suite, "lba_range_overlap", lba_range_overlap) == NULL ) { CU_cleanup_registry(); return CU_get_error();