// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2013 Fusion IO.  All rights reserved.
 */

#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sizes.h>
#include "btrfs-tests.h"
#include "../ctree.h"
#include "../extent_io.h"
#include "../disk-io.h"
#include "../btrfs_inode.h"

#define PROCESS_UNLOCK		(1U << 0)
#define PROCESS_RELEASE		(1U << 1)
#define PROCESS_TEST_LOCKED	(1U << 2)

static noinline int process_page_range(struct inode *inode, u64 start, u64 end,
				       unsigned long flags)
{
	int ret;
	struct folio_batch fbatch;
	pgoff_t index = start >> PAGE_SHIFT;
	pgoff_t end_index = end >> PAGE_SHIFT;
	int i;
	int count = 0;
	int loops = 0;

	folio_batch_init(&fbatch);

	while (index <= end_index) {
		ret = filemap_get_folios_contig(inode->i_mapping, &index,
				end_index, &fbatch);
		for (i = 0; i < ret; i++) {
			struct folio *folio = fbatch.folios[i];

			if (flags & PROCESS_TEST_LOCKED &&
			    !folio_test_locked(folio))
				count++;
			if (flags & PROCESS_UNLOCK && folio_test_locked(folio))
				folio_unlock(folio);
			if (flags & PROCESS_RELEASE)
				folio_put(folio);
		}
		folio_batch_release(&fbatch);
		cond_resched();
		loops++;
		if (loops > 100000) {
			printk(KERN_ERR
		"stuck in a loop, start %llu, end %llu, ret %d\n",
				start, end, ret);
			break;
		}
	}

	return count;
}

#define STATE_FLAG_STR_LEN			256

