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

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

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/indexer/volume.c
Extension
.c
Size
54928 bytes
Lines
1692
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

if (last_used <= oldest_time) {
			oldest_time = last_used;
			oldest_index = i;
		}
	}

	page = &cache->cache[oldest_index];
	if (page->physical_page != cache->indexable_pages) {
		WRITE_ONCE(cache->index[page->physical_page], cache->cache_slots);
		wait_for_pending_searches(cache, page->physical_page);
	}

	page->read_pending = true;
	clear_cache_page(cache, page);
	return page;
}

/* Make a newly filled cache entry available to other threads. */
static int put_page_in_cache(struct page_cache *cache, u32 physical_page,
			     struct cached_page *page)
{
	int result;

	/* We hold the read_threads_mutex. */
	result = VDO_ASSERT((page->read_pending), "page to install has a pending read");
	if (result != VDO_SUCCESS)
		return result;

	page->physical_page = physical_page;
	make_page_most_recent(cache, page);
	page->read_pending = false;

	/*
	 * We hold the read_threads_mutex, but we must have a write memory barrier before making
	 * the cached_page available to the readers that do not hold the mutex. The corresponding
	 * read memory barrier is in get_page_and_index().
	 */
	smp_wmb();

	/* This assignment also clears the queued flag. */
	WRITE_ONCE(cache->index[physical_page], page - cache->cache);
	return UDS_SUCCESS;
}

static void cancel_page_in_cache(struct page_cache *cache, u32 physical_page,
				 struct cached_page *page)
{
	int result;

	/* We hold the read_threads_mutex. */
	result = VDO_ASSERT((page->read_pending), "page to install has a pending read");
	if (result != VDO_SUCCESS)
		return;

	clear_cache_page(cache, page);
	page->read_pending = false;

	/* Clear the mapping and the queued flag for the new page. */
	WRITE_ONCE(cache->index[physical_page], cache->cache_slots);
}

static inline u16 next_queue_position(u16 position)
{
	return (position + 1) % VOLUME_CACHE_MAX_QUEUED_READS;
}

static inline void advance_queue_position(u16 *position)
{
	*position = next_queue_position(*position);
}

static inline bool read_queue_is_full(struct page_cache *cache)
{
	return cache->read_queue_first == next_queue_position(cache->read_queue_last);
}

static bool enqueue_read(struct page_cache *cache, struct uds_request *request,
			 u32 physical_page)
{
	struct queued_read *queue_entry;
	u16 last = cache->read_queue_last;
	u16 read_queue_index;

	/* We hold the read_threads_mutex. */
	if ((cache->index[physical_page] & VOLUME_CACHE_QUEUED_FLAG) == 0) {
		/* This page has no existing entry in the queue. */
		if (read_queue_is_full(cache))
			return false;

		/* Fill in the read queue entry. */

Annotation

Implementation Notes