Commit 4d5ee263 authored by Mike Gerdts's avatar Mike Gerdts Committed by Konrad Sztyber
Browse files

blob: pass blob context to esnap_bs_dev_create



When consumers open a blob with spdk_bs_open_blob_ext(), they can set
esnap_ctx in struct spdk_blob_open_opts to have that context passed
to bs->external_bs_dev_create().

Change-Id: I0c1a9cec0e5aed5ef2a7143103e822cbe400aabb
Signed-off-by: default avatarMike Gerdts <mgerdts@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14971


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent a75bdf36
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@ typedef void (*spdk_blob_op_with_bs_dev)(void *cb_arg, struct spdk_bs_dev *bs_de
 *
 * \param bs_ctx Context provided by the blobstore consumer via esnap_ctx member of struct
 * spdk_bs_opts.
 * \param blob_ctx Context provided to spdk_bs_open_ext() via esnap_ctx member of struct
 * spdk_bs_open_opts.
 * \param blob The blob that needs its external snapshot device.
 * \param esnap_id A copy of the esnap_id passed via blob_opts when creating the esnap clone.
 * \param id_size The size in bytes of the data referenced by esnap_id.
@@ -141,7 +143,7 @@ typedef void (*spdk_blob_op_with_bs_dev)(void *cb_arg, struct spdk_bs_dev *bs_de
 *
 * \return 0 on success, else a negative errno.
 */
typedef int (*spdk_bs_esnap_dev_create)(void *bs_ctx, struct spdk_blob *blob,
typedef int (*spdk_bs_esnap_dev_create)(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
					const void *esnap_id, uint32_t id_size,
					struct spdk_bs_dev **bs_dev);

@@ -753,8 +755,14 @@ struct spdk_blob_open_opts {
	 * New added fields should be put at the end of the struct.
	 */
	size_t opts_size;

	/**
	 * Blob context to be passed to any call of bs->external_bs_dev_create() that is triggered
	 * by this open call.
	 */
	void *esnap_ctx;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_blob_open_opts) == 16, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_blob_open_opts) == 24, "Incorrect size");

/**
 * Initialize a spdk_blob_open_opts structure to the default blob option values.
+10 −7
Original line number Diff line number Diff line
@@ -1340,7 +1340,7 @@ blob_load_snapshot_cpl(void *cb_arg, struct spdk_blob *snapshot, int bserrno)
static void blob_update_clear_method(struct spdk_blob *blob);

static int
blob_load_esnap(struct spdk_blob *blob)
blob_load_esnap(struct spdk_blob *blob, void *blob_ctx)
{
	struct spdk_blob_store *bs = blob->bs;
	struct spdk_bs_dev *bs_dev = NULL;
@@ -1364,7 +1364,8 @@ blob_load_esnap(struct spdk_blob *blob)

	SPDK_INFOLOG(blob, "Creating external snapshot device\n");

	rc = bs->esnap_bs_dev_create(bs->esnap_ctx, blob, esnap_id, (uint32_t)id_len, &bs_dev);
	rc = bs->esnap_bs_dev_create(bs->esnap_ctx, blob_ctx, blob, esnap_id, (uint32_t)id_len,
				     &bs_dev);
	if (rc != 0) {
		SPDK_DEBUGLOG(blob_esnap, "blob 0x%" PRIx64 ": failed to load back_bs_dev "
			      "with error %d\n", blob->id, rc);
@@ -1388,7 +1389,7 @@ blob_load_esnap(struct spdk_blob *blob)
}

static void
blob_load_backing_dev(void *cb_arg)
blob_load_backing_dev(spdk_bs_sequence_t *seq, void *cb_arg)
{
	struct spdk_blob_load_ctx	*ctx = cb_arg;
	struct spdk_blob		*blob = ctx->blob;
@@ -1397,7 +1398,7 @@ blob_load_backing_dev(void *cb_arg)
	int				rc;

	if (blob_is_esnap_clone(blob)) {
		rc = blob_load_esnap(blob);
		rc = blob_load_esnap(blob, seq->cpl.u.blob_handle.esnap_ctx);
		assert((rc == 0) ^ (blob->back_bs_dev == NULL));
		blob_load_final(ctx, rc);
		return;
@@ -1507,7 +1508,7 @@ blob_load_cpl_extents_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
		}
	}

	blob_load_backing_dev(ctx);
	blob_load_backing_dev(seq, ctx);
}

static void
@@ -1595,7 +1596,7 @@ blob_load_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
	if (blob->extent_table_found) {
		blob_load_cpl_extents_cpl(seq, ctx, 0);
	} else {
		blob_load_backing_dev(ctx);
		blob_load_backing_dev(seq, ctx);
	}
}

@@ -7418,12 +7419,13 @@ blob_open_opts_copy(const struct spdk_blob_open_opts *src, struct spdk_blob_open
        } \

	SET_FIELD(clear_method);
	SET_FIELD(esnap_ctx);

	dst->opts_size = src->opts_size;

	/* You should not remove this statement, but need to update the assert statement
	 * if you add a new field, and also add a corresponding SET_FIELD statement */
	SPDK_STATIC_ASSERT(sizeof(struct spdk_blob_open_opts) == 16, "Incorrect size");
	SPDK_STATIC_ASSERT(sizeof(struct spdk_blob_open_opts) == 24, "Incorrect size");

#undef FIELD_OK
#undef SET_FIELD
@@ -7476,6 +7478,7 @@ bs_open_blob(struct spdk_blob_store *bs,
	cpl.u.blob_handle.cb_fn = cb_fn;
	cpl.u.blob_handle.cb_arg = cb_arg;
	cpl.u.blob_handle.blob = blob;
	cpl.u.blob_handle.esnap_ctx = opts_local.esnap_ctx;

	seq = bs_sequence_start(bs->md_channel, &cpl);
	if (!seq) {
+2 −1
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (C) 2017 Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *   Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 */

#ifndef SPDK_BS_REQUEST_H
@@ -65,6 +65,7 @@ struct spdk_bs_cpl {
			spdk_blob_op_with_handle_complete       cb_fn;
			void                                    *cb_arg;
			struct spdk_blob                        *blob;
			void					*esnap_ctx;
		} blob_handle;

		struct {
+15 −1
Original line number Diff line number Diff line
@@ -7415,13 +7415,14 @@ blob_esnap_create(void)
	struct spdk_bs_opts	bs_opts;
	struct ut_esnap_opts	esnap_opts;
	struct spdk_blob_opts	opts;
	struct spdk_blob_open_opts open_opts;
	struct spdk_blob	*blob;
	uint32_t		cluster_sz, block_sz;
	const uint32_t		esnap_num_clusters = 4;
	uint64_t		esnap_num_blocks;
	uint32_t		sz;
	spdk_blob_id		blobid;
	uint32_t		bs_ctx_count;
	uint32_t		bs_ctx_count, blob_ctx_count;

	cluster_sz = spdk_bs_get_cluster_size(bs);
	block_sz = spdk_bs_get_io_unit_size(bs);
@@ -7522,6 +7523,19 @@ blob_esnap_create(void)
	poll_threads();
	CU_ASSERT(g_bserrno == 0);
	g_blob = NULL;
	/* If open_opts.esnap_ctx is set it is passed to the esnap create callback */
	blob_ctx_count = 0;
	spdk_blob_open_opts_init(&open_opts, sizeof(open_opts));
	open_opts.esnap_ctx = &blob_ctx_count;
	spdk_bs_open_blob_ext(bs, blobid, &open_opts, blob_op_with_handle_complete, NULL);
	poll_threads();
	blob = g_blob;
	CU_ASSERT(bs_ctx_count == 3);
	CU_ASSERT(blob_ctx_count == 1);
	spdk_blob_close(blob, blob_op_complete, NULL);
	poll_threads();
	CU_ASSERT(g_bserrno == 0);
	g_blob = NULL;
}

static void
+18 −5
Original line number Diff line number Diff line
@@ -92,12 +92,14 @@ ut_esnap_dev_alloc(const struct ut_esnap_opts *opts)
}

static int
ut_esnap_create(void *bs_ctx, struct spdk_blob *blob, const void *id, uint32_t id_len,
		struct spdk_bs_dev **bs_devp)
ut_esnap_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
		const void *id, uint32_t id_len, struct spdk_bs_dev **bs_devp)
{
	struct spdk_bs_dev	*bs_dev = NULL;

	/* With any blobstore that will use bs_ctx, wrap this function and pass NULL as bs_ctx. */
	/* With any blobstore that will use bs_ctx or blob_ctx, wrap this function and pass NULL as
	 * bs_ctx and blob_ctx. */
	CU_ASSERT(bs_ctx == NULL);
	CU_ASSERT(bs_ctx == NULL);

	SPDK_CU_ASSERT_FATAL(id != NULL);
@@ -111,13 +113,24 @@ ut_esnap_create(void *bs_ctx, struct spdk_blob *blob, const void *id, uint32_t i
}

static int
ut_esnap_create_with_count(void *bs_ctx, struct spdk_blob *blob,
ut_esnap_create_with_count(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
			   const void *id, uint32_t id_len, struct spdk_bs_dev **bs_devp)
{
	uint32_t *bs_ctx_count = bs_ctx;
	uint32_t *blob_ctx_count = blob_ctx;

	SPDK_CU_ASSERT_FATAL(bs_ctx != NULL);

	(*bs_ctx_count)++;
	return ut_esnap_create(NULL, blob, id, id_len, bs_devp);

	/*
	 * blob_ctx can be non-NULL when spdk_bs_open_blob() is used. Opens that come via
	 * spdk_bs_load(), spdk_bs_open_blob(), and those that come via spdk_bs_open_blob_ext() with
	 * NULL opts->esnap_ctx will have blob_ctx == NULL.
	 */
	if (blob_ctx_count != NULL) {
		(*blob_ctx_count)++;
	}

	return ut_esnap_create(NULL, NULL, blob, id, id_len, bs_devp);
}