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: Mike Gerdts <mgerdts@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14971
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Mike Gerdts 2022-10-11 08:52:13 -05:00 committed by Konrad Sztyber
parent a75bdf361c
commit 4d5ee263b1
5 changed files with 55 additions and 16 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -1,7 +1,7 @@
/* 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 {

View File

@ -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

View File

@ -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);
}