Commit c355bbb1 authored by Piotr Pelplinski's avatar Piotr Pelplinski Committed by Jim Harris
Browse files

blob: Add xattrs to spdk_blob_opts.

parent 95ac75aa
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -208,6 +208,15 @@ uint64_t spdk_blob_get_num_clusters(struct spdk_blob *blob);

struct spdk_blob_opts {
	uint64_t  num_clusters;
	/* Number of attributes */
	size_t	xattr_count;
	/* Array of attribute names. Caller should free this array after use. */
	char	**xattr_names;
	/* User context passed to get_xattr_value function */
	void	*xattr_ctx;
	/* Callback that will return value for each attribute name. */
	void	(*get_xattr_value)(void *xattr_ctx, const char *name,
				   const void **value, size_t *value_len);
};

/* Initialize an spdk_blob_opts structure to the default blob option values. */
+34 −1
Original line number Diff line number Diff line
@@ -87,6 +87,10 @@ void
spdk_blob_opts_init(struct spdk_blob_opts *opts)
{
	opts->num_clusters = 0;
	opts->xattr_count = 0;
	opts->xattr_names = NULL;
	opts->xattr_ctx = NULL;
	opts->get_xattr_value = NULL;
}

static struct spdk_blob_data *
@@ -2702,6 +2706,29 @@ _spdk_bs_create_blob_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
	spdk_bs_sequence_finish(seq, bserrno);
}

static int
_spdk_blob_set_xattrs(struct spdk_blob	*blob, const struct spdk_blob_opts *opts)
{
	uint64_t i;
	size_t value_len = 0;
	int rc;
	const void *value = NULL;
	if (opts->xattr_count > 0 && opts->get_xattr_value == NULL) {
		return -EINVAL;
	}
	for (i = 0; i < opts->xattr_count; i++) {
		opts->get_xattr_value(opts->xattr_ctx, opts->xattr_names[i], &value, &value_len);
		if (value == NULL || value_len == 0) {
			return -EINVAL;
		}
		rc = spdk_blob_set_xattr(blob, opts->xattr_names[i], value, value_len);
		if (rc < 0) {
			return rc;
		}
	}
	return 0;
}

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)
{
@@ -2711,6 +2738,7 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_
	struct spdk_blob_opts	opts_default;
	spdk_bs_sequence_t	*seq;
	spdk_blob_id		id;
	int rc;

	page_idx = spdk_bit_array_find_first_clear(bs->used_md_pages, 0);
	if (page_idx >= spdk_bit_array_capacity(bs->used_md_pages)) {
@@ -2734,7 +2762,12 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_
		spdk_blob_opts_init(&opts_default);
		opts = &opts_default;
	}

	rc = _spdk_blob_set_xattrs(__data_to_blob(blob), opts);
	if (rc < 0) {
		_spdk_blob_free(blob);
		cb_fn(cb_arg, 0, rc);
		return;
	}
	spdk_blob_resize(__data_to_blob(blob), opts->num_clusters);
	cpl.type = SPDK_BS_CPL_TYPE_BLOBID;
	cpl.u.blobid.cb_fn = cb_fn;
+132 −1
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ struct spdk_blob *g_blob;
int g_bserrno;
struct spdk_xattr_names *g_names;
int g_done;
char *g_xattr_names[] = {"first", "second", "third"};
char *g_xattr_values[] = {"one", "two", "three"};
uint64_t g_ctx = 1729;

bool g_scheduler_delay = false;

@@ -2265,6 +2268,133 @@ 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)
{
	struct spdk_blob_store *bs;
	struct spdk_bs_dev *dev;
	struct spdk_blob *blob;
	struct spdk_blob_opts opts;
	spdk_blob_id blobid;
	const void *value;
	size_t value_len;
	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 extra attributes */
	spdk_blob_opts_init(&opts);

	opts.xattr_names = g_xattr_names;
	opts.get_xattr_value = _get_xattr_value;
	opts.xattr_count = 3;
	opts.xattr_ctx = &g_ctx;

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

	/* Get the xattrs */
	value = NULL;

	rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len);
	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);
	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);
	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);

	/* Try to get non existing attribute */

	rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len);
	CU_ASSERT(rc == -ENOENT);

	spdk_blob_close(blob, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	blob = NULL;
	g_blob = NULL;
	g_blobid = SPDK_BLOBID_INVALID;

	/* NULL callback */
	spdk_blob_opts_init(&opts);
	opts.xattr_names = g_xattr_names;
	opts.get_xattr_value = NULL;
	opts.xattr_count = 1;
	opts.xattr_ctx = &g_ctx;

	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
	CU_ASSERT(g_bserrno == -EINVAL);
	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);

	/* NULL values */
	spdk_blob_opts_init(&opts);
	opts.xattr_names = g_xattr_names;
	opts.get_xattr_value = _get_xattr_value_null;
	opts.xattr_count = 1;
	opts.xattr_ctx = NULL;

	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
	CU_ASSERT(g_bserrno == -EINVAL);

	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;
@@ -2309,7 +2439,8 @@ int main(int argc, char **argv)
		CU_add_test(suite, "super_block_crc", super_block_crc) == NULL ||
		CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL ||
		CU_add_test(suite, "blob_flags", blob_flags) == NULL ||
		CU_add_test(suite, "bs_version", bs_version) == NULL
		CU_add_test(suite, "bs_version", bs_version) == NULL ||
		CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL
	) {
		CU_cleanup_registry();
		return CU_get_error();