#define PRINT_ONE_FLAG(state, dest, cur, name)				\
({									\
	if (state->state & EXTENT_##name)				\
		cur += scnprintf(dest + cur, STATE_FLAG_STR_LEN - cur,	\
				 "%s" #name, cur == 0 ? "" : "|");	\
})

static void extent_flag_to_str(const struct extent_state *state, char *dest)
{
	int cur = 0;

	dest[0] = 0;
	PRINT_ONE_FLAG(state, dest, cur, DIRTY);
	PRINT_ONE_FLAG(state, dest, cur, LOCKED);
	PRINT_ONE_FLAG(state, dest, cur, DIRTY_LOG1);
	PRINT_ONE_FLAG(state, dest, cur, DIRTY_LOG2);
	PRINT_ONE_FLAG(state, dest, cur, DELALLOC);
	PRINT_ONE_FLAG(state, dest, cur, DEFRAG);
	PRINT_ONE_FLAG(state, dest, cur, BOUNDARY);
	PRINT_ONE_FLAG(state, dest, cur, NODATASUM);
	PRINT_ONE_FLAG(state, dest, cur, CLEAR_META_RESV);
	PRINT_ONE_FLAG(state, dest, cur, NEED_WAIT);
	PRINT_ONE_FLAG(state, dest, cur, NORESERVE);
	PRINT_ONE_FLAG(state, dest, cur, QGROUP_RESERVED);
	PRINT_ONE_FLAG(state, dest, cur, CLEAR_DATA_RESV);
}

static void dump_extent_io_tree(const struct extent_io_tree *tree)
{
	struct rb_node *node;
	char flags_str[STATE_FLAG_STR_LEN];

	node = rb_first(&tree->state);
	test_msg("io tree content:");
	while (node) {
		struct extent_state *state;

		state = rb_entry(node, struct extent_state, rb_node);
		extent_flag_to_str(state, flags_str);
		test_msg("  start=%llu len=%llu flags=%s", state->start,
			 state->end + 1 - state->start, flags_str);
		node = rb_next(node);
	}
}

static int test_find_delalloc(u32 sectorsize, u32 nodesize)
{
	struct btrfs_fs_info *fs_info;
	struct btrfs_root *root = NULL;
	struct inode *inode = NULL;
	struct extent_io_tree *tmp;
	struct page *page;
	struct page *locked_page = NULL;
	/* In this test we need at least 2 file extents at its maximum size */
	u64 max_bytes = BTRFS_MAX_EXTENT_SIZE;
	u64 total_dirty = 2 * max_bytes;
	u64 start, end, test_start;
	bool found;
	int ret = -EINVAL;

	test_msg("running find delalloc tests");

	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
	if (!fs_info) {
		test_std_err(TEST_ALLOC_FS_INFO);
		return -ENOMEM;
	}

	root = btrfs_alloc_dummy_root(fs_info);
	if (IS_ERR(root)) {
		test_std_err(TEST_ALLOC_ROOT);
		ret = PTR_ERR(root);
		goto out;
	}

	inode = btrfs_new_test_inode();
	if (!inode) {
		test_std_err(TEST_ALLOC_INODE);
		ret = -ENOMEM;
		goto out;
	}
	tmp = &BTRFS_I(inode)->io_tree;
	BTRFS_I(inode)->root = root;

	/*
	 * Passing NULL as we don't have fs_info but tracepoints are not used
	 * at this point
	 */
	btrfs_extent_io_tree_init(NULL, tmp, IO_TREE_SELFTEST);

	/*
	 * First go through and create and mark all of our pages dirty, we pin
	 * everything to make sure our pages don't get evicted and screw up our
	 * test.
	 */
	for (pgoff_t index = 0; index < (total_dirty >> PAGE_SHIFT); index++) {
		page = find_or_create_page(inode->i_mapping, index, GFP_KERNEL);
		if (!page) {
			test_err("failed to allocate test page");
			ret = -ENOMEM;
			goto out;
		}
		SetPageDirty(page);
		if (index) {
			unlock_page(page);
		} else {
			get_page(page);
			locked_page = page;
		}
	}

	/* Test this scenario
	 * |--- delalloc ---|
	 * |---  search  ---|
	 */
	btrfs_set_extent_bit(tmp, 0, sectorsize - 1, EXTENT_DELALLOC, NULL);
	start = 0;
	end = start + PAGE_SIZE - 1;
	found = find_lock_delalloc_range(inode, page_folio(locked_page), &start,
					 &end);
	if (!found) {
		test_err("should have found at least one delalloc");
		goto out_bits;
	}
	if (start != 0 || end != (sectorsize - 1)) {
		test_err("expected start 0 end %u, got start %llu end %llu",
			sectorsize - 1, start, end);
		goto out_bits;
	}
	btrfs_unlock_extent(tmp, start, end, NULL);
	unlock_page(locked_page);
	put_page(locked_page);

	/*
	 * Test this scenario
	 *
	 * |--- delalloc ---|
	 *           |--- search ---|
	 */
	test_start = SZ_64M;
	locked_page = find_lock_page(inode->i_mapping,
				     test_start >> PAGE_SHIFT);
	if (!locked_page) {
		test_err("couldn't find the locked page");
		goto out_bits;
	}
	btrfs_set_extent_bit(tmp, sectorsize, max_bytes - 1, EXTENT_DELALLOC, NULL);
	start = test_start;
	end = start + PAGE_SIZE - 1;
	found = find_lock_delalloc_range(inode, page_folio(locked_page), &start,
					 &end);
	if (!found) {
		test_err("couldn't find delalloc in our range");
		goto out_bits;
	}
	if (start != test_start || end != max_bytes - 1) {
		test_err("expected start %llu end %llu, got start %llu, end %llu",
				test_start, max_bytes - 1, start, end);
		goto out_bits;
	}
	if (process_page_range(inode, start, end,
			       PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
		test_err("there were unlocked pages in the range");
		goto out_bits;
	}
	btrfs_unlock_extent(tmp, start, end, NULL);
	/* locked_page was unlocked above */
	put_page(locked_page);

	/*
	 * Test this scenario
	 * |--- delalloc ---|
	 *                    |--- search ---|
	 */
	test_start = max_bytes + sectorsize;
	locked_page = find_lock_page(inode->i_mapping, test_start >>
				     PAGE_SHIFT);
	if (!locked_page) {
		test_err("couldn't find the locked page");
		goto out_bits;
	}
	start = test_start;
	end = start + PAGE_SIZE - 1;
	found = find_lock_delalloc_range(inode, page_folio(locked_page), &start,
					 &end);
	if (found) {
		test_err("found range when we shouldn't have");
		goto out_bits;
	}
	if (end != test_start + PAGE_SIZE - 1) {
		test_err("did not return the proper end offset");
		goto out_bits;
	}

	/*
	 * Test this scenario
	 * [------- delalloc -------|
	 * [max_bytes]|-- search--|
	 *
	 * We are re-using our test_start from above since it works out well.
	 */
	btrfs_set_extent_bit(tmp, max_bytes, total_dirty - 1, EXTENT_DELALLOC, NULL);
	start = test_start;
	end = start + PAGE_SIZE - 1;
	found = find_lock_delalloc_range(inode, page_folio(locked_page), &start,
					 &end);
	if (!found) {
		test_err("didn't find our range");
		goto out_bits;
	}
	if (start != test_start || end != total_dirty - 1) {
		test_err("expected start %llu end %llu, got start %llu end %llu",
			 test_start, total_dirty - 1, start, end);
		goto out_bits;
	}
	if (process_page_range(inode, start, end,
			       PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
		test_err("pages in range were not all locked");
		goto out_bits;
	}
	btrfs_unlock_extent(tmp, start, end, NULL);

	/*
	 * Now to test where we run into a page that is no longer dirty in the
	 * range we want to find.
	 */
	page = find_get_page(inode->i_mapping,
			     (max_bytes + SZ_1M) >> PAGE_SHIFT);
	if (!page) {
		test_err("couldn't find our page");
		goto out_bits;
	}
	ClearPageDirty(page);
	put_page(page);

	/* We unlocked it in the previous test */
	lock_page(locked_page);
	start = test_start;
	end = start + PAGE_SIZE - 1;
	/*
	 * Currently if we fail to find dirty pages in the delalloc range we
	 * will adjust max_bytes down to PAGE_SIZE and then re-search.  If
	 * this changes at any point in the future we will need to fix this
	 * tests expected behavior.
	 */
	found = find_lock_delalloc_range(inode, page_folio(locked_page), &start,
					 &end);
	if (!found) {
		test_err("didn't find our range");
		goto out_bits;
	}
	if (start != test_start && end != test_start + PAGE_SIZE - 1) {
		test_err("expected start %llu end %llu, got start %llu end %llu",
			 test_start, test_start + PAGE_SIZE - 1, start, end);
		goto out_bits;
	}
	if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED |
			       PROCESS_UNLOCK)) {
		test_err("pages in range were not all locked");
		goto out_bits;
	}
	ret = 0;
out_bits:
	if (ret)
		dump_extent_io_tree(tmp);
	btrfs_clear_extent_bit(tmp, 0, total_dirty - 1, (unsigned)-1, NULL);
out:
	if (locked_page)
		put_page(locked_page);
	process_page_range(inode, 0, total_dirty - 1,
			   PROCESS_UNLOCK | PROCESS_RELEASE);
	iput(inode);
	btrfs_free_dummy_root(root);
	btrfs_free_dummy_fs_info(fs_info);
	return ret;
}

static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb)
{
	unsigned long i;

	for (i = 0; i < eb->len * BITS_PER_BYTE; i++) {
		bool bit_set, bit1_set;

		bit_set = test_bit(i, bitmap);
		bit1_set = extent_buffer_test_bit(eb, 0, i);
		if (bit1_set != bit_set) {
			u8 has;
			u8 expect;

			read_extent_buffer(eb, &has, i / BITS_PER_BYTE, 1);
			expect = bitmap_get_value8(bitmap, ALIGN(i, BITS_PER_BYTE));

			test_err(
		"bits do not match, start byte 0 bit %lu, byte %lu has 0x%02x expect 0x%02x",
				 i, i / BITS_PER_BYTE, has, expect);
			return -EINVAL;
		}

		bit1_set = extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
						  i % BITS_PER_BYTE);
		if (bit1_set != bit_set) {
			u8 has;
			u8 expect;

			read_extent_buffer(eb, &has, i / BITS_PER_BYTE, 1);
			expect = bitmap_get_value8(bitmap, ALIGN(i, BITS_PER_BYTE));

			test_err(
		"bits do not match, start byte %lu bit %lu, byte %lu has 0x%02x expect 0x%02x",
				 i / BITS_PER_BYTE, i % BITS_PER_BYTE,
				 i / BITS_PER_BYTE, has, expect);
			return -EINVAL;
		}
	}
	return 0;
}

