drivers/md/dm-flakey.c

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

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-flakey.c
Extension
.c
Size
17857 bytes
Lines
710
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 flakey_c {
	struct dm_dev *dev;
	unsigned long start_time;
	sector_t start;
	unsigned int up_interval;
	unsigned int down_interval;
	unsigned long flags;
	unsigned int corrupt_bio_byte;
	unsigned int corrupt_bio_rw;
	unsigned int corrupt_bio_value;
	blk_opf_t corrupt_bio_flags;
	unsigned int random_read_corrupt;
	unsigned int random_write_corrupt;
};

enum feature_flag_bits {
	ERROR_READS,
	DROP_WRITES,
	ERROR_WRITES
};

struct per_bio_data {
	bool bio_can_corrupt;
	struct bvec_iter saved_iter;
};

static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
			  struct dm_target *ti)
{
	int r = 0;
	unsigned int argc = 0;
	const char *arg_name;

	static const struct dm_arg _args[] = {
		{0, 11, "Invalid number of feature args"},
		{1, UINT_MAX, "Invalid corrupt bio byte"},
		{0, 255, "Invalid corrupt value to write into bio byte (0-255)"},
		{0, UINT_MAX, "Invalid corrupt bio flags mask"},
		{0, PROBABILITY_BASE, "Invalid random corrupt argument"},
	};

	if (as->argc && (r = dm_read_arg_group(_args, as, &argc, &ti->error)))
		return r;

	/* No feature arguments supplied. */
	if (!argc)
		goto error_all_io;

	while (argc) {
		arg_name = dm_shift_arg(as);
		argc--;

		if (!arg_name) {
			ti->error = "Insufficient feature arguments";
			return -EINVAL;
		}

		/*
		 * error_reads
		 */
		if (!strcasecmp(arg_name, "error_reads")) {
			if (test_and_set_bit(ERROR_READS, &fc->flags)) {
				ti->error = "Feature error_reads duplicated";
				return -EINVAL;
			}
			continue;
		}

		/*
		 * drop_writes
		 */
		if (!strcasecmp(arg_name, "drop_writes")) {
			if (test_and_set_bit(DROP_WRITES, &fc->flags)) {
				ti->error = "Feature drop_writes duplicated";
				return -EINVAL;
			} else if (test_bit(ERROR_WRITES, &fc->flags)) {
				ti->error = "Feature drop_writes conflicts with feature error_writes";
				return -EINVAL;
			}

			continue;
		}

		/*
		 * error_writes
		 */
		if (!strcasecmp(arg_name, "error_writes")) {
			if (test_and_set_bit(ERROR_WRITES, &fc->flags)) {
				ti->error = "Feature error_writes duplicated";
				return -EINVAL;

Annotation

Implementation Notes