fs/btrfs/tests/extent-map-tests.c

Source file repositories/reference/linux-study-clean/fs/btrfs/tests/extent-map-tests.c

File Facts

System
Linux kernel
Corpus path
fs/btrfs/tests/extent-map-tests.c
Extension
.c
Size
29998 bytes
Lines
1203
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct extent_range {
	u64 start;
	u64 len;
};

/* The valid states of the tree after every drop, as described below. */
struct extent_range valid_ranges[][7] = {
	{
	  { .start = 0,			.len = SZ_8K },		/* [0, 8K) */
	  { .start = SZ_4K * 3,		.len = SZ_4K * 3},	/* [12k, 24k) */
	  { .start = SZ_4K * 6,		.len = SZ_4K * 3},	/* [24k, 36k) */
	  { .start = SZ_32K + SZ_4K,	.len = SZ_4K},		/* [36k, 40k) */
	  { .start = SZ_4K * 10,	.len = SZ_4K * 6},	/* [40k, 64k) */
	},
	{
	  { .start = 0,			.len = SZ_8K },		/* [0, 8K) */
	  { .start = SZ_4K * 5,		.len = SZ_4K},		/* [20k, 24k) */
	  { .start = SZ_4K * 6,		.len = SZ_4K * 3},	/* [24k, 36k) */
	  { .start = SZ_32K + SZ_4K,	.len = SZ_4K},		/* [36k, 40k) */
	  { .start = SZ_4K * 10,	.len = SZ_4K * 6},	/* [40k, 64k) */
	},
	{
	  { .start = 0,			.len = SZ_8K },		/* [0, 8K) */
	  { .start = SZ_4K * 5,		.len = SZ_4K},		/* [20k, 24k) */
	  { .start = SZ_4K * 6,		.len = SZ_4K},		/* [24k, 28k) */
	  { .start = SZ_32K,		.len = SZ_4K},		/* [32k, 36k) */
	  { .start = SZ_32K + SZ_4K,	.len = SZ_4K},		/* [36k, 40k) */
	  { .start = SZ_4K * 10,	.len = SZ_4K * 6},	/* [40k, 64k) */
	},
	{
	  { .start = 0,			.len = SZ_8K},		/* [0, 8K) */
	  { .start = SZ_4K * 5,		.len = SZ_4K},		/* [20k, 24k) */
	  { .start = SZ_4K * 6,		.len = SZ_4K},		/* [24k, 28k) */
	}
};

static int validate_range(struct extent_map_tree *em_tree, int index)
{
	struct rb_node *n;
	int i;

	for (i = 0, n = rb_first(&em_tree->root);
	     valid_ranges[index][i].len && n;
	     i++, n = rb_next(n)) {
		struct extent_map *entry = rb_entry(n, struct extent_map, rb_node);

		if (entry->start != valid_ranges[index][i].start) {
			test_err("mapping has start %llu expected %llu",
				 entry->start, valid_ranges[index][i].start);
			return -EINVAL;
		}

		if (entry->len != valid_ranges[index][i].len) {
			test_err("mapping has len %llu expected %llu",
				 entry->len, valid_ranges[index][i].len);
			return -EINVAL;
		}
	}

	/*
	 * We exited because we don't have any more entries in the extent_map
	 * but we still expect more valid entries.
	 */
	if (valid_ranges[index][i].len) {
		test_err("missing an entry");
		return -EINVAL;
	}

	/* We exited the loop but still have entries in the extent map. */
	if (n) {
		test_err("we have a left over entry in the extent map we didn't expect");
		return -EINVAL;
	}

	return 0;
}

/*
 * Test scenario:
 *
 * Test the various edge cases of btrfs_drop_extent_map_range, create the
 * following ranges
 *
 * [0, 12k)[12k, 24k)[24k, 36k)[36k, 40k)[40k,64k)
 *
 * And then we'll drop:
 *
 * [8k, 12k) - test the single front split
 * [12k, 20k) - test the single back split
 * [28k, 32k) - test the double split

Annotation

Implementation Notes