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
|
||||
* 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.
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user