drivers/md/dm-pcache/cache_key.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-pcache/cache_key.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-pcache/cache_key.c
Extension
.c
Size
25406 bytes
Lines
890
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 (!next_seg) {
			ret = -EBUSY;
			goto out;
		}

		/* clear outdated kset in next seg */
		memcpy_flushcache(next_seg->segment.data, &pcache_empty_kset,
					sizeof(struct pcache_cache_kset_onmedia));
		append_last_kset(cache, next_seg->cache_seg_id);
		cache->key_head.cache_seg = next_seg;
		cache->key_head.seg_off = 0;
		goto again;
	}

	kset_onmedia->magic = PCACHE_KSET_MAGIC;
	kset_onmedia->crc = cache_kset_crc(kset_onmedia);

	/* clear outdated kset after current kset */
	memcpy_flushcache(get_key_head_addr(cache) + kset_onmedia_size, &pcache_empty_kset,
				sizeof(struct pcache_cache_kset_onmedia));
	/* write current kset into segment */
	memcpy_flushcache(get_key_head_addr(cache), kset_onmedia, kset_onmedia_size);
	pmem_wmb();

	/* reset kset_onmedia */
	memset(kset_onmedia, 0, sizeof(struct pcache_cache_kset_onmedia));
	cache_pos_advance(&cache->key_head, kset_onmedia_size);

	ret = 0;
out:
	spin_unlock(&cache->key_head_lock);

	return ret;
}

/**
 * cache_key_append - Append a cache key to the related kset.
 * @cache: Pointer to the pcache_cache structure.
 * @key: Pointer to the cache key structure to append.
 * @force_close: Need to close current kset if true.
 *
 * This function appends a cache key to the appropriate kset. If the kset
 * is full, it closes the kset. If not, it queues a flush work to write
 * the kset to media.
 *
 * Returns 0 on success, or a negative error code on failure.
 */
int cache_key_append(struct pcache_cache *cache, struct pcache_cache_key *key, bool force_close)
{
	struct pcache_cache_kset *kset;
	struct pcache_cache_kset_onmedia *kset_onmedia;
	struct pcache_cache_key_onmedia *key_onmedia;
	u32 kset_id = get_kset_id(cache, key->off);
	int ret = 0;

	kset = get_kset(cache, kset_id);
	kset_onmedia = &kset->kset_onmedia;

	spin_lock(&kset->kset_lock);
	key_onmedia = &kset_onmedia->data[kset_onmedia->key_num];
	cache_key_encode(cache, key_onmedia, key);

	/* Check if the current kset has reached the maximum number of keys */
	if (++kset_onmedia->key_num == PCACHE_KSET_KEYS_MAX || force_close) {
		/* If full, close the kset */
		ret = cache_kset_close(cache, kset);
		if (ret) {
			kset_onmedia->key_num--;
			goto out;
		}
	} else {
		/* If not full, queue a delayed work to flush the kset */
		queue_delayed_work(cache_get_wq(cache), &kset->flush_work, 1 * HZ);
	}
out:
	spin_unlock(&kset->kset_lock);

	return ret;
}

/**
 * cache_subtree_walk - Traverse the cache tree.
 * @ctx: Pointer to the context structure for traversal.
 *
 * This function traverses the cache tree starting from the specified node.
 * It calls the appropriate callback functions based on the relationships
 * between the keys in the cache tree.
 *
 * Returns 0 on success, or a negative error code on failure.
 */

Annotation

Implementation Notes