Merge pull request #120 from arutk/core-query-api
Add API to query for core devices associated with cache
This commit is contained in:
		| @@ -83,6 +83,30 @@ typedef void (*ocf_metadata_probe_end_t)(void *priv, int error, | |||||||
| void ocf_metadata_probe(ocf_ctx_t ctx, ocf_volume_t volume, | void ocf_metadata_probe(ocf_ctx_t ctx, ocf_volume_t volume, | ||||||
| 		ocf_metadata_probe_end_t cmpl, void *priv); | 		ocf_metadata_probe_end_t cmpl, void *priv); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Metadata probe for cores completion callback | ||||||
|  |  * | ||||||
|  |  * @param[in] priv Completion context | ||||||
|  |  * @param[in] error Error code (zero on success) | ||||||
|  |  * @param[in] num_cores Number of cores in cache metadata | ||||||
|  |  */ | ||||||
|  | typedef void (*ocf_metadata_probe_cores_end_t)(void *priv, int error, | ||||||
|  | 		unsigned int num_cores); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Probe cache device for associated cores | ||||||
|  |  * | ||||||
|  |  * @param[in] ctx handle to object designating ocf context | ||||||
|  |  * @param[in] volume Cache volume | ||||||
|  |  * @param[in,out] uuids Array of uuids | ||||||
|  |  * @param[in] uuid_count Size of @uuid array | ||||||
|  |  * @param[in] cmpl Completion callback | ||||||
|  |  * @param[in] priv Completion context | ||||||
|  |  */ | ||||||
|  | void ocf_metadata_probe_cores(ocf_ctx_t ctx, ocf_volume_t volume, | ||||||
|  | 		struct ocf_volume_uuid *uuids, uint32_t uuid_count, | ||||||
|  | 		ocf_metadata_probe_cores_end_t cmpl, void *priv); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Check if sectors in cache line before given address are invalid |  * @brief Check if sectors in cache line before given address are invalid | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -217,21 +217,6 @@ int ocf_mngt_cache_visit(ocf_ctx_t ctx, ocf_mngt_cache_visitor_t visitor, | |||||||
| int ocf_mngt_cache_visit_reverse(ocf_ctx_t ctx, ocf_mngt_cache_visitor_t visitor, | int ocf_mngt_cache_visit_reverse(ocf_ctx_t ctx, ocf_mngt_cache_visitor_t visitor, | ||||||
| 		void *cntx); | 		void *cntx); | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @brief Cache probe status |  | ||||||
|  */ |  | ||||||
| struct ocf_mngt_cache_probe_status { |  | ||||||
| 	/** |  | ||||||
| 	 * @brief Gracefully shutdown for cache detected |  | ||||||
| 	 */ |  | ||||||
| 	bool clean_shutdown; |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * @brief Cache is dirty and requires flushing |  | ||||||
| 	 */ |  | ||||||
| 	bool cache_dirty; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Cache start configuration |  * @brief Cache start configuration | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ struct ocf_volume_uuid { | |||||||
| 	size_t size; | 	size_t size; | ||||||
| 		/*!< UUID data size */ | 		/*!< UUID data size */ | ||||||
|  |  | ||||||
| 	const void *data; | 	void *data; | ||||||
| 		/*!< UUID data content */ | 		/*!< UUID data content */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -360,3 +360,39 @@ void ocf_metadata_probe(ocf_ctx_t ctx, ocf_volume_t volume, | |||||||
| 	if (result) | 	if (result) | ||||||
| 		cmpl(priv, result, NULL); | 		cmpl(priv, result, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* completion context for query_cores */ | ||||||
|  | struct ocf_metadata_query_cores_context | ||||||
|  | { | ||||||
|  | 	ocf_metadata_probe_cores_end_t cmpl; | ||||||
|  | 	void *priv; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void ocf_metadata_query_cores_end(void *_context, int error, | ||||||
|  | 		unsigned num_cores) | ||||||
|  | { | ||||||
|  | 	struct ocf_metadata_query_cores_context *context = _context; | ||||||
|  |  | ||||||
|  | 	context->cmpl(context->priv, error, num_cores); | ||||||
|  | 	env_vfree(context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ocf_metadata_probe_cores(ocf_ctx_t ctx, ocf_volume_t volume, | ||||||
|  | 		struct ocf_volume_uuid *uuids, uint32_t uuids_count, | ||||||
|  | 		ocf_metadata_probe_cores_end_t cmpl, void *priv) | ||||||
|  | { | ||||||
|  | 	struct ocf_metadata_query_cores_context *context; | ||||||
|  | 	const struct ocf_metadata_iface *iface; | ||||||
|  |  | ||||||
|  | 	context = env_vzalloc(sizeof(*context)); | ||||||
|  | 	if (!context) | ||||||
|  | 		cmpl(priv, -OCF_ERR_NO_MEM, 0); | ||||||
|  | 	context->cmpl = cmpl; | ||||||
|  | 	context->priv = priv; | ||||||
|  |  | ||||||
|  | 	iface = metadata_hash_get_iface(); | ||||||
|  | 	iface->query_cores(ctx, volume, uuids, uuids_count, | ||||||
|  | 			ocf_metadata_query_cores_end, context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -251,8 +251,7 @@ static int ocf_metadata_hash_calculate_metadata_size( | |||||||
| 					raw->entries_in_page); | 					raw->entries_in_page); | ||||||
|  |  | ||||||
| 			/* Update offset for next container */ | 			/* Update offset for next container */ | ||||||
| 			count_pages += ocf_metadata_raw_size_on_ssd( | 			count_pages += ocf_metadata_raw_size_on_ssd(raw); | ||||||
| 					cache, raw); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| @@ -446,27 +445,16 @@ static void ocf_metadata_hash_deinit(struct ocf_cache *cache) | |||||||
| 		ENV_BUG(); | 		ENV_BUG(); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int ocf_metadata_hash_init(struct ocf_cache *cache, | static struct ocf_metadata_hash_ctrl *ocf_metadata_hash_ctrl_init( | ||||||
| 	ocf_cache_line_size_t cache_line_size) | 		bool metadata_volatile) | ||||||
| { | { | ||||||
| 	struct ocf_metadata_hash_ctrl *ctrl = NULL; | 	struct ocf_metadata_hash_ctrl *ctrl = NULL; | ||||||
| 	struct ocf_cache_line_settings *settings = |  | ||||||
| 		(struct ocf_cache_line_settings *)&cache->metadata.settings; |  | ||||||
| 	uint32_t i = 0; |  | ||||||
| 	uint32_t page = 0; | 	uint32_t page = 0; | ||||||
| 	int result = 0; | 	uint32_t i = 0; | ||||||
|  |  | ||||||
| 	OCF_DEBUG_TRACE(cache); |  | ||||||
|  |  | ||||||
| 	ENV_WARN_ON(cache->metadata.iface_priv); |  | ||||||
|  |  | ||||||
| 	ctrl = env_vzalloc(sizeof(*ctrl)); | 	ctrl = env_vzalloc(sizeof(*ctrl)); | ||||||
| 	if (!ctrl) | 	if (!ctrl) | ||||||
| 		return -ENOMEM; | 		return NULL; | ||||||
|  |  | ||||||
| 	cache->metadata.iface_priv = ctrl; |  | ||||||
|  |  | ||||||
| 	ocf_metadata_config_init(cache, settings, cache_line_size); |  | ||||||
|  |  | ||||||
| 	/* Initial setup of RAW containers */ | 	/* Initial setup of RAW containers */ | ||||||
| 	for (i = 0; i < metadata_segment_fixed_size_max; i++) { | 	for (i = 0; i < metadata_segment_fixed_size_max; i++) { | ||||||
| @@ -477,7 +465,7 @@ static int ocf_metadata_hash_init(struct ocf_cache *cache, | |||||||
| 		/* Default type for metadata RAW container */ | 		/* Default type for metadata RAW container */ | ||||||
| 		raw->raw_type = metadata_raw_type_ram; | 		raw->raw_type = metadata_raw_type_ram; | ||||||
|  |  | ||||||
| 		if (cache->metadata.is_volatile) { | 		if (metadata_volatile) { | ||||||
| 			raw->raw_type = metadata_raw_type_volatile; | 			raw->raw_type = metadata_raw_type_volatile; | ||||||
| 		} else if (i == metadata_segment_core_uuid) { | 		} else if (i == metadata_segment_core_uuid) { | ||||||
| 			raw->raw_type = metadata_raw_type_dynamic; | 			raw->raw_type = metadata_raw_type_dynamic; | ||||||
| @@ -499,11 +487,35 @@ static int ocf_metadata_hash_init(struct ocf_cache *cache, | |||||||
| 				raw->entries_in_page); | 				raw->entries_in_page); | ||||||
|  |  | ||||||
| 		/* Update offset for next container */ | 		/* Update offset for next container */ | ||||||
| 		page += ocf_metadata_raw_size_on_ssd(cache, raw); | 		page += ocf_metadata_raw_size_on_ssd(raw); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctrl->count_pages = page; | 	ctrl->count_pages = page; | ||||||
|  |  | ||||||
|  | 	return ctrl; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ocf_metadata_hash_init(struct ocf_cache *cache, | ||||||
|  | 		ocf_cache_line_size_t cache_line_size) | ||||||
|  | { | ||||||
|  | 	struct ocf_metadata_hash_ctrl *ctrl = NULL; | ||||||
|  | 	struct ocf_metadata *metadata = &cache->metadata; | ||||||
|  | 	struct ocf_cache_line_settings *settings = | ||||||
|  | 		(struct ocf_cache_line_settings *)&metadata->settings; | ||||||
|  | 	uint32_t i = 0; | ||||||
|  | 	int result = 0; | ||||||
|  |  | ||||||
|  | 	OCF_DEBUG_TRACE(cache); | ||||||
|  |  | ||||||
|  | 	ENV_WARN_ON(metadata->iface_priv); | ||||||
|  |  | ||||||
|  | 	ocf_metadata_config_init(cache, settings, cache_line_size); | ||||||
|  |  | ||||||
|  | 	ctrl = ocf_metadata_hash_ctrl_init(metadata->is_volatile); | ||||||
|  | 	if (!ctrl) | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 	metadata->iface_priv = ctrl; | ||||||
|  |  | ||||||
| 	for (i = 0; i < metadata_segment_fixed_size_max; i++) { | 	for (i = 0; i < metadata_segment_fixed_size_max; i++) { | ||||||
| 		result |= ocf_metadata_raw_init(cache, &(ctrl->raw_desc[i])); | 		result |= ocf_metadata_raw_init(cache, &(ctrl->raw_desc[i])); | ||||||
| 		if (result) | 		if (result) | ||||||
| @@ -531,7 +543,305 @@ static int ocf_metadata_hash_init(struct ocf_cache *cache, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* metadata segment data + iterators */ | ||||||
|  | struct query_cores_data | ||||||
|  | { | ||||||
|  | 	/* array of data */ | ||||||
|  | 	ctx_data_t *data; | ||||||
|  | 	/* current metadata entry counter */ | ||||||
|  | 	uint32_t entry; | ||||||
|  | 	/* number of entries per page */ | ||||||
|  | 	uint32_t entries_in_page; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* query cores context */ | ||||||
|  | struct query_cores_context | ||||||
|  | { | ||||||
|  | 	ocf_ctx_t ctx; | ||||||
|  |  | ||||||
|  | 	struct ocf_superblock_config superblock; | ||||||
|  | 	struct ocf_metadata_uuid muuid; | ||||||
|  |  | ||||||
|  | 	struct { | ||||||
|  | 		struct query_cores_data core_uuids; | ||||||
|  | 		struct query_cores_data core_config; | ||||||
|  | 		struct query_cores_data superblock; | ||||||
|  | 	} data; | ||||||
|  |  | ||||||
|  | 	env_atomic count; | ||||||
|  | 	env_atomic error; | ||||||
|  |  | ||||||
|  | 	/* OCF entry point parameters */ | ||||||
|  | 	struct { | ||||||
|  | 		struct ocf_volume_uuid *uuids; | ||||||
|  | 		uint32_t uuids_count; | ||||||
|  | 		void *priv; | ||||||
|  | 		ocf_metadata_query_cores_end_t cmpl; | ||||||
|  | 	} params; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* copy next metadata entry from data to memory buffer */ | ||||||
|  | static void ocf_metadata_hash_query_cores_data_read(ocf_ctx_t ctx, | ||||||
|  | 		struct query_cores_data *data, | ||||||
|  | 		void *buf, uint32_t size) | ||||||
|  | { | ||||||
|  | 	if (data->entry > 0 && data->entry % data->entries_in_page == 0) { | ||||||
|  | 		ctx_data_seek_check(ctx, data->data, | ||||||
|  | 				ctx_data_seek_current, | ||||||
|  | 				PAGE_SIZE - data->entries_in_page * size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx_data_rd_check(ctx, buf, data->data, size); | ||||||
|  |  | ||||||
|  | 	++data->entry; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ocf_metadata_query_cores_end(struct query_cores_context *context, | ||||||
|  | 		int error) | ||||||
|  | { | ||||||
|  | 	ocf_ctx_t ctx = context->ctx; | ||||||
|  | 	unsigned i, core_idx; | ||||||
|  | 	struct ocf_metadata_uuid *muuid = &context->muuid; | ||||||
|  | 	struct ocf_core_meta_config core_config; | ||||||
|  | 	unsigned core_count = 0; | ||||||
|  | 	unsigned long valid_core_bitmap[(OCF_CORE_MAX / | ||||||
|  | 			(sizeof(unsigned long) * 8)) + 1]; | ||||||
|  | 	unsigned out_cores; | ||||||
|  |  | ||||||
|  | 	if (error) | ||||||
|  | 		env_atomic_cmpxchg(&context->error, 0, error); | ||||||
|  |  | ||||||
|  | 	if (env_atomic_dec_return(&context->count)) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	error = env_atomic_read(&context->error); | ||||||
|  | 	if (error) | ||||||
|  | 		goto exit; | ||||||
|  |  | ||||||
|  | 	/* read superblock */ | ||||||
|  | 	ctx_data_rd_check(ctx, &context->superblock, | ||||||
|  | 			context->data.superblock.data, | ||||||
|  | 			sizeof(context->superblock)); | ||||||
|  |  | ||||||
|  | 	if (context->superblock.magic_number != CACHE_MAGIC_NUMBER) { | ||||||
|  | 		error = -ENODATA; | ||||||
|  | 		goto exit; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	env_memset(&valid_core_bitmap, sizeof(valid_core_bitmap), 0); | ||||||
|  |  | ||||||
|  | 	/* read valid cores from core config segment */ | ||||||
|  | 	for (i = 0; i < OCF_CORE_MAX; i++) { | ||||||
|  | 		ocf_metadata_hash_query_cores_data_read(ctx, | ||||||
|  | 				&context->data.core_config, | ||||||
|  | 				&core_config, sizeof(core_config)); | ||||||
|  | 		if (core_config.added) { | ||||||
|  | 			env_bit_set(i, valid_core_bitmap); | ||||||
|  | 			++core_count; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* read core uuids */ | ||||||
|  | 	out_cores = OCF_MIN(core_count, context->params.uuids_count); | ||||||
|  | 	for (i = 0, core_idx = 0; i < OCF_CORE_MAX && core_idx < out_cores; | ||||||
|  | 			i++) { | ||||||
|  | 		ocf_metadata_hash_query_cores_data_read(ctx, | ||||||
|  | 				&context->data.core_uuids, | ||||||
|  | 				muuid, sizeof(*muuid)); | ||||||
|  |  | ||||||
|  | 		if (!env_bit_test(i, valid_core_bitmap)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (muuid->size > OCF_VOLUME_UUID_MAX_SIZE) { | ||||||
|  | 			error = -EINVAL; | ||||||
|  | 			goto exit; | ||||||
|  | 		} | ||||||
|  | 		if (muuid->size > context->params.uuids[core_idx].size) { | ||||||
|  | 			error = -ENOSPC; | ||||||
|  | 			goto exit; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		error = env_memcpy(context->params.uuids[core_idx].data, | ||||||
|  | 				context->params.uuids[core_idx].size, | ||||||
|  | 				muuid->data, muuid->size); | ||||||
|  | 		if (error) | ||||||
|  | 			goto exit; | ||||||
|  | 		context->params.uuids[core_idx].size = muuid->size; | ||||||
|  |  | ||||||
|  | 		++core_idx; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | exit: | ||||||
|  | 	/* provide actual core count to completion */ | ||||||
|  | 	context->params.cmpl(context->params.priv, error, core_count); | ||||||
|  |  | ||||||
|  | 	/* free data */ | ||||||
|  | 	ctx_data_free(ctx, context->data.core_uuids.data); | ||||||
|  | 	ctx_data_free(ctx, context->data.core_config.data); | ||||||
|  | 	ctx_data_free(ctx, context->data.superblock.data); | ||||||
|  |  | ||||||
|  | 	env_vfree(context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ocf_metadata_query_cores_end_io(struct ocf_io *io, int error) | ||||||
|  | { | ||||||
|  | 	struct query_cores_context *context = io->priv1; | ||||||
|  |  | ||||||
|  | 	ocf_io_put(io); | ||||||
|  | 	ocf_metadata_query_cores_end(context, error); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ocf_metadata_query_cores_io(ocf_volume_t volume, | ||||||
|  | 		struct query_cores_context *context, ctx_data_t *data, | ||||||
|  | 		uint32_t offset, uint64_t page, uint32_t num_pages) | ||||||
|  | { | ||||||
|  | 	struct ocf_io *io; | ||||||
|  | 	int err; | ||||||
|  |  | ||||||
|  | 	env_atomic_inc(&context->count); | ||||||
|  |  | ||||||
|  | 	/* Allocate new IO */ | ||||||
|  | 	io = ocf_volume_new_io(volume); | ||||||
|  | 	if (!io) { | ||||||
|  | 		err = -OCF_ERR_NO_MEM; | ||||||
|  | 		goto exit_error; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* Setup IO */ | ||||||
|  | 	ocf_io_configure(io, | ||||||
|  | 			PAGES_TO_BYTES(page), | ||||||
|  | 			PAGES_TO_BYTES(num_pages), | ||||||
|  | 			OCF_READ, 0, 0); | ||||||
|  |  | ||||||
|  | 	ocf_io_set_cmpl(io, context, NULL, | ||||||
|  | 			ocf_metadata_query_cores_end_io); | ||||||
|  | 	err = ocf_io_set_data(io, data, PAGES_TO_BYTES(offset)); | ||||||
|  | 	if (err) { | ||||||
|  | 		ocf_io_put(io); | ||||||
|  | 		goto exit_error; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ocf_volume_submit_io(io); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | exit_error: | ||||||
|  | 	env_atomic_dec(&context->count); | ||||||
|  | 	return err; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ocf_metadata_query_cores_segment_io( | ||||||
|  | 		 struct query_cores_context *context, | ||||||
|  | 		ocf_ctx_t owner, | ||||||
|  | 		ocf_volume_t volume, | ||||||
|  | 		enum ocf_metadata_segment segment, | ||||||
|  | 		struct ocf_metadata_hash_ctrl *ctrl, | ||||||
|  | 		struct query_cores_data *segment_data) | ||||||
|  | { | ||||||
|  | 	uint32_t pages_left; | ||||||
|  | 	uint32_t pages; | ||||||
|  | 	uint32_t addr; | ||||||
|  | 	uint32_t offset; | ||||||
|  | 	uint32_t io_count; | ||||||
|  | 	uint32_t i; | ||||||
|  | 	uint32_t max_pages_per_io = ocf_volume_get_max_io_size(volume) / | ||||||
|  | 						PAGE_SIZE; | ||||||
|  | 	int err = 0; | ||||||
|  |  | ||||||
|  | 	/* Allocate data */ | ||||||
|  | 	segment_data->data = ctx_data_alloc(owner, | ||||||
|  | 			ctrl->raw_desc[segment].ssd_pages); | ||||||
|  | 	if (!segment_data->data) { | ||||||
|  | 		err = -ENOMEM; | ||||||
|  | 		goto exit; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	segment_data->entries_in_page = ctrl->raw_desc[segment].entries_in_page; | ||||||
|  |  | ||||||
|  | 	io_count = OCF_DIV_ROUND_UP(ctrl->raw_desc[segment].ssd_pages, | ||||||
|  | 			max_pages_per_io); | ||||||
|  |  | ||||||
|  | 	/* submit segment data I/O */ | ||||||
|  | 	pages_left = ctrl->raw_desc[segment].ssd_pages; | ||||||
|  | 	addr = ctrl->raw_desc[segment].ssd_pages_offset; | ||||||
|  | 	offset = 0; | ||||||
|  | 	i = 0; | ||||||
|  | 	while (pages_left) { | ||||||
|  | 		ENV_BUG_ON(i >= io_count); | ||||||
|  |  | ||||||
|  | 		pages = OCF_MIN(pages_left, max_pages_per_io); | ||||||
|  |  | ||||||
|  | 		err = ocf_metadata_query_cores_io(volume, context, | ||||||
|  | 				segment_data->data, offset, addr, pages); | ||||||
|  | 		if (err) | ||||||
|  | 			goto exit; | ||||||
|  |  | ||||||
|  | 		addr += pages; | ||||||
|  | 		offset += pages; | ||||||
|  | 		pages_left -= pages; | ||||||
|  | 		++i; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | exit: | ||||||
|  | 	return err; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ocf_metadata_hash_query_cores(ocf_ctx_t owner, ocf_volume_t volume, | ||||||
|  | 		struct ocf_volume_uuid *uuid, uint32_t count, | ||||||
|  | 		ocf_metadata_query_cores_end_t cmpl, void *priv) | ||||||
|  | { | ||||||
|  | 	struct ocf_metadata_hash_ctrl *ctrl = NULL; | ||||||
|  | 	struct query_cores_context *context; | ||||||
|  | 	int err; | ||||||
|  |  | ||||||
|  | 	if (count > OCF_CORE_MAX) { | ||||||
|  | 		cmpl(priv, -EINVAL, 0); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* intialize query context */ | ||||||
|  | 	context = env_vzalloc(sizeof(*context)); | ||||||
|  | 	if (!context) { | ||||||
|  | 		cmpl(priv, -ENOMEM, 0); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	context->ctx = owner; | ||||||
|  | 	context->params.cmpl = cmpl; | ||||||
|  | 	context->params.priv = priv; | ||||||
|  | 	context->params.uuids = uuid; | ||||||
|  | 	context->params.uuids_count = count; | ||||||
|  | 	env_atomic_set(&context->count, 1); | ||||||
|  |  | ||||||
|  | 	ctrl = ocf_metadata_hash_ctrl_init(false); | ||||||
|  | 	if (!ctrl) { | ||||||
|  | 		err = -ENOMEM; | ||||||
|  | 		goto exit; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* superblock I/O */ | ||||||
|  | 	err = ocf_metadata_query_cores_segment_io(context, owner, | ||||||
|  | 			volume, metadata_segment_sb_config, ctrl, | ||||||
|  | 			&context->data.superblock); | ||||||
|  | 	if (err) | ||||||
|  | 		goto exit; | ||||||
|  |  | ||||||
|  | 	/* core config I/O */ | ||||||
|  | 	err = ocf_metadata_query_cores_segment_io(context, owner, | ||||||
|  | 			volume, metadata_segment_core_uuid, ctrl, | ||||||
|  | 			&context->data.core_uuids); | ||||||
|  | 	if (err) | ||||||
|  | 		goto exit; | ||||||
|  |  | ||||||
|  | 	/* core uuid I/O */ | ||||||
|  | 	err = ocf_metadata_query_cores_segment_io(context, owner, | ||||||
|  | 			volume, metadata_segment_core_config, ctrl, | ||||||
|  | 			&context->data.core_config); | ||||||
|  | 	if (err) | ||||||
|  | 		goto exit; | ||||||
|  | exit: | ||||||
|  | 	env_vfree(ctrl); | ||||||
|  | 	ocf_metadata_query_cores_end(context, err); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Initialize hash metadata interface |  * Initialize hash metadata interface | ||||||
| @@ -2456,6 +2766,7 @@ static void ocf_metadata_hash_set_partition_info( | |||||||
| static const struct ocf_metadata_iface metadata_hash_iface = { | static const struct ocf_metadata_iface metadata_hash_iface = { | ||||||
| 	.init = ocf_metadata_hash_init, | 	.init = ocf_metadata_hash_init, | ||||||
| 	.deinit = ocf_metadata_hash_deinit, | 	.deinit = ocf_metadata_hash_deinit, | ||||||
|  | 	.query_cores = ocf_metadata_hash_query_cores, | ||||||
| 	.init_variable_size = ocf_metadata_hash_init_variable_size, | 	.init_variable_size = ocf_metadata_hash_init_variable_size, | ||||||
| 	.deinit_variable_size = ocf_metadata_hash_deinit_variable_size, | 	.deinit_variable_size = ocf_metadata_hash_deinit_variable_size, | ||||||
| 	.init_hash_table = ocf_metadata_hash_init_hash_table, | 	.init_hash_table = ocf_metadata_hash_init_hash_table, | ||||||
|   | |||||||
| @@ -109,8 +109,7 @@ static int _raw_ram_init(ocf_cache_t cache, | |||||||
| /* | /* | ||||||
|  * RAM Implementation - Size of |  * RAM Implementation - Size of | ||||||
|  */ |  */ | ||||||
| static size_t _raw_ram_size_of(ocf_cache_t cache, | static size_t _raw_ram_size_of(ocf_cache_t cache, struct ocf_metadata_raw *raw) | ||||||
| 		struct ocf_metadata_raw *raw) |  | ||||||
| { | { | ||||||
| 	size_t size; | 	size_t size; | ||||||
|  |  | ||||||
| @@ -123,8 +122,7 @@ static size_t _raw_ram_size_of(ocf_cache_t cache, | |||||||
| /* | /* | ||||||
|  * RAM Implementation - Size on SSD |  * RAM Implementation - Size on SSD | ||||||
|  */ |  */ | ||||||
| static uint32_t _raw_ram_size_on_ssd(ocf_cache_t cache, | static uint32_t _raw_ram_size_on_ssd(struct ocf_metadata_raw *raw) | ||||||
| 		struct ocf_metadata_raw *raw) |  | ||||||
| { | { | ||||||
| 	const size_t alignment = 128 * KiB / PAGE_SIZE; | 	const size_t alignment = 128 * KiB / PAGE_SIZE; | ||||||
|  |  | ||||||
| @@ -644,11 +642,10 @@ int ocf_metadata_raw_deinit(ocf_cache_t cache, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t ocf_metadata_raw_size_on_ssd(ocf_cache_t cache, | size_t ocf_metadata_raw_size_on_ssd(struct ocf_metadata_raw* raw) | ||||||
|                 struct ocf_metadata_raw* raw) |  | ||||||
| { | { | ||||||
| 	ENV_BUG_ON(raw->raw_type < metadata_raw_type_min); | 	ENV_BUG_ON(raw->raw_type < metadata_raw_type_min); | ||||||
| 	ENV_BUG_ON(raw->raw_type >= metadata_raw_type_max); | 	ENV_BUG_ON(raw->raw_type >= metadata_raw_type_max); | ||||||
|  |  | ||||||
| 	return IRAW[raw->raw_type].size_on_ssd(cache, raw); | 	return IRAW[raw->raw_type].size_on_ssd(raw); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -93,13 +93,11 @@ struct raw_iface { | |||||||
| 	/** | 	/** | ||||||
| 	 * @brief Return size which metadata take on cache device | 	 * @brief Return size which metadata take on cache device | ||||||
| 	 * | 	 * | ||||||
| 	 * @param cache Cache instance |  | ||||||
| 	 * @param raw RAW container of metadata | 	 * @param raw RAW container of metadata | ||||||
| 	 * | 	 * | ||||||
| 	 * @return Number of pages (4 kiB) on cache device | 	 * @return Number of pages (4 kiB) on cache device | ||||||
| 	 */ | 	 */ | ||||||
| 	uint32_t (*size_on_ssd)(ocf_cache_t cache, | 	uint32_t (*size_on_ssd)(struct ocf_metadata_raw *raw); | ||||||
| 			struct ocf_metadata_raw *raw); |  | ||||||
|  |  | ||||||
| 	uint32_t (*checksum)(ocf_cache_t cache, | 	uint32_t (*checksum)(ocf_cache_t cache, | ||||||
| 			struct ocf_metadata_raw *raw); | 			struct ocf_metadata_raw *raw); | ||||||
| @@ -175,12 +173,10 @@ static inline size_t ocf_metadata_raw_size_of(ocf_cache_t cache, | |||||||
| /** | /** | ||||||
|  * @brief Get SSD footprint |  * @brief Get SSD footprint | ||||||
|  * |  * | ||||||
|  * @param cache - Cache instance |  | ||||||
|  * @param raw - RAW descriptor |  * @param raw - RAW descriptor | ||||||
|  * @return Size on SSD |  * @return Size on SSD | ||||||
|  */ |  */ | ||||||
| size_t ocf_metadata_raw_size_on_ssd(struct ocf_cache* cache, | size_t ocf_metadata_raw_size_on_ssd(struct ocf_metadata_raw* raw); | ||||||
| 		struct ocf_metadata_raw* raw); |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Calculate metadata checksum |  * @brief Calculate metadata checksum | ||||||
|   | |||||||
| @@ -188,8 +188,7 @@ size_t raw_dynamic_size_of(ocf_cache_t cache, | |||||||
| /* | /* | ||||||
|  * RAW DYNAMIC Implementation - Size on SSD |  * RAW DYNAMIC Implementation - Size on SSD | ||||||
|  */ |  */ | ||||||
| uint32_t raw_dynamic_size_on_ssd(ocf_cache_t cache, | uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw) | ||||||
| 		struct ocf_metadata_raw *raw) |  | ||||||
| { | { | ||||||
| 	const size_t alignment = 128 * KiB / PAGE_SIZE; | 	const size_t alignment = 128 * KiB / PAGE_SIZE; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,8 +32,7 @@ size_t raw_dynamic_size_of(ocf_cache_t cache, | |||||||
| /* | /* | ||||||
|  * RAW DYNAMIC Implementation - Size on SSD |  * RAW DYNAMIC Implementation - Size on SSD | ||||||
|  */ |  */ | ||||||
| uint32_t raw_dynamic_size_on_ssd(ocf_cache_t cache, | uint32_t raw_dynamic_size_on_ssd(struct ocf_metadata_raw *raw); | ||||||
| 		struct ocf_metadata_raw *raw); |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * RAW DYNAMIC Implementation - Checksum |  * RAW DYNAMIC Implementation - Checksum | ||||||
|   | |||||||
| @@ -12,8 +12,7 @@ | |||||||
| /* | /* | ||||||
|  * RAW volatile Implementation - Size on SSD |  * RAW volatile Implementation - Size on SSD | ||||||
|  */ |  */ | ||||||
| uint32_t raw_volatile_size_on_ssd(ocf_cache_t cache, | uint32_t raw_volatile_size_on_ssd(struct ocf_metadata_raw *raw) | ||||||
| 		struct ocf_metadata_raw *raw) |  | ||||||
| { | { | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,8 +9,7 @@ | |||||||
| /* | /* | ||||||
|  * RAW volatile Implementation - Size on SSD |  * RAW volatile Implementation - Size on SSD | ||||||
|  */ |  */ | ||||||
| uint32_t raw_volatile_size_on_ssd(ocf_cache_t cache, | uint32_t raw_volatile_size_on_ssd(struct ocf_metadata_raw *raw); | ||||||
| 		struct ocf_metadata_raw *raw); |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * RAW volatile Implementation - Checksum |  * RAW volatile Implementation - Checksum | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| #include "../cleaning/cleaning.h" | #include "../cleaning/cleaning.h" | ||||||
| #include "../ocf_request.h" | #include "../ocf_request.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @file metadata_priv.h |  * @file metadata_priv.h | ||||||
|  * @brief Metadata private structures |  * @brief Metadata private structures | ||||||
| @@ -81,6 +82,16 @@ struct ocf_metadata_layout_iface { | |||||||
| 			ocf_cache_line_t phy); | 			ocf_cache_line_t phy); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Query cores completion callback | ||||||
|  |  * | ||||||
|  |  * @param priv - Caller private data | ||||||
|  |  * @param error - Operation error status | ||||||
|  |  * @param num_cores - Number of cores in metadata | ||||||
|  |  */ | ||||||
|  | typedef void (*ocf_metadata_query_cores_end_t)(void *priv, int error, | ||||||
|  | 		unsigned int num_cores); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * OCF Metadata interface |  * OCF Metadata interface | ||||||
|  */ |  */ | ||||||
| @@ -108,6 +119,20 @@ struct ocf_metadata_iface { | |||||||
| 			ocf_cache_line_size_t cache_line_size, | 			ocf_cache_line_size_t cache_line_size, | ||||||
| 			ocf_metadata_layout_t layout); | 			ocf_metadata_layout_t layout); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @brief Query metadata for added cores | ||||||
|  | 	 * | ||||||
|  | 	 * @param[in] owner - OCF context | ||||||
|  | 	 * @param[in] volume - volume to probe | ||||||
|  | 	 * @param[in,out] uuid - array of uuids | ||||||
|  | 	 * @param[in] count - size of uuid array | ||||||
|  | 	 * @param[in] cmpl - completion callback | ||||||
|  | 	 * @param[in] priv - completion private data | ||||||
|  | 	 */ | ||||||
|  | 	void (*query_cores)(ocf_ctx_t owner, ocf_volume_t volume, | ||||||
|  | 		struct ocf_volume_uuid *uuid, uint32_t count, | ||||||
|  | 		ocf_metadata_query_cores_end_t cmpl, void *priv); | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * @brief Metadata cache line location on pages interface | 	 * @brief Metadata cache line location on pages interface | ||||||
| 	 */ | 	 */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jan Musiał
					Jan Musiał