drivers/md/persistent-data/dm-space-map-common.c

Source file repositories/reference/linux-study-clean/drivers/md/persistent-data/dm-space-map-common.c

File Facts

System
Linux kernel
Corpus path
drivers/md/persistent-data/dm-space-map-common.c
Extension
.c
Size
28195 bytes
Lines
1266
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 inc_context {
	struct disk_index_entry ie_disk;
	struct dm_block *bitmap_block;
	void *bitmap;

	struct dm_block *overflow_leaf;
};

static inline void init_inc_context(struct inc_context *ic)
{
	ic->bitmap_block = NULL;
	ic->bitmap = NULL;
	ic->overflow_leaf = NULL;
}

static inline void exit_inc_context(struct ll_disk *ll, struct inc_context *ic)
{
	if (ic->bitmap_block)
		dm_tm_unlock(ll->tm, ic->bitmap_block);
	if (ic->overflow_leaf)
		dm_tm_unlock(ll->tm, ic->overflow_leaf);
}

static inline void reset_inc_context(struct ll_disk *ll, struct inc_context *ic)
{
	exit_inc_context(ll, ic);
	init_inc_context(ic);
}

/*
 * Confirms a btree node contains a particular key at an index.
 */
static bool contains_key(struct btree_node *n, uint64_t key, int index)
{
	return index >= 0 &&
		index < le32_to_cpu(n->header.nr_entries) &&
		le64_to_cpu(n->keys[index]) == key;
}

static int __sm_ll_inc_overflow(struct ll_disk *ll, dm_block_t b, struct inc_context *ic)
{
	int r;
	int index;
	struct btree_node *n;
	__le32 *v_ptr;
	uint32_t rc;

	/*
	 * bitmap_block needs to be unlocked because getting the
	 * overflow_leaf may need to allocate, and thus use the space map.
	 */
	reset_inc_context(ll, ic);

	r = btree_get_overwrite_leaf(&ll->ref_count_info, ll->ref_count_root,
				     b, &index, &ll->ref_count_root, &ic->overflow_leaf);
	if (r < 0)
		return r;

	n = dm_block_data(ic->overflow_leaf);

	if (!contains_key(n, b, index)) {
		DMERR("overflow btree is missing an entry");
		return -EINVAL;
	}

	v_ptr = value_ptr(n, index);
	rc = le32_to_cpu(*v_ptr) + 1;
	*v_ptr = cpu_to_le32(rc);

	return 0;
}

static int sm_ll_inc_overflow(struct ll_disk *ll, dm_block_t b, struct inc_context *ic)
{
	int index;
	struct btree_node *n;
	__le32 *v_ptr;
	uint32_t rc;

	/*
	 * Do we already have the correct overflow leaf?
	 */
	if (ic->overflow_leaf) {
		n = dm_block_data(ic->overflow_leaf);
		index = lower_bound(n, b);
		if (contains_key(n, b, index)) {
			v_ptr = value_ptr(n, index);
			rc = le32_to_cpu(*v_ptr) + 1;
			*v_ptr = cpu_to_le32(rc);

Annotation

Implementation Notes