diff --git a/include/spdk/lvol.h b/include/spdk/lvol.h index a1f1d66ad..488941a69 100644 --- a/include/spdk/lvol.h +++ b/include/spdk/lvol.h @@ -373,6 +373,14 @@ void spdk_lvol_inflate(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void */ void spdk_lvol_decouple_parent(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg); +/** + * Determine if an lvol is degraded. A degraded lvol cannot perform IO. + * + * \param lvol Handle to lvol + * \return true if the lvol has no open blob or the lvol's blob is degraded, else false. + */ +bool spdk_lvol_is_degraded(const struct spdk_lvol *lvol); + #ifdef __cplusplus } #endif diff --git a/lib/lvol/lvol.c b/lib/lvol/lvol.c index fd54a477d..0b552d16a 100644 --- a/lib/lvol/lvol.c +++ b/lib/lvol/lvol.c @@ -2197,3 +2197,14 @@ spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name) pthread_mutex_unlock(&g_lvol_stores_mutex); return NULL; } + +bool +spdk_lvol_is_degraded(const struct spdk_lvol *lvol) +{ + struct spdk_blob *blob = lvol->blob; + + if (blob == NULL) { + return true; + } + return spdk_blob_is_degraded(blob); +} diff --git a/lib/lvol/spdk_lvol.map b/lib/lvol/spdk_lvol.map index ab169af12..bc93c968c 100644 --- a/lib/lvol/spdk_lvol.map +++ b/lib/lvol/spdk_lvol.map @@ -25,6 +25,7 @@ spdk_lvol_iter_immediate_clones; spdk_lvol_get_by_uuid; spdk_lvol_get_by_names; + spdk_lvol_is_degraded; # internal functions spdk_lvol_resize; diff --git a/module/bdev/lvol/vbdev_lvol.c b/module/bdev/lvol/vbdev_lvol.c index cb439e634..b3614c953 100644 --- a/module/bdev/lvol/vbdev_lvol.c +++ b/module/bdev/lvol/vbdev_lvol.c @@ -653,7 +653,7 @@ _vbdev_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *c ctx->cb_fn = cb_fn; ctx->cb_arg = cb_arg; - if (spdk_blob_is_degraded(lvol->blob)) { + if (spdk_lvol_is_degraded(lvol)) { spdk_lvol_close(lvol, _vbdev_lvol_destroy_cb, ctx); return; } @@ -1111,7 +1111,7 @@ _create_lvol_disk(struct spdk_lvol *lvol, bool destroy) unsigned char *alias; int rc; - if (spdk_blob_is_degraded(lvol->blob)) { + if (spdk_lvol_is_degraded(lvol)) { SPDK_NOTICELOG("lvol %s: blob is degraded: deferring bdev creation\n", lvol->unique_id); return 0; diff --git a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c index 5bfeb4623..6210696ff 100644 --- a/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c +++ b/test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut.c @@ -49,8 +49,8 @@ DEFINE_STUB(spdk_lvol_iter_immediate_clones, int, DEFINE_STUB(spdk_lvs_esnap_missing_add, int, (struct spdk_lvol_store *lvs, struct spdk_lvol *lvol, const void *esnap_id, uint32_t id_len), -ENOTSUP); -DEFINE_STUB(spdk_blob_is_degraded, bool, (const struct spdk_blob *blob), false); DEFINE_STUB(spdk_blob_get_esnap_bs_dev, struct spdk_bs_dev *, (const struct spdk_blob *blob), NULL); +DEFINE_STUB(spdk_lvol_is_degraded, bool, (const struct spdk_lvol *lvol), false); struct spdk_blob { uint64_t id; @@ -1836,7 +1836,7 @@ ut_esnap_dev_create(void) /* Bdev not found */ g_base_bdev = NULL; - MOCK_SET(spdk_blob_is_degraded, true); + MOCK_SET(spdk_lvol_is_degraded, true); rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev); CU_ASSERT(rc == 0); SPDK_CU_ASSERT_FATAL(bs_dev != NULL); @@ -1847,7 +1847,7 @@ ut_esnap_dev_create(void) /* TODO: This suggests we need a way to wait for a claim to be available. */ g_base_bdev = &bdev; lvol_already_opened = true; - MOCK_SET(spdk_blob_is_degraded, true); + MOCK_SET(spdk_lvol_is_degraded, true); rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev); CU_ASSERT(rc == 0); SPDK_CU_ASSERT_FATAL(bs_dev != NULL); @@ -1856,7 +1856,7 @@ ut_esnap_dev_create(void) /* Happy path */ lvol_already_opened = false; - MOCK_SET(spdk_blob_is_degraded, false); + MOCK_SET(spdk_lvol_is_degraded, false); rc = vbdev_lvol_esnap_dev_create(&lvs, &lvol, &blob, uuid_str, sizeof(uuid_str), &bs_dev); CU_ASSERT(rc == 0); SPDK_CU_ASSERT_FATAL(bs_dev != NULL); @@ -1866,7 +1866,7 @@ ut_esnap_dev_create(void) g_base_bdev = NULL; lvol_already_opened = false; free(unterminated); - MOCK_CLEAR(spdk_blob_is_degraded); + MOCK_CLEAR(spdk_lvol_is_degraded); } static void diff --git a/test/unit/lib/lvol/lvol.c/lvol_ut.c b/test/unit/lib/lvol/lvol.c/lvol_ut.c index 1e1f77d9c..4663bdccd 100644 --- a/test/unit/lib/lvol/lvol.c/lvol_ut.c +++ b/test/unit/lib/lvol/lvol.c/lvol_ut.c @@ -35,6 +35,7 @@ DEFINE_STUB(spdk_bdev_create_bs_dev_ro, int, (const char *bdev_name, spdk_bdev_event_cb_t event_cb, void *event_ctx, struct spdk_bs_dev **bs_dev), -ENOTSUP); DEFINE_STUB(spdk_blob_is_esnap_clone, bool, (const struct spdk_blob *blob), false); +DEFINE_STUB(spdk_blob_is_degraded, bool, (const struct spdk_blob *blob), false); const char *uuid = "828d9766-ae50-11e7-bd8d-001e67edf350";