diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 36cf78ba6..72907f73b 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -140,15 +140,21 @@ _spdk_bs_release_cluster(struct spdk_blob_store *bs, uint32_t cluster_num) pthread_mutex_unlock(&bs->used_clusters_mutex); } +static void +_spdk_blob_xattrs_init(struct spdk_blob_xattr_opts *xattrs) +{ + xattrs->count = 0; + xattrs->names = NULL; + xattrs->ctx = NULL; + xattrs->get_value = NULL; +} + void spdk_blob_opts_init(struct spdk_blob_opts *opts) { opts->num_clusters = 0; opts->thin_provision = false; - opts->xattrs.count = 0; - opts->xattrs.names = NULL; - opts->xattrs.ctx = NULL; - opts->xattrs.get_value = NULL; + _spdk_blob_xattrs_init(&opts->xattrs); } static struct spdk_blob * @@ -3414,13 +3420,17 @@ _spdk_blob_set_thin_provision(struct spdk_blob *blob) blob->state = SPDK_BLOB_STATE_DIRTY; } -void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_opts *opts, - spdk_blob_op_with_id_complete cb_fn, void *cb_arg) +static void +_spdk_bs_create_blob(struct spdk_blob_store *bs, + const struct spdk_blob_opts *opts, + const struct spdk_blob_xattr_opts *internal_xattrs, + spdk_blob_op_with_id_complete cb_fn, void *cb_arg) { struct spdk_blob *blob; uint32_t page_idx; struct spdk_bs_cpl cpl; struct spdk_blob_opts opts_default; + struct spdk_blob_xattr_opts internal_xattrs_default; spdk_bs_sequence_t *seq; spdk_blob_id id; int rc; @@ -3449,6 +3459,10 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_ spdk_blob_opts_init(&opts_default); opts = &opts_default; } + if (!internal_xattrs) { + _spdk_blob_xattrs_init(&internal_xattrs_default); + internal_xattrs = &internal_xattrs_default; + } rc = _spdk_blob_set_xattrs(blob, &opts->xattrs, false); if (rc < 0) { @@ -3456,6 +3470,14 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_ cb_fn(cb_arg, 0, rc); return; } + + rc = _spdk_blob_set_xattrs(blob, internal_xattrs, true); + if (rc < 0) { + _spdk_blob_free(blob); + cb_fn(cb_arg, 0, rc); + return; + } + if (opts->thin_provision) { _spdk_blob_set_thin_provision(blob); } @@ -3484,7 +3506,13 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_ void spdk_bs_create_blob(struct spdk_blob_store *bs, spdk_blob_op_with_id_complete cb_fn, void *cb_arg) { - spdk_bs_create_blob_ext(bs, NULL, cb_fn, cb_arg); + _spdk_bs_create_blob(bs, NULL, NULL, cb_fn, cb_arg); +} + +void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_opts *opts, + spdk_blob_op_with_id_complete cb_fn, void *cb_arg) +{ + _spdk_bs_create_blob(bs, opts, NULL, cb_fn, cb_arg); } /* END spdk_bs_create_blob */ diff --git a/test/unit/lib/blob/blob.c/blob_ut.c b/test/unit/lib/blob/blob.c/blob_ut.c index b9f0e4352..cebeb32a1 100644 --- a/test/unit/lib/blob/blob.c/blob_ut.c +++ b/test/unit/lib/blob/blob.c/blob_ut.c @@ -87,6 +87,39 @@ struct spdk_bs_super_block_ver1 { } __attribute__((packed)); SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); + +static void +_get_xattr_value(void *arg, const char *name, + const void **value, size_t *value_len) +{ + uint64_t i; + + SPDK_CU_ASSERT_FATAL(value_len != NULL); + SPDK_CU_ASSERT_FATAL(value != NULL); + CU_ASSERT(arg == &g_ctx) + + for (i = 0; i < sizeof(g_xattr_names); i++) { + if (!strcmp(name, g_xattr_names[i])) { + *value_len = strlen(g_xattr_values[i]); + *value = g_xattr_values[i]; + break; + } + } +} + +static void +_get_xattr_value_null(void *arg, const char *name, + const void **value, size_t *value_len) +{ + SPDK_CU_ASSERT_FATAL(value_len != NULL); + SPDK_CU_ASSERT_FATAL(value != NULL); + CU_ASSERT(arg == NULL) + + *value_len = 0; + *value = NULL; +} + + static void _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) { @@ -357,6 +390,98 @@ blob_create(void) } +static void +blob_create_internal(void) +{ + struct spdk_blob_store *bs; + struct spdk_bs_dev *dev; + struct spdk_blob *blob; + struct spdk_blob_opts opts; + struct spdk_blob_xattr_opts internal_xattrs; + const void *value; + size_t value_len; + spdk_blob_id blobid; + int rc; + + 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; + + /* Create blob with custom xattrs */ + + spdk_blob_opts_init(&opts); + _spdk_blob_xattrs_init(&internal_xattrs); + internal_xattrs.count = 3; + internal_xattrs.names = g_xattr_names; + internal_xattrs.get_value = _get_xattr_value; + internal_xattrs.ctx = &g_ctx; + + _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); + CU_ASSERT(g_bserrno == 0); + CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); + 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; + + rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(value != NULL); + CU_ASSERT(value_len == strlen(g_xattr_values[0])); + CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); + + rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(value != NULL); + CU_ASSERT(value_len == strlen(g_xattr_values[1])); + CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); + + rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); + CU_ASSERT(rc == 0); + SPDK_CU_ASSERT_FATAL(value != NULL); + CU_ASSERT(value_len == strlen(g_xattr_values[2])); + CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); + + rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); + CU_ASSERT(rc != 0); + + rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); + CU_ASSERT(rc != 0); + + rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); + CU_ASSERT(rc != 0); + + spdk_blob_close(blob, blob_op_complete, NULL); + CU_ASSERT(g_bserrno == 0); + + /* Create blob with NULL internal options */ + + _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); + CU_ASSERT(g_bserrno == 0); + CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); + 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); + CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); + + blob = g_blob; + + spdk_blob_close(blob, 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; + +} + static void blob_thin_provision(void) { @@ -2605,37 +2730,6 @@ bs_version(void) CU_ASSERT(super->used_blobid_mask_len == 0); } -static void -_get_xattr_value(void *arg, const char *name, - const void **value, size_t *value_len) -{ - uint64_t i; - - SPDK_CU_ASSERT_FATAL(value_len != NULL); - SPDK_CU_ASSERT_FATAL(value != NULL); - CU_ASSERT(arg == &g_ctx) - - for (i = 0; i < sizeof(g_xattr_names); i++) { - if (!strcmp(name, g_xattr_names[i])) { - *value_len = strlen(g_xattr_values[i]); - *value = g_xattr_values[i]; - break; - } - } -} - -static void -_get_xattr_value_null(void *arg, const char *name, - const void **value, size_t *value_len) -{ - SPDK_CU_ASSERT_FATAL(value_len != NULL); - SPDK_CU_ASSERT_FATAL(value != NULL); - CU_ASSERT(arg == NULL) - - *value_len = 0; - *value = NULL; -} - static void blob_set_xattrs(void) { @@ -3213,6 +3307,7 @@ int main(int argc, char **argv) CU_add_test(suite, "blob_init", blob_init) == NULL || CU_add_test(suite, "blob_open", blob_open) == NULL || CU_add_test(suite, "blob_create", blob_create) == NULL || + CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || CU_add_test(suite, "blob_delete", blob_delete) == NULL || CU_add_test(suite, "blob_resize", blob_resize) == NULL ||