Commit b86c4b65 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki Committed by Daniel Verkamp
Browse files

blob: persist super_blob id on blobstore immediately



Before this patch super_blob id for blobstore was persisted
only during spdk_bs_unload. If power fail occurred after creating and
syncing blob, super_blob id was lost within blobstore.

Lvol store metadata would be lost, if proper shutdown
didn't occur in first SPDK instance run since creation of lvs.

This fix changes setting super blob to be instantly persisted
on disk in super block. Without affecting clean bit in super block.

Change-Id: I578f1fc8717e2d7968ad506fa4dead7507a5e0b4
Signed-off-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.gerrithub.io/398804


Reviewed-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent 2a274cc9
Loading
Loading
Loading
Loading
+79 −1
Original line number Diff line number Diff line
@@ -3144,14 +3144,92 @@ spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_a

/* END spdk_bs_unload */

/* START spdk_bs_set_super */

struct spdk_bs_set_super_ctx {
	struct spdk_blob_store		*bs;
	struct spdk_bs_super_block	*super;
};

static void
_spdk_bs_set_super_write_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
	struct spdk_bs_set_super_ctx	*ctx = cb_arg;

	if (bserrno != 0) {
		SPDK_ERRLOG("Unable to write to super block of blobstore\n");
	}

	spdk_dma_free(ctx->super);

	spdk_bs_sequence_finish(seq, bserrno);

	free(ctx);
}

static void
_spdk_bs_set_super_read_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
{
	struct spdk_bs_set_super_ctx	*ctx = cb_arg;

	if (bserrno != 0) {
		SPDK_ERRLOG("Unable to read super block of blobstore\n");
		spdk_dma_free(ctx->super);
		spdk_bs_sequence_finish(seq, bserrno);
		free(ctx);
		return;
	}

	_spdk_bs_write_super(seq, ctx->bs, ctx->super, _spdk_bs_set_super_write_cpl, ctx);
}

void
spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid,
		  spdk_bs_op_complete cb_fn, void *cb_arg)
{
	struct spdk_bs_cpl		cpl;
	spdk_bs_sequence_t		*seq;
	struct spdk_bs_set_super_ctx	*ctx;

	SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Setting super blob id on blobstore\n");

	ctx = calloc(1, sizeof(*ctx));
	if (!ctx) {
		cb_fn(cb_arg, -ENOMEM);
		return;
	}

	ctx->bs = bs;

	ctx->super = spdk_dma_zmalloc(sizeof(*ctx->super), 0x1000, NULL);
	if (!ctx->super) {
		free(ctx);
		cb_fn(cb_arg, -ENOMEM);
		return;
	}

	cpl.type = SPDK_BS_CPL_TYPE_BS_BASIC;
	cpl.u.bs_basic.cb_fn = cb_fn;
	cpl.u.bs_basic.cb_arg = cb_arg;

	seq = spdk_bs_sequence_start(bs->md_channel, &cpl);
	if (!seq) {
		spdk_dma_free(ctx->super);
		free(ctx);
		cb_fn(cb_arg, -ENOMEM);
		return;
	}

	bs->super_blob = blobid;
	cb_fn(cb_arg, 0);

	/* Read super block */
	spdk_bs_sequence_read_dev(seq, ctx->super, _spdk_bs_page_to_lba(bs, 0),
				  _spdk_bs_byte_to_lba(bs, sizeof(*ctx->super)),
				  _spdk_bs_set_super_read_cpl, ctx);
}

/* END spdk_bs_set_super */

void
spdk_bs_get_super(struct spdk_blob_store *bs,
		  spdk_blob_op_with_id_complete cb_fn, void *cb_arg)
+11 −2
Original line number Diff line number Diff line
@@ -2063,13 +2063,13 @@ super_block_crc(void)
}

/* For blob dirty shutdown test case we do the following sub-test cases:
 * 1 Initialize new blob store and create 1 blob with some xattrs, then we
 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we
 *   dirty shutdown and reload the blob store and verify the xattrs.
 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown,
 *   reload the blob store and verify the clusters number.
 * 3 Create the second blob and then dirty shutdown, reload the blob store
 *   and verify the second blob.
 * 4 Delete the second blob and then dirty shutdown, reload teh blob store
 * 4 Delete the second blob and then dirty shutdown, reload the blob store
 *   and verify the second blob is invalid.
 * 5 Create the second blob again and also create the third blob, modify the
 *   md of second blob which makes the md invalid, and then dirty shutdown,
@@ -2122,6 +2122,10 @@ blob_dirty_shutdown(void)
	rc = spdk_blob_resize(blob, 10);
	CU_ASSERT(rc == 0);

	/* Set the blob as the super blob */
	spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	free_clusters = spdk_bs_free_cluster_count(g_bs);

	spdk_blob_close(blob, blob_op_complete, NULL);
@@ -2138,6 +2142,11 @@ blob_dirty_shutdown(void)
	spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	/* Get the super blob */
	spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(blobid1 == g_blobid);

	spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(g_blob != NULL);