blob: allow inserting cluster from non metadata thread
This will be needed for thin provisioning, since a write I/O may result in needing to insert a cluster into the blob and that write I/O may not have been performed on the metadata thread. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I84b0cb6e7af87b1f9c6cab4e2c24fa26b12e2c06 Reviewed-on: https://review.gerrithub.io/396737 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
71dba27cab
commit
98d28d604d
@ -50,6 +50,8 @@
|
||||
static int spdk_bs_register_md_thread(struct spdk_blob_store *bs);
|
||||
static int spdk_bs_unregister_md_thread(struct spdk_blob_store *bs);
|
||||
static void _spdk_blob_close_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno);
|
||||
void _spdk_blob_insert_cluster_on_md_thread(struct spdk_blob_data *blob, uint32_t cluster_num,
|
||||
uint64_t cluster, spdk_blob_op_complete cb_fn, void *cb_arg);
|
||||
|
||||
static inline size_t
|
||||
divide_round_up(size_t num, size_t divisor)
|
||||
@ -3214,6 +3216,71 @@ spdk_blob_sync_md(struct spdk_blob *_blob, spdk_blob_op_complete cb_fn, void *cb
|
||||
|
||||
/* END spdk_blob_sync_md */
|
||||
|
||||
struct spdk_blob_insert_cluster_ctx {
|
||||
struct spdk_thread *thread;
|
||||
struct spdk_blob_data *blob;
|
||||
uint32_t cluster_num; /* cluster index in blob */
|
||||
uint32_t cluster; /* cluster on disk */
|
||||
int rc;
|
||||
spdk_blob_op_complete cb_fn;
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
static void
|
||||
_spdk_blob_insert_cluster_msg_cpl(void *arg)
|
||||
{
|
||||
struct spdk_blob_insert_cluster_ctx *ctx = arg;
|
||||
|
||||
ctx->cb_fn(ctx->cb_arg, ctx->rc);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_blob_insert_cluster_msg_cb(void *arg, int bserrno)
|
||||
{
|
||||
struct spdk_blob_insert_cluster_ctx *ctx = arg;
|
||||
|
||||
ctx->rc = bserrno;
|
||||
spdk_thread_send_msg(ctx->thread, _spdk_blob_insert_cluster_msg_cpl, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_blob_insert_cluster_msg(void *arg)
|
||||
{
|
||||
struct spdk_blob_insert_cluster_ctx *ctx = arg;
|
||||
|
||||
ctx->rc = _spdk_blob_insert_cluster(ctx->blob, ctx->cluster_num, ctx->cluster);
|
||||
if (ctx->rc != 0) {
|
||||
spdk_thread_send_msg(ctx->thread, _spdk_blob_insert_cluster_msg_cpl, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->blob->state = SPDK_BLOB_STATE_DIRTY;
|
||||
_spdk_blob_sync_md(ctx->blob, _spdk_blob_insert_cluster_msg_cb, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
_spdk_blob_insert_cluster_on_md_thread(struct spdk_blob_data *blob, uint32_t cluster_num,
|
||||
uint64_t cluster, spdk_blob_op_complete cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_blob_insert_cluster_ctx *ctx;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (ctx == NULL) {
|
||||
cb_fn(cb_arg, -ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->thread = spdk_get_thread();
|
||||
ctx->blob = blob;
|
||||
ctx->cluster_num = cluster_num;
|
||||
ctx->cluster = cluster;
|
||||
ctx->cb_fn = cb_fn;
|
||||
ctx->cb_arg = cb_arg;
|
||||
|
||||
spdk_thread_send_msg(blob->bs->md_thread, _spdk_blob_insert_cluster_msg, ctx);
|
||||
}
|
||||
|
||||
/* START spdk_blob_close */
|
||||
|
||||
static void
|
||||
|
@ -2679,7 +2679,7 @@ blob_thin_prov_alloc(void)
|
||||
|
||||
spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blob != NULL);
|
||||
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
|
||||
blob = g_blob;
|
||||
blob_data = __blob_to_data(blob);
|
||||
|
||||
@ -2698,6 +2698,88 @@ blob_thin_prov_alloc(void)
|
||||
g_bs = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blob_insert_cluster_msg(void)
|
||||
{
|
||||
struct spdk_blob_store *bs;
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_blob *blob;
|
||||
struct spdk_blob_data *blob_data;
|
||||
struct spdk_blob_opts opts;
|
||||
spdk_blob_id blobid;
|
||||
uint64_t free_clusters;
|
||||
|
||||
dev = init_dev();
|
||||
|
||||
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
bs = g_bs;
|
||||
free_clusters = spdk_bs_free_cluster_count(bs);
|
||||
|
||||
/* Set blob as thin provisioned */
|
||||
spdk_blob_opts_init(&opts);
|
||||
opts.thin_provision = true;
|
||||
opts.num_clusters = 4;
|
||||
|
||||
spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
|
||||
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
|
||||
blobid = g_blobid;
|
||||
|
||||
spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
|
||||
blob = g_blob;
|
||||
blob_data = __blob_to_data(blob);
|
||||
|
||||
CU_ASSERT(blob_data->active.num_clusters == 4);
|
||||
CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4);
|
||||
CU_ASSERT(blob_data->active.clusters[1] == 0);
|
||||
|
||||
_spdk_bs_claim_cluster(bs, 0xF);
|
||||
_spdk_blob_insert_cluster_on_md_thread(blob_data, 1, 0xF, blob_op_complete, NULL);
|
||||
|
||||
CU_ASSERT(blob_data->active.clusters[1] != 0);
|
||||
|
||||
spdk_blob_close(blob, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
/* Unload the blob store */
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_blob = NULL;
|
||||
g_blobid = 0;
|
||||
|
||||
/* Load an existing blob store */
|
||||
dev = init_dev();
|
||||
spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
bs = g_bs;
|
||||
|
||||
spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blob != NULL);
|
||||
blob = g_blob;
|
||||
blob_data = __blob_to_data(blob);
|
||||
|
||||
CU_ASSERT(blob_data->active.clusters[1] != 0);
|
||||
|
||||
spdk_blob_close(blob, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CU_pSuite suite = NULL;
|
||||
@ -2746,7 +2828,8 @@ int main(int argc, char **argv)
|
||||
CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
|
||||
CU_add_test(suite, "bs_version", bs_version) == NULL ||
|
||||
CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL ||
|
||||
CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL
|
||||
CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL ||
|
||||
CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
Reference in New Issue
Block a user