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

btrfs: Get rid of the confusing btrfs_file_extent_inline_len



We used to call btrfs_file_extent_inline_len() to get the uncompressed
data size of an inlined extent.

However this function is hiding evil, for compressed extent, it has no
choice but to directly read out ram_bytes from btrfs_file_extent_item.
While for uncompressed extent, it uses item size to calculate the real
data size, and ignoring ram_bytes completely.

In fact, for corrupted ram_bytes, due to above behavior kernel
btrfs_print_leaf() can't even print correct ram_bytes to expose the bug.

Since we have the tree-checker to verify all EXTENT_DATA, such mismatch
can be detected pretty easily, thus we can trust ram_bytes without the
evil btrfs_file_extent_inline_len().

Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent bc877d28
Loading
Loading
Loading
Loading
+0 −26
Original line number Diff line number Diff line
@@ -2428,32 +2428,6 @@ static inline u32 btrfs_file_extent_inline_item_len(
	return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START;
}

/* this returns the number of file bytes represented by the inline item.
 * If an item is compressed, this is the uncompressed size
 */
static inline u32 btrfs_file_extent_inline_len(const struct extent_buffer *eb,
					int slot,
					const struct btrfs_file_extent_item *fi)
{
	struct btrfs_map_token token;

	btrfs_init_map_token(&token);
	/*
	 * return the space used on disk if this item isn't
	 * compressed or encoded
	 */
	if (btrfs_token_file_extent_compression(eb, fi, &token) == 0 &&
	    btrfs_token_file_extent_encryption(eb, fi, &token) == 0 &&
	    btrfs_token_file_extent_other_encoding(eb, fi, &token) == 0) {
		return btrfs_file_extent_inline_item_len(eb,
							 btrfs_item_nr(slot));
	}

	/* otherwise use the ram bytes field */
	return btrfs_token_file_extent_ram_bytes(eb, fi, &token);
}


/* btrfs_dev_stats_item */
static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
					const struct btrfs_dev_stats_item *ptr,
+1 −1
Original line number Diff line number Diff line
@@ -942,7 +942,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
			btrfs_file_extent_num_bytes(leaf, fi);
	} else if (type == BTRFS_FILE_EXTENT_INLINE) {
		size_t size;
		size = btrfs_file_extent_inline_len(leaf, slot, fi);
		size = btrfs_file_extent_ram_bytes(leaf, fi);
		extent_end = ALIGN(extent_start + size,
				   fs_info->sectorsize);
	}
+1 −2
Original line number Diff line number Diff line
@@ -833,8 +833,7 @@ next_slot:
				btrfs_file_extent_num_bytes(leaf, fi);
		} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
			extent_end = key.offset +
				btrfs_file_extent_inline_len(leaf,
						     path->slots[0], fi);
				btrfs_file_extent_ram_bytes(leaf, fi);
		} else {
			/* can't happen */
			BUG();
+6 −6
Original line number Diff line number Diff line
@@ -1443,8 +1443,7 @@ next_slot:
			nocow = 1;
		} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
			extent_end = found_key.offset +
				btrfs_file_extent_inline_len(leaf,
						     path->slots[0], fi);
				btrfs_file_extent_ram_bytes(leaf, fi);
			extent_end = ALIGN(extent_end,
					   fs_info->sectorsize);
		} else {
@@ -4643,8 +4642,8 @@ search_again:
					BTRFS_I(inode), leaf, fi,
					found_key.offset);
			} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
				item_end += btrfs_file_extent_inline_len(leaf,
							 path->slots[0], fi);
				item_end += btrfs_file_extent_ram_bytes(leaf,
									fi);

				trace_btrfs_truncate_show_fi_inline(
					BTRFS_I(inode), leaf, fi, path->slots[0],
@@ -6943,7 +6942,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
						       extent_start);
	} else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
		size_t size;
		size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);

		size = btrfs_file_extent_ram_bytes(leaf, item);
		extent_end = ALIGN(extent_start + size,
				   fs_info->sectorsize);

@@ -6994,7 +6994,7 @@ next:
		if (new_inline)
			goto out;

		size = btrfs_file_extent_inline_len(leaf, path->slots[0], item);
		size = btrfs_file_extent_ram_bytes(leaf, item);
		extent_offset = page_offset(page) + pg_offset - extent_start;
		copy_size = min_t(u64, PAGE_SIZE - pg_offset,
				  size - extent_offset);
+2 −2
Original line number Diff line number Diff line
@@ -267,8 +267,8 @@ void btrfs_print_leaf(struct extent_buffer *l)
					    struct btrfs_file_extent_item);
			if (btrfs_file_extent_type(l, fi) ==
			    BTRFS_FILE_EXTENT_INLINE) {
				pr_info("\t\tinline extent data size %u\n",
				       btrfs_file_extent_inline_len(l, i, fi));
				pr_info("\t\tinline extent data size %llu\n",
				       btrfs_file_extent_ram_bytes(l, fi));
				break;
			}
			pr_info("\t\textent data disk bytenr %llu nr %llu\n",
Loading