lib/raid/raid6/tests/raid6_kunit.c

Source file repositories/reference/linux-study-clean/lib/raid/raid6/tests/raid6_kunit.c

File Facts

System
Linux kernel
Corpus path
lib/raid/raid6/tests/raid6_kunit.c
Extension
.c
Size
8436 bytes
Lines
322
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct test_args {
	unsigned int recov_idx;
	const struct raid6_recov_calls *recov;
	unsigned int gen_idx;
	const struct raid6_calls *gen;
};

static struct test_args args;

static u32 rand32(void)
{
	return prandom_u32_state(&rng);
}

/* Generate a random length that is a multiple of 512. */
static unsigned int random_length(unsigned int max_length)
{
	return round_up((rand32() % max_length) + 1, 512);
}

static unsigned int random_nr_buffers(void)
{
	return (rand32() % (RAID6_KUNIT_MAX_BUFFERS - (RAID6_MIN_DISKS - 1))) +
			RAID6_MIN_DISKS;
}

/* Generate a random alignment that is a multiple of 64. */
static unsigned int random_alignment(unsigned int max_alignment)
{
	if (max_alignment == 0)
		return 0;
	return (rand32() % (max_alignment + 1)) & ~63;
}

static void makedata(int start, int stop)
{
	int i;

	for (i = start; i <= stop; i++)
		prandom_bytes_state(&rng, test_buffers[i], test_buflen);
}

static char member_type(unsigned int nr_buffers, int d)
{
	if (d == nr_buffers - 2)
		return 'P';
	if (d == nr_buffers - 1)
		return 'Q';
	return 'D';
}

static void test_recover_one(struct kunit *test, unsigned int nr_buffers,
		unsigned int len, int faila, int failb)
{
	const struct test_args *ta = test->param_value;
	void *dataptrs[RAID6_KUNIT_MAX_BUFFERS];
	int i;

	if (faila > failb)
		swap(faila, failb);

	for (i = 0; i < RAID6_KUNIT_MAX_FAILURES; i++)
		memset(test_recov_buffers[i], 0xf0, test_buflen);

	memcpy(dataptrs, aligned_buffers, sizeof(dataptrs));
	dataptrs[faila] = test_recov_buffers[0];
	dataptrs[failb] = test_recov_buffers[1];

	if (failb == nr_buffers - 1) {
		/*
		 * We don't implement the data+Q failure scenario, since it
		 * is equivalent to a RAID-5 failure (XOR, then recompute Q).
		 */
		if (WARN_ON_ONCE(faila != nr_buffers - 2))
			return;

		/* P+Q failure.  Just rebuild the syndrome. */
		ta->gen->gen_syndrome(nr_buffers, len, dataptrs);
	} else if (failb == nr_buffers - 2) {
		/* data+P failure. */
		ta->recov->datap(nr_buffers, len, faila, dataptrs);
	} else {
		/* data+data failure. */
		ta->recov->data2(nr_buffers, len, faila, failb, dataptrs);
	}

	KUNIT_EXPECT_MEMEQ_MSG(test, aligned_buffers[faila], dataptrs[faila],
			len,
			"faila miscompared: %3d[%c] buffers %u len %u (failb=%3d[%c])\n",
			faila, member_type(nr_buffers, faila),

Annotation

Implementation Notes