Commit 09bf2b20 authored by Mike Gerdts's avatar Mike Gerdts Committed by Jim Harris
Browse files

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: default avatarMike Gerdts <mgerdts@nvidia.com>
Change-Id: Ib02227f5735b00038ed30923813e1d5b57deb1ab
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17516


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 1db33a8f
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
+13 −0
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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: *;
};
+71 −0
Original line number Diff line number Diff line
@@ -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);