Commit a982fc82 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: extract the inline extent read code into its own function



Currently we have inline extent read code behind two levels of
indentation, factor them them out into a new function,
read_inline_extent(), to make it a little easier to read.

Since we're here, also remove @extent_offset and @pg_offset arguments
from uncompress_inline() function, as it's not possible to have inline
extents at non-inline file offset.

Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 280f15cb
Loading
Loading
Loading
Loading
+34 −35
Original line number Diff line number Diff line
@@ -6865,7 +6865,6 @@ static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,

static noinline int uncompress_inline(struct btrfs_path *path,
				      struct page *page,
				      size_t pg_offset, u64 extent_offset,
				      struct btrfs_file_extent_item *item)
{
	int ret;
@@ -6876,7 +6875,6 @@ static noinline int uncompress_inline(struct btrfs_path *path,
	unsigned long ptr;
	int compress_type;

	WARN_ON(pg_offset != 0);
	compress_type = btrfs_file_extent_compression(leaf, item);
	max_size = btrfs_file_extent_ram_bytes(leaf, item);
	inline_size = btrfs_file_extent_inline_item_len(leaf, path->slots[0]);
@@ -6888,8 +6886,7 @@ static noinline int uncompress_inline(struct btrfs_path *path,
	read_extent_buffer(leaf, tmp, ptr, inline_size);

	max_size = min_t(unsigned long, PAGE_SIZE, max_size);
	ret = btrfs_decompress(compress_type, tmp, page,
			       extent_offset, inline_size, max_size);
	ret = btrfs_decompress(compress_type, tmp, page, 0, inline_size, max_size);

	/*
	 * decompression code contains a memset to fill in any space between the end
@@ -6899,13 +6896,40 @@ static noinline int uncompress_inline(struct btrfs_path *path,
	 * cover that region here.
	 */

	if (max_size + pg_offset < PAGE_SIZE)
		memzero_page(page,  pg_offset + max_size,
			     PAGE_SIZE - max_size - pg_offset);
	if (max_size < PAGE_SIZE)
		memzero_page(page, max_size, PAGE_SIZE - max_size);
	kfree(tmp);
	return ret;
}

static int read_inline_extent(struct btrfs_inode *inode, struct btrfs_path *path,
			      struct page *page)
{
	struct btrfs_file_extent_item *fi;
	void *kaddr;
	size_t copy_size;

	if (!page || PageUptodate(page))
		return 0;

	ASSERT(page_offset(page) == 0);

	fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
			    struct btrfs_file_extent_item);
	if (btrfs_file_extent_compression(path->nodes[0], fi) != BTRFS_COMPRESS_NONE)
		return uncompress_inline(path, page, fi);

	copy_size = min_t(u64, PAGE_SIZE,
			  btrfs_file_extent_ram_bytes(path->nodes[0], fi));
	kaddr = kmap_local_page(page);
	read_extent_buffer(path->nodes[0], kaddr,
			   btrfs_file_extent_inline_start(fi), copy_size);
	kunmap_local(kaddr);
	if (copy_size < PAGE_SIZE)
		memzero_page(page, copy_size, PAGE_SIZE - copy_size);
	return 0;
}

/*
 * Lookup the first extent overlapping a range in a file.
 *
@@ -7064,25 +7088,15 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
	    extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
		goto insert;
	} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
		char *map;
		size_t copy_size;

		if (!page)
			goto out;

		/*
		 * Inline extent can only exist at file offset 0. This is
		 * ensured by tree-checker and inline extent creation path.
		 * Thus all members representing file offsets should be zero.
		 */
		ASSERT(page_offset(page) == 0);
		ASSERT(pg_offset == 0);
		ASSERT(extent_start == 0);
		ASSERT(em->start == 0);

		copy_size = min_t(u64, PAGE_SIZE,
				  btrfs_file_extent_ram_bytes(leaf, item));

		/*
		 * btrfs_extent_item_to_extent_map() should have properly
		 * initialized em members already.
@@ -7092,24 +7106,9 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
		ASSERT(em->block_start == EXTENT_MAP_INLINE);
		ASSERT(em->len = fs_info->sectorsize);

		if (!PageUptodate(page)) {
			if (btrfs_file_extent_compression(leaf, item) !=
			    BTRFS_COMPRESS_NONE) {
				ret = uncompress_inline(path, page, 0, 0, item);
				if (ret)
		ret = read_inline_extent(inode, path, page);
		if (ret < 0)
			goto out;
			} else {
				map = kmap_local_page(page);
				read_extent_buffer(leaf, map,
					btrfs_file_extent_inline_start(item),
					copy_size);
				if (copy_size < PAGE_SIZE)
					memset(map + copy_size, 0,
					       PAGE_SIZE - copy_size);
				kunmap_local(map);
			}
			flush_dcache_page(page);
		}
		goto insert;
	}
not_found: