From 9522ed36f8474c9314b76b2618e8d2d9de56afee Mon Sep 17 00:00:00 2001 From: Evgeniy Kochetov Date: Wed, 11 Sep 2019 13:42:42 +0000 Subject: [PATCH] bdev: Add resize event This patch adds RESIZE event to block device API. Signed-off-by: Evgeniy Kochetov Signed-off-by: Sasha Kotchubievsky Signed-off-by: Alexey Marchuk Change-Id: Ic9fe359d19544fa0a48eed91216b858097e82995 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468543 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto --- CHANGELOG.md | 3 +++ include/spdk/bdev.h | 5 +++-- lib/bdev/bdev.c | 34 +++++++++++++++++++++++++++++ test/unit/lib/bdev/bdev.c/bdev_ut.c | 29 ++++++++++++++++++++++-- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 563e93d85..e07153b58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,9 @@ asynchronous event such as bdev removal. spdk_bdev_open_ext function takes bdev an argument instead of bdev structure to avoid a race condition that can happen when the bdev is being removed between a call to get its structure based on a name and actually openning it. +New 'resize' event has been added to notify about change of block count property of block device. +Event is delivered only if block device was opened with spdk_bdev_open_ext function. + ### blobstore A new spdk_bdev_create_bs_dev_from_desc function has been added and spdk_bdev_create_bs_dev diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index 6abcc91c5..d48a14a0d 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -1,8 +1,8 @@ /*- * BSD LICENSE * - * Copyright (c) Intel Corporation. - * All rights reserved. + * Copyright (c) Intel Corporation. All rights reserved. + * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -63,6 +63,7 @@ extern "C" { /** Asynchronous event type */ enum spdk_bdev_event_type { SPDK_BDEV_EVENT_REMOVE, + SPDK_BDEV_EVENT_RESIZE }; /** diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 2149313b0..d73068912 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -2669,9 +2669,35 @@ _spdk_bdev_desc_free(struct spdk_bdev_desc *desc) free(desc); } +static void +_resize_notify(void *arg) +{ + struct spdk_bdev_desc *desc = arg; + + pthread_mutex_lock(&desc->mutex); + desc->refs--; + if (!desc->closed) { + pthread_mutex_unlock(&desc->mutex); + desc->callback.event_fn(SPDK_BDEV_EVENT_RESIZE, + desc->bdev, + desc->callback.ctx); + return; + } else if (0 == desc->refs) { + /* This descriptor was closed after this resize_notify message was sent. + * spdk_bdev_close() could not free the descriptor since this message was + * in flight, so we free it now using _spdk_bdev_desc_free(). + */ + pthread_mutex_unlock(&desc->mutex); + _spdk_bdev_desc_free(desc); + return; + } + pthread_mutex_unlock(&desc->mutex); +} + int spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) { + struct spdk_bdev_desc *desc; int ret; pthread_mutex_lock(&bdev->internal.mutex); @@ -2682,6 +2708,14 @@ spdk_bdev_notify_blockcnt_change(struct spdk_bdev *bdev, uint64_t size) ret = -EBUSY; } else { bdev->blockcnt = size; + TAILQ_FOREACH(desc, &bdev->internal.open_descs, link) { + pthread_mutex_lock(&desc->mutex); + if (desc->callback.open_with_ext && !desc->closed) { + desc->refs++; + spdk_thread_send_msg(desc->thread, _resize_notify, desc); + } + pthread_mutex_unlock(&desc->mutex); + } ret = 0; } diff --git a/test/unit/lib/bdev/bdev.c/bdev_ut.c b/test/unit/lib/bdev/bdev.c/bdev_ut.c index aea0a63fb..c7eeced41 100644 --- a/test/unit/lib/bdev/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/bdev.c/bdev_ut.c @@ -431,7 +431,9 @@ bdev_open_cb1(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *even struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; g_event_type1 = type; - spdk_bdev_close(desc); + if (SPDK_BDEV_EVENT_REMOVE == type) { + spdk_bdev_close(desc); + } } static void @@ -440,7 +442,9 @@ bdev_open_cb2(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *even struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; g_event_type2 = type; - spdk_bdev_close(desc); + if (SPDK_BDEV_EVENT_REMOVE == type) { + spdk_bdev_close(desc); + } } static void @@ -635,6 +639,7 @@ num_blocks_test(void) { struct spdk_bdev bdev; struct spdk_bdev_desc *desc = NULL; + struct spdk_bdev_desc *desc_ext = NULL; int rc; memset(&bdev, 0, sizeof(bdev)); @@ -659,10 +664,30 @@ num_blocks_test(void) /* Shrinking block number */ CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); + /* In case bdev opened with ext API */ + rc = spdk_bdev_open_ext("num_blocks", false, bdev_open_cb1, &desc_ext, &desc_ext); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(desc_ext != NULL); + + g_event_type1 = 0xFF; + /* Growing block number */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 90) == 0); + + poll_threads(); + CU_ASSERT_EQUAL(g_event_type1, SPDK_BDEV_EVENT_RESIZE); + + g_event_type1 = 0xFF; + /* Growing block number and closing */ + CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 100) == 0); + spdk_bdev_close(desc); + spdk_bdev_close(desc_ext); spdk_bdev_unregister(&bdev, NULL, NULL); poll_threads(); + + /* Callback is not called for closed device */ + CU_ASSERT_EQUAL(g_event_type1, 0xFF); } static void