drivers/md/dm-log-writes.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-log-writes.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-log-writes.c
Extension
.c
Size
24515 bytes
Lines
948
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 log_write_super {
	__le64 magic;
	__le64 version;
	__le64 nr_entries;
	__le32 sectorsize;
};

/*
 * sector - the sector we wrote.
 * nr_sectors - the number of sectors we wrote.
 * flags - flags for this log entry.
 * data_len - the size of the data in this log entry, this is for private log
 * entry stuff, the MARK data provided by userspace for example.
 */
struct log_write_entry {
	__le64 sector;
	__le64 nr_sectors;
	__le64 flags;
	__le64 data_len;
};

struct log_writes_c {
	struct dm_dev *dev;
	struct dm_dev *logdev;
	u64 logged_entries;
	u32 sectorsize;
	u32 sectorshift;
	atomic_t io_blocks;
	atomic_t pending_blocks;
	sector_t next_sector;
	sector_t end_sector;
	bool logging_enabled;
	bool device_supports_discard;
	spinlock_t blocks_lock;
	struct list_head unflushed_blocks;
	struct list_head logging_blocks;
	wait_queue_head_t wait;
	struct task_struct *log_kthread;
	struct completion super_done;
};

struct pending_block {
	int vec_cnt;
	u64 flags;
	sector_t sector;
	sector_t nr_sectors;
	char *data;
	u32 datalen;
	struct list_head list;
	struct bio_vec vecs[];
};

struct per_bio_data {
	struct pending_block *block;
};

static inline sector_t bio_to_dev_sectors(struct log_writes_c *lc,
					  sector_t sectors)
{
	return sectors >> (lc->sectorshift - SECTOR_SHIFT);
}

static inline sector_t dev_to_bio_sectors(struct log_writes_c *lc,
					  sector_t sectors)
{
	return sectors << (lc->sectorshift - SECTOR_SHIFT);
}

static void put_pending_block(struct log_writes_c *lc)
{
	if (atomic_dec_and_test(&lc->pending_blocks)) {
		smp_mb__after_atomic();
		if (waitqueue_active(&lc->wait))
			wake_up(&lc->wait);
	}
}

static void put_io_block(struct log_writes_c *lc)
{
	if (atomic_dec_and_test(&lc->io_blocks)) {
		smp_mb__after_atomic();
		if (waitqueue_active(&lc->wait))
			wake_up(&lc->wait);
	}
}

static void log_end_io(struct bio *bio)
{
	struct log_writes_c *lc = bio->bi_private;

Annotation

Implementation Notes