static int test_bitmap_set(const char *name, unsigned long *bitmap,
			   struct extent_buffer *eb,
			   unsigned long byte_start, unsigned long bit_start,
			   unsigned long bit_len)
{
	int ret;

	bitmap_set(bitmap, byte_start * BITS_PER_BYTE + bit_start, bit_len);
	extent_buffer_bitmap_set(eb, byte_start, bit_start, bit_len);
	ret = check_eb_bitmap(bitmap, eb);
	if (ret < 0)
		test_err("%s test failed", name);
	return ret;
}

static int test_bitmap_clear(const char *name, unsigned long *bitmap,
			     struct extent_buffer *eb,
			     unsigned long byte_start, unsigned long bit_start,
			     unsigned long bit_len)
{
	int ret;

	bitmap_clear(bitmap, byte_start * BITS_PER_BYTE + bit_start, bit_len);
	extent_buffer_bitmap_clear(eb, byte_start, bit_start, bit_len);
	ret = check_eb_bitmap(bitmap, eb);
	if (ret < 0)
		test_err("%s test failed", name);
	return ret;
}
static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb)
{
	unsigned long i, j;
	unsigned long byte_len = eb->len;
	u32 x;
	int ret;

	ret = test_bitmap_clear("clear all run 1", bitmap, eb, 0, 0,
				byte_len * BITS_PER_BYTE);
	if (ret < 0)
		return ret;

	ret = test_bitmap_set("set all", bitmap, eb, 0, 0, byte_len * BITS_PER_BYTE);
	if (ret < 0)
		return ret;

	ret = test_bitmap_clear("clear all run 2", bitmap, eb, 0, 0,
				byte_len * BITS_PER_BYTE);
	if (ret < 0)
		return ret;

	ret = test_bitmap_set("same byte set", bitmap, eb, 0, 2, 4);
	if (ret < 0)
		return ret;

	ret = test_bitmap_clear("same byte partial clear", bitmap, eb, 0, 4, 1);
	if (ret < 0)
		return ret;

	ret = test_bitmap_set("cross byte set", bitmap, eb, 2, 4, 8);
	if (ret < 0)
		return ret;

	ret = test_bitmap_set("cross multi byte set", bitmap, eb, 4, 4, 24);
	if (ret < 0)
		return ret;

	ret = test_bitmap_clear("cross byte clear", bitmap, eb, 2, 6, 4);
	if (ret < 0)
		return ret;

	ret = test_bitmap_clear("cross multi byte clear", bitmap, eb, 4, 6, 20);
	if (ret < 0)
		return ret;

	/* Straddling pages test */
	if (byte_len > PAGE_SIZE) {
		ret = test_bitmap_set("cross page set", bitmap, eb,
				      PAGE_SIZE - sizeof(long) / 2, 0,
				      sizeof(long) * BITS_PER_BYTE);
		if (ret < 0)
			return ret;

		ret = test_bitmap_set("cross page set all", bitmap, eb, 0, 0,
				      byte_len * BITS_PER_BYTE);
		if (ret < 0)
			return ret;

		ret = test_bitmap_clear("cross page clear", bitmap, eb,
					PAGE_SIZE - sizeof(long) / 2, 0,
					sizeof(long) * BITS_PER_BYTE);
		if (ret < 0)
			return ret;
	}

	/*
	 * Generate a wonky pseudo-random bit pattern for the sake of not using
	 * something repetitive that could miss some hypothetical off-by-n bug.
	 */
	x = 0;
	ret = test_bitmap_clear("clear all run 3", bitmap, eb, 0, 0,
				byte_len * BITS_PER_BYTE);
	if (ret < 0)
		return ret;

	for (i = 0; i < byte_len * BITS_PER_BYTE / 32; i++) {
		x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffU;
		for (j = 0; j < 32; j++) {
			if (x & (1U << j)) {
				bitmap_set(bitmap, i * 32 + j, 1);
				extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
			}
		}
	}

	ret = check_eb_bitmap(bitmap, eb);
	if (ret) {
		test_err("random bit pattern failed");
		return ret;
	}

	return 0;
}

