drivers/md/persistent-data/dm-transaction-manager.c

Source file repositories/reference/linux-study-clean/drivers/md/persistent-data/dm-transaction-manager.c

File Facts

System
Linux kernel
Corpus path
drivers/md/persistent-data/dm-transaction-manager.c
Extension
.c
Size
11449 bytes
Lines
542
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 prefetch_set {
	struct mutex lock;
	dm_block_t blocks[PREFETCH_SIZE];
};

static unsigned int prefetch_hash(dm_block_t b)
{
	return hash_64(b, PREFETCH_BITS);
}

static void prefetch_wipe(struct prefetch_set *p)
{
	unsigned int i;

	for (i = 0; i < PREFETCH_SIZE; i++)
		p->blocks[i] = PREFETCH_SENTINEL;
}

static void prefetch_init(struct prefetch_set *p)
{
	mutex_init(&p->lock);
	prefetch_wipe(p);
}

static void prefetch_add(struct prefetch_set *p, dm_block_t b)
{
	unsigned int h = prefetch_hash(b);

	mutex_lock(&p->lock);
	if (p->blocks[h] == PREFETCH_SENTINEL)
		p->blocks[h] = b;

	mutex_unlock(&p->lock);
}

static void prefetch_issue(struct prefetch_set *p, struct dm_block_manager *bm)
{
	unsigned int i;

	mutex_lock(&p->lock);

	for (i = 0; i < PREFETCH_SIZE; i++)
		if (p->blocks[i] != PREFETCH_SENTINEL) {
			dm_bm_prefetch(bm, p->blocks[i]);
			p->blocks[i] = PREFETCH_SENTINEL;
		}

	mutex_unlock(&p->lock);
}

/*----------------------------------------------------------------*/

struct shadow_info {
	struct rb_node node;
	dm_block_t where;
};

/*
 * It would be nice if we scaled with the size of transaction.
 */
#define DM_HASH_SIZE 256
#define DM_HASH_MASK (DM_HASH_SIZE - 1)

struct dm_transaction_manager {
	int is_clone;
	struct dm_transaction_manager *real;

	struct dm_block_manager *bm;
	struct dm_space_map *sm;

	spinlock_t lock;
	struct rb_root buckets[DM_HASH_SIZE];

	struct prefetch_set prefetches;
};

/*----------------------------------------------------------------*/

static int is_shadow(struct dm_transaction_manager *tm, dm_block_t b)
{
	int r = 0;
	unsigned int bucket = dm_hash_block(b, DM_HASH_MASK);
	struct rb_node **node;

	spin_lock(&tm->lock);
	node = &tm->buckets[bucket].rb_node;
	while (*node) {
		struct shadow_info *si =
			rb_entry(*node, struct shadow_info, node);
		if (b == si->where) {

Annotation

Implementation Notes