blob: add spdk_blob_is_degraded()

In preparation for supporting degraded lvols, spdk_blob_is_degraded() is
added. To support this, bs_dev gains an optional is_degraded() callback.
spdk_blob_is_degraded() returns false so long as no bs_dev that the blob
depends on is degraded. Depended upon bs_devs include the blobstore's
device and the blob's back_bs_dev.

Signed-off-by: Mike Gerdts <mgerdts@nvidia.com>
Change-Id: Ib02227f5735b00038ed30923813e1d5b57deb1ab
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17516
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Mike Gerdts 2023-04-06 08:55:38 -05:00 committed by David Ko
parent 510b723ba9
commit 42e50f66d0
4 changed files with 96 additions and 0 deletions

View File

@ -244,6 +244,8 @@ struct spdk_bs_dev {
uint64_t dst_lba, uint64_t src_lba, uint64_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
bool (*is_degraded)(struct spdk_bs_dev *dev);
uint64_t blockcnt;
uint32_t blocklen; /* In bytes */
};
@ -1143,6 +1145,15 @@ void spdk_blob_set_esnap_bs_dev(struct spdk_blob *blob, struct spdk_bs_dev *back
*/
struct spdk_bs_dev *spdk_blob_get_esnap_bs_dev(const struct spdk_blob *blob);
/**
* Determine if the blob is degraded. A degraded blob cannot perform IO.
*
* \param blob A blob
*
* \return true if the blob or any snapshots upon which it depends are degraded, else false.
*/
bool spdk_blob_is_degraded(const struct spdk_blob *blob);
#ifdef __cplusplus
}
#endif

View File

@ -9115,5 +9115,18 @@ spdk_blob_get_esnap_bs_dev(const struct spdk_blob *blob)
return blob->back_bs_dev;
}
bool
spdk_blob_is_degraded(const struct spdk_blob *blob)
{
if (blob->bs->dev->is_degraded != NULL && blob->bs->dev->is_degraded(blob->bs->dev)) {
return true;
}
if (blob->back_bs_dev == NULL || blob->back_bs_dev->is_degraded == NULL) {
return false;
}
return blob->back_bs_dev->is_degraded(blob->back_bs_dev);
}
SPDK_LOG_REGISTER_COMPONENT(blob)
SPDK_LOG_REGISTER_COMPONENT(blob_esnap)

View File

@ -68,6 +68,7 @@
spdk_bs_set_bstype;
spdk_blob_get_esnap_bs_dev;
spdk_blob_set_esnap_bs_dev;
spdk_blob_is_degraded;
local: *;
};

View File

@ -8506,6 +8506,76 @@ blob_esnap_hotplug(void)
CU_ASSERT(g_bserrno == 0);
}
static bool g_blob_is_degraded;
static int g_blob_is_degraded_called;
static bool
_blob_is_degraded(struct spdk_bs_dev *dev)
{
g_blob_is_degraded_called++;
return g_blob_is_degraded;
}
static void
blob_is_degraded(void)
{
struct spdk_bs_dev bs_is_degraded_null = { 0 };
struct spdk_bs_dev bs_is_degraded = { .is_degraded = _blob_is_degraded };
/* No back_bs_dev, no bs->dev->is_degraded */
g_blob_is_degraded_called = 0;
CU_ASSERT(!spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 0);
/* No back_bs_dev, blobstore device degraded */
g_bs->dev->is_degraded = _blob_is_degraded;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = true;
CU_ASSERT(spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 1);
/* No back_bs_dev, blobstore device not degraded */
g_bs->dev->is_degraded = _blob_is_degraded;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = false;
CU_ASSERT(!spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 1);
/* back_bs_dev does not define is_degraded, no bs->dev->is_degraded */
g_bs->dev->is_degraded = NULL;
g_blob->back_bs_dev = &bs_is_degraded_null;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = false;
CU_ASSERT(!spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 0);
/* back_bs_dev is not degraded, no bs->dev->is_degraded */
g_bs->dev->is_degraded = NULL;
g_blob->back_bs_dev = &bs_is_degraded;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = false;
CU_ASSERT(!spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 1);
/* back_bs_dev is degraded, no bs->dev->is_degraded */
g_bs->dev->is_degraded = NULL;
g_blob->back_bs_dev = &bs_is_degraded;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = true;
CU_ASSERT(spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 1);
/* back_bs_dev is not degraded, blobstore device is not degraded */
g_bs->dev->is_degraded = _blob_is_degraded;
g_blob->back_bs_dev = &bs_is_degraded;
g_blob_is_degraded_called = 0;
g_blob_is_degraded = false;
CU_ASSERT(!spdk_blob_is_degraded(g_blob));
CU_ASSERT(g_blob_is_degraded_called == 2);
g_blob->back_bs_dev = NULL;
}
static void
suite_bs_setup(void)
{
@ -8717,6 +8787,7 @@ main(int argc, char **argv)
CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_decouple);
CU_ADD_TEST(suite_esnap_bs, blob_esnap_clone_reload);
CU_ADD_TEST(suite_esnap_bs, blob_esnap_hotplug);
CU_ADD_TEST(suite_blob, blob_is_degraded);
allocate_threads(2);
set_thread(0);