static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
{
	struct btrfs_fs_info *fs_info;
	unsigned long AUTO_KFREE(bitmap);
	struct extent_buffer *eb = NULL;
	int ret;

	test_msg("running extent buffer bitmap tests");

	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
	if (!fs_info) {
		test_std_err(TEST_ALLOC_FS_INFO);
		return -ENOMEM;
	}

	bitmap = kmalloc(nodesize, GFP_KERNEL);
	if (!bitmap) {
		test_err("couldn't allocate test bitmap");
		ret = -ENOMEM;
		goto out;
	}

	eb = alloc_dummy_extent_buffer(fs_info, 0);
	if (!eb) {
		test_std_err(TEST_ALLOC_ROOT);
		ret = -ENOMEM;
		goto out;
	}

	ret = __test_eb_bitmaps(bitmap, eb);
	if (ret)
		goto out;

	free_extent_buffer(eb);

	/*
	 * Test again for case where the tree block is sectorsize aligned but
	 * not nodesize aligned.
	 */
	eb = alloc_dummy_extent_buffer(fs_info, sectorsize);
	if (!eb) {
		test_std_err(TEST_ALLOC_ROOT);
		ret = -ENOMEM;
		goto out;
	}

	ret = __test_eb_bitmaps(bitmap, eb);
out:
	free_extent_buffer(eb);
	btrfs_free_dummy_fs_info(fs_info);
	return ret;
}

