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:
parent
a75bdf361c
commit
4d5ee263b1
@ -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
|
* \param bs_ctx Context provided by the blobstore consumer via esnap_ctx member of struct
|
||||||
* spdk_bs_opts.
|
* 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 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 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.
|
* \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.
|
* \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,
|
const void *esnap_id, uint32_t id_size,
|
||||||
struct spdk_bs_dev **bs_dev);
|
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.
|
* New added fields should be put at the end of the struct.
|
||||||
*/
|
*/
|
||||||
size_t opts_size;
|
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.
|
* Initialize a spdk_blob_open_opts structure to the default blob option values.
|
||||||
|
@ -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 void blob_update_clear_method(struct spdk_blob *blob);
|
||||||
|
|
||||||
static int
|
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_blob_store *bs = blob->bs;
|
||||||
struct spdk_bs_dev *bs_dev = NULL;
|
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");
|
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) {
|
if (rc != 0) {
|
||||||
SPDK_DEBUGLOG(blob_esnap, "blob 0x%" PRIx64 ": failed to load back_bs_dev "
|
SPDK_DEBUGLOG(blob_esnap, "blob 0x%" PRIx64 ": failed to load back_bs_dev "
|
||||||
"with error %d\n", blob->id, rc);
|
"with error %d\n", blob->id, rc);
|
||||||
@ -1388,7 +1389,7 @@ blob_load_esnap(struct spdk_blob *blob)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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_load_ctx *ctx = cb_arg;
|
||||||
struct spdk_blob *blob = ctx->blob;
|
struct spdk_blob *blob = ctx->blob;
|
||||||
@ -1397,7 +1398,7 @@ blob_load_backing_dev(void *cb_arg)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (blob_is_esnap_clone(blob)) {
|
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));
|
assert((rc == 0) ^ (blob->back_bs_dev == NULL));
|
||||||
blob_load_final(ctx, rc);
|
blob_load_final(ctx, rc);
|
||||||
return;
|
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
|
static void
|
||||||
@ -1595,7 +1596,7 @@ blob_load_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
|||||||
if (blob->extent_table_found) {
|
if (blob->extent_table_found) {
|
||||||
blob_load_cpl_extents_cpl(seq, ctx, 0);
|
blob_load_cpl_extents_cpl(seq, ctx, 0);
|
||||||
} else {
|
} 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(clear_method);
|
||||||
|
SET_FIELD(esnap_ctx);
|
||||||
|
|
||||||
dst->opts_size = src->opts_size;
|
dst->opts_size = src->opts_size;
|
||||||
|
|
||||||
/* You should not remove this statement, but need to update the assert statement
|
/* 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 */
|
* 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 FIELD_OK
|
||||||
#undef SET_FIELD
|
#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_fn = cb_fn;
|
||||||
cpl.u.blob_handle.cb_arg = cb_arg;
|
cpl.u.blob_handle.cb_arg = cb_arg;
|
||||||
cpl.u.blob_handle.blob = blob;
|
cpl.u.blob_handle.blob = blob;
|
||||||
|
cpl.u.blob_handle.esnap_ctx = opts_local.esnap_ctx;
|
||||||
|
|
||||||
seq = bs_sequence_start(bs->md_channel, &cpl);
|
seq = bs_sequence_start(bs->md_channel, &cpl);
|
||||||
if (!seq) {
|
if (!seq) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: BSD-3-Clause
|
/* SPDX-License-Identifier: BSD-3-Clause
|
||||||
* Copyright (C) 2017 Intel Corporation.
|
* Copyright (C) 2017 Intel Corporation.
|
||||||
* All rights reserved.
|
* 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
|
#ifndef SPDK_BS_REQUEST_H
|
||||||
@ -65,6 +65,7 @@ struct spdk_bs_cpl {
|
|||||||
spdk_blob_op_with_handle_complete cb_fn;
|
spdk_blob_op_with_handle_complete cb_fn;
|
||||||
void *cb_arg;
|
void *cb_arg;
|
||||||
struct spdk_blob *blob;
|
struct spdk_blob *blob;
|
||||||
|
void *esnap_ctx;
|
||||||
} blob_handle;
|
} blob_handle;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -7415,13 +7415,14 @@ blob_esnap_create(void)
|
|||||||
struct spdk_bs_opts bs_opts;
|
struct spdk_bs_opts bs_opts;
|
||||||
struct ut_esnap_opts esnap_opts;
|
struct ut_esnap_opts esnap_opts;
|
||||||
struct spdk_blob_opts opts;
|
struct spdk_blob_opts opts;
|
||||||
|
struct spdk_blob_open_opts open_opts;
|
||||||
struct spdk_blob *blob;
|
struct spdk_blob *blob;
|
||||||
uint32_t cluster_sz, block_sz;
|
uint32_t cluster_sz, block_sz;
|
||||||
const uint32_t esnap_num_clusters = 4;
|
const uint32_t esnap_num_clusters = 4;
|
||||||
uint64_t esnap_num_blocks;
|
uint64_t esnap_num_blocks;
|
||||||
uint32_t sz;
|
uint32_t sz;
|
||||||
spdk_blob_id blobid;
|
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);
|
cluster_sz = spdk_bs_get_cluster_size(bs);
|
||||||
block_sz = spdk_bs_get_io_unit_size(bs);
|
block_sz = spdk_bs_get_io_unit_size(bs);
|
||||||
@ -7522,6 +7523,19 @@ blob_esnap_create(void)
|
|||||||
poll_threads();
|
poll_threads();
|
||||||
CU_ASSERT(g_bserrno == 0);
|
CU_ASSERT(g_bserrno == 0);
|
||||||
g_blob = NULL;
|
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
|
static void
|
||||||
|
@ -92,12 +92,14 @@ ut_esnap_dev_alloc(const struct ut_esnap_opts *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ut_esnap_create(void *bs_ctx, struct spdk_blob *blob, const void *id, uint32_t id_len,
|
ut_esnap_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
|
||||||
struct spdk_bs_dev **bs_devp)
|
const void *id, uint32_t id_len, struct spdk_bs_dev **bs_devp)
|
||||||
{
|
{
|
||||||
struct spdk_bs_dev *bs_dev = NULL;
|
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);
|
CU_ASSERT(bs_ctx == NULL);
|
||||||
|
|
||||||
SPDK_CU_ASSERT_FATAL(id != 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
|
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)
|
const void *id, uint32_t id_len, struct spdk_bs_dev **bs_devp)
|
||||||
{
|
{
|
||||||
uint32_t *bs_ctx_count = bs_ctx;
|
uint32_t *bs_ctx_count = bs_ctx;
|
||||||
|
uint32_t *blob_ctx_count = blob_ctx;
|
||||||
|
|
||||||
SPDK_CU_ASSERT_FATAL(bs_ctx != NULL);
|
SPDK_CU_ASSERT_FATAL(bs_ctx != NULL);
|
||||||
|
|
||||||
(*bs_ctx_count)++;
|
(*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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user