drivers/md/dm-vdo/indexer/index.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/indexer/index.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/indexer/index.c
Extension
.c
Size
41867 bytes
Lines
1382
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct chapter_writer {
	/* The index to which we belong */
	struct uds_index *index;
	/* The thread to do the writing */
	struct thread *thread;
	/* The lock protecting the following fields */
	struct mutex mutex;
	/* The condition signalled on state changes */
	struct cond_var cond;
	/* Set to true to stop the thread */
	bool stop;
	/* The result from the most recent write */
	int result;
	/* The number of bytes allocated by the chapter writer */
	size_t memory_size;
	/* The number of zones which have submitted a chapter for writing */
	unsigned int zones_to_write;
	/* Open chapter index used by uds_close_open_chapter() */
	struct open_chapter_index *open_chapter_index;
	/* Collated records used by uds_close_open_chapter() */
	struct uds_volume_record *collated_records;
	/* The chapters to write (one per zone) */
	struct open_chapter_zone *chapters[];
};

static bool is_zone_chapter_sparse(const struct index_zone *zone, u64 virtual_chapter)
{
	return uds_is_chapter_sparse(zone->index->volume->geometry,
				     zone->oldest_virtual_chapter,
				     zone->newest_virtual_chapter, virtual_chapter);
}

static int launch_zone_message(struct uds_zone_message message, unsigned int zone,
			       struct uds_index *index)
{
	int result;
	struct uds_request *request;

	result = vdo_allocate(1, __func__, &request);
	if (result != VDO_SUCCESS)
		return result;

	request->index = index;
	request->unbatched = true;
	request->zone_number = zone;
	request->zone_message = message;

	uds_enqueue_request(request, STAGE_MESSAGE);
	return UDS_SUCCESS;
}

static void enqueue_barrier_messages(struct uds_index *index, u64 virtual_chapter)
{
	struct uds_zone_message message = {
		.type = UDS_MESSAGE_SPARSE_CACHE_BARRIER,
		.virtual_chapter = virtual_chapter,
	};
	unsigned int zone;

	for (zone = 0; zone < index->zone_count; zone++) {
		int result = launch_zone_message(message, zone, index);

		VDO_ASSERT_LOG_ONLY((result == UDS_SUCCESS), "barrier message allocation");
	}
}

/*
 * Determine whether this request should trigger a sparse cache barrier message to change the
 * membership of the sparse cache. If a change in membership is desired, the function returns the
 * chapter number to add.
 */
static u64 triage_index_request(struct uds_index *index, struct uds_request *request)
{
	u64 virtual_chapter;
	struct index_zone *zone;

	virtual_chapter = uds_lookup_volume_index_name(index->volume_index,
						       &request->record_name);
	if (virtual_chapter == NO_CHAPTER)
		return NO_CHAPTER;

	zone = index->zones[request->zone_number];
	if (!is_zone_chapter_sparse(zone, virtual_chapter))
		return NO_CHAPTER;

	/*
	 * FIXME: Optimize for a common case by remembering the chapter from the most recent
	 * barrier message and skipping this chapter if is it the same.
	 */

Annotation

Implementation Notes