static int test_find_first_clear_extent_bit(void)
{
	struct extent_io_tree tree;
	u64 start, end;
	int ret = -EINVAL;

	test_msg("running find_first_clear_extent_bit test");

	btrfs_extent_io_tree_init(NULL, &tree, IO_TREE_SELFTEST);

	/* Test correct handling of empty tree */
	btrfs_find_first_clear_extent_bit(&tree, 0, &start, &end, CHUNK_TRIMMED);
	if (start != 0 || end != -1) {
		test_err(
	"error getting a range from completely empty tree: start %llu end %llu",
			 start, end);
		goto out;
	}
	/*
	 * Set 1M-4M alloc/discard and 32M-64M thus leaving a hole between
	 * 4M-32M
	 */
	btrfs_set_extent_bit(&tree, SZ_1M, SZ_4M - 1,
			     CHUNK_TRIMMED | CHUNK_ALLOCATED, NULL);

	btrfs_find_first_clear_extent_bit(&tree, SZ_512K, &start, &end,
					  CHUNK_TRIMMED | CHUNK_ALLOCATED);

	if (start != 0 || end != SZ_1M - 1) {
		test_err("error finding beginning range: start %llu end %llu",
			 start, end);
		goto out;
	}

	/* Now add 32M-64M so that we have a hole between 4M-32M */
	btrfs_set_extent_bit(&tree, SZ_32M, SZ_64M - 1,
			     CHUNK_TRIMMED | CHUNK_ALLOCATED, NULL);

	/*
	 * Request first hole starting at 12M, we should get 4M-32M
	 */
	btrfs_find_first_clear_extent_bit(&tree, 12 * SZ_1M, &start, &end,
					  CHUNK_TRIMMED | CHUNK_ALLOCATED);

	if (start != SZ_4M || end != SZ_32M - 1) {
		test_err("error finding trimmed range: start %llu end %llu",
			 start, end);
		goto out;
	}

	/*
	 * Search in the middle of allocated range, should get the next one
	 * available, which happens to be unallocated -> 4M-32M
	 */
	btrfs_find_first_clear_extent_bit(&tree, SZ_2M, &start, &end,
					  CHUNK_TRIMMED | CHUNK_ALLOCATED);

	if (start != SZ_4M || end != SZ_32M - 1) {
		test_err("error finding next unalloc range: start %llu end %llu",
			 start, end);
		goto out;
	}

	/*
	 * Set 64M-72M with CHUNK_ALLOC flag, then search for CHUNK_TRIMMED flag
	 * being unset in this range, we should get the entry in range 64M-72M
	 */
	btrfs_set_extent_bit(&tree, SZ_64M, SZ_64M + SZ_8M - 1, CHUNK_ALLOCATED, NULL);
	btrfs_find_first_clear_extent_bit(&tree, SZ_64M + SZ_1M, &start, &end,
					  CHUNK_TRIMMED);

	if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
		test_err("error finding exact range: start %llu end %llu",
			 start, end);
		goto out;
	}

	btrfs_find_first_clear_extent_bit(&tree, SZ_64M - SZ_8M, &start, &end,
					  CHUNK_TRIMMED);

	/*
	 * Search in the middle of set range whose immediate neighbour doesn't
	 * have the bits set so it must be returned
	 */
	if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
		test_err("error finding next alloc range: start %llu end %llu",
			 start, end);
		goto out;
	}

	/*
	 * Search beyond any known range, shall return after last known range
	 * and end should be -1
	 */
	btrfs_find_first_clear_extent_bit(&tree, -1, &start, &end, CHUNK_TRIMMED);
	if (start != SZ_64M + SZ_8M || end != -1) {
		test_err(
		"error handling beyond end of range search: start %llu end %llu",
			start, end);
		goto out;
	}

	ret = 0;
