drivers/md/raid5-ppl.c

Source file repositories/reference/linux-study-clean/drivers/md/raid5-ppl.c

File Facts

System
Linux kernel
Corpus path
drivers/md/raid5-ppl.c
Extension
.c
Size
42426 bytes
Lines
1522
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 ppl_conf {
	struct mddev *mddev;

	/* array of child logs, one for each raid disk */
	struct ppl_log *child_logs;
	int count;

	int block_size;		/* the logical block size used for data_sector
				 * in ppl_header_entry */
	u32 signature;		/* raid array identifier */
	atomic64_t seq;		/* current log write sequence number */

	struct kmem_cache *io_kc;
	mempool_t io_pool;
	struct bio_set bs;
	struct bio_set flush_bs;

	/* used only for recovery */
	int recovered_entries;
	int mismatch_count;

	/* stripes to retry if failed to allocate io_unit */
	struct list_head no_mem_stripes;
	spinlock_t no_mem_stripes_lock;

	unsigned short write_hint;
};

struct ppl_log {
	struct ppl_conf *ppl_conf;	/* shared between all log instances */

	struct md_rdev *rdev;		/* array member disk associated with
					 * this log instance */
	struct mutex io_mutex;
	struct ppl_io_unit *current_io;	/* current io_unit accepting new data
					 * always at the end of io_list */
	spinlock_t io_list_lock;
	struct list_head io_list;	/* all io_units of this log */

	sector_t next_io_sector;
	unsigned int entry_space;
	bool use_multippl;
	bool wb_cache_on;
	unsigned long disk_flush_bitmap;
};

#define PPL_IO_INLINE_BVECS 32

struct ppl_io_unit {
	struct ppl_log *log;

	struct page *header_page;	/* for ppl_header */

	unsigned int entries_count;	/* number of entries in ppl_header */
	unsigned int pp_size;		/* total size current of partial parity */

	u64 seq;			/* sequence number of this log write */
	struct list_head log_sibling;	/* log->io_list */

	struct list_head stripe_list;	/* stripes added to the io_unit */
	atomic_t pending_stripes;	/* how many stripes not written to raid */
	atomic_t pending_flushes;	/* how many disk flushes are in progress */

	bool submitted;			/* true if write to log started */

	/* inline bio and its biovec for submitting the iounit */
	struct bio bio;
	struct bio_vec biovec[PPL_IO_INLINE_BVECS];
};

struct dma_async_tx_descriptor *
ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,
		       struct dma_async_tx_descriptor *tx)
{
	int disks = sh->disks;
	struct page **srcs = percpu->scribble;
	int count = 0, pd_idx = sh->pd_idx, i;
	struct async_submit_ctl submit;

	pr_debug("%s: stripe %llu\n", __func__, (unsigned long long)sh->sector);

	/*
	 * Partial parity is the XOR of stripe data chunks that are not changed
	 * during the write request. Depending on available data
	 * (read-modify-write vs. reconstruct-write case) we calculate it
	 * differently.
	 */
	if (sh->reconstruct_state == reconstruct_state_prexor_drain_run) {
		/*
		 * rmw: xor old data and parity from updated disks

Annotation

Implementation Notes