out:
	if (ret)
		dump_extent_io_tree(&tree);
	btrfs_clear_extent_bit(&tree, 0, (u64)-1, CHUNK_TRIMMED | CHUNK_ALLOCATED, NULL);

	return ret;
}

static void dump_eb_and_memory_contents(struct extent_buffer *eb, void *memory,
					const char *test_name)
{
	for (int i = 0; i < eb->len; i++) {
		struct page *page = folio_page(eb->folios[i >> PAGE_SHIFT], 0);
		void *addr = page_address(page) + offset_in_page(i);

		if (memcmp(addr, memory + i, 1) != 0) {
			test_err("%s failed", test_name);
			test_err("eb and memory diffs at byte %u, eb has 0x%02x memory has 0x%02x",
				 i, *(u8 *)addr, *(u8 *)(memory + i));
			return;
		}
	}
}

static int verify_eb_and_memory(struct extent_buffer *eb, void *memory,
				const char *test_name)
{
	for (int i = 0; i < (eb->len >> PAGE_SHIFT); i++) {
		void *eb_addr = folio_address(eb->folios[i]);

		if (memcmp(memory + (i << PAGE_SHIFT), eb_addr, PAGE_SIZE) != 0) {
			dump_eb_and_memory_contents(eb, memory, test_name);
			return -EUCLEAN;
		}
	}
	return 0;
}

/*
 * Init both memory and extent buffer contents to the same randomly generated
 * contents.
 */
static void init_eb_and_memory(struct extent_buffer *eb, void *memory)
{
	get_random_bytes(memory, eb->len);
	write_extent_buffer(eb, memory, 0, eb->len);
}

static int test_eb_mem_ops(u32 sectorsize, u32 nodesize)
{
	struct btrfs_fs_info *fs_info;
	struct extent_buffer *eb = NULL;
	void *memory = NULL;
	int ret;

	test_msg("running extent buffer memory operation tests");

	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
	if (!fs_info) {
		test_std_err(TEST_ALLOC_FS_INFO);
		return -ENOMEM;
	}

	memory = kvzalloc(nodesize, GFP_KERNEL);
	if (!memory) {
		test_err("failed to allocate memory");
		ret = -ENOMEM;
		goto out;
	}

	eb = alloc_dummy_extent_buffer(fs_info, SZ_1M);
	if (!eb) {
		test_std_err(TEST_ALLOC_EXTENT_BUFFER);
		ret = -ENOMEM;
		goto out;
	}

	init_eb_and_memory(eb, memory);
	ret = verify_eb_and_memory(eb, memory, "full eb write");
	if (ret < 0)
		goto out;

	memcpy(memory, memory + 16, 16);
	memcpy_extent_buffer(eb, 0, 16, 16);
	ret = verify_eb_and_memory(eb, memory, "same page non-overlapping memcpy 1");
	if (ret < 0)
		goto out;

	memcpy(memory, memory + 2048, 16);
	memcpy_extent_buffer(eb, 0, 2048, 16);
	ret = verify_eb_and_memory(eb, memory, "same page non-overlapping memcpy 2");
	if (ret < 0)
		goto out;
	memcpy(memory, memory + 2048, 2048);
	memcpy_extent_buffer(eb, 0, 2048, 2048);
	ret = verify_eb_and_memory(eb, memory, "same page non-overlapping memcpy 3");
	if (ret < 0)
		goto out;

	memmove(memory + 512, memory + 256, 512);
	memmove_extent_buffer(eb, 512, 256, 512);
	ret = verify_eb_and_memory(eb, memory, "same page overlapping memcpy 1");
	if (ret < 0)
		goto out;

	memmove(memory + 2048, memory + 512, 2048);
	memmove_extent_buffer(eb, 2048, 512, 2048);
	ret = verify_eb_and_memory(eb, memory, "same page overlapping memcpy 2");
	if (ret < 0)
		goto out;
	memmove(memory + 512, memory + 2048, 2048);
	memmove_extent_buffer(eb, 512, 2048, 2048);
	ret = verify_eb_and_memory(eb, memory, "same page overlapping memcpy 3");
	if (ret < 0)
		goto out;

	if (nodesize > PAGE_SIZE) {
		memcpy(memory, memory + 4096 - 128, 256);
		memcpy_extent_buffer(eb, 0, 4096 - 128, 256);
		ret = verify_eb_and_memory(eb, memory, "cross page non-overlapping memcpy 1");
		if (ret < 0)
			goto out;

		memcpy(memory + 4096 - 128, memory + 4096 + 128, 256);
		memcpy_extent_buffer(eb, 4096 - 128, 4096 + 128, 256);
		ret = verify_eb_and_memory(eb, memory, "cross page non-overlapping memcpy 2");
		if (ret < 0)
			goto out;

		memmove(memory + 4096 - 128, memory + 4096 - 64, 256);
		memmove_extent_buffer(eb, 4096 - 128, 4096 - 64, 256);
		ret = verify_eb_and_memory(eb, memory, "cross page overlapping memcpy 1");
		if (ret < 0)
			goto out;

		memmove(memory + 4096 - 64, memory + 4096 - 128, 256);
		memmove_extent_buffer(eb, 4096 - 64, 4096 - 128, 256);
		ret = verify_eb_and_memory(eb, memory, "cross page overlapping memcpy 2");
		if (ret < 0)
			goto out;
	}
out:
	free_extent_buffer(eb);
	kvfree(memory);
	btrfs_free_dummy_fs_info(fs_info);
	return ret;
}

int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
{
	int ret;

	test_msg("running extent I/O tests");

	ret = test_find_delalloc(sectorsize, nodesize);
	if (ret)
		goto out;

	ret = test_find_first_clear_extent_bit();
	if (ret)
		goto out;

	ret = test_eb_bitmaps(sectorsize, nodesize);
	if (ret)
		goto out;

	ret = test_eb_mem_ops(sectorsize, nodesize);
out:
	return ret;
}
