提交 e41ca589 编写于 作者: Q Qu Wenruo 提交者: David Sterba

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: NQu Wenruo <wqu@suse.com>
Reviewed-by: NDavid Sterba <dsterba@suse.com>
Signed-off-by: NDavid Sterba <dsterba@suse.com>
上级 bc877d28
...@@ -2428,32 +2428,6 @@ static inline u32 btrfs_file_extent_inline_item_len( ...@@ -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; 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 */ /* btrfs_dev_stats_item */
static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb, static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
const struct btrfs_dev_stats_item *ptr, const struct btrfs_dev_stats_item *ptr,
......
...@@ -942,7 +942,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, ...@@ -942,7 +942,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
btrfs_file_extent_num_bytes(leaf, fi); btrfs_file_extent_num_bytes(leaf, fi);
} else if (type == BTRFS_FILE_EXTENT_INLINE) { } else if (type == BTRFS_FILE_EXTENT_INLINE) {
size_t size; 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, extent_end = ALIGN(extent_start + size,
fs_info->sectorsize); fs_info->sectorsize);
} }
......
...@@ -833,8 +833,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, ...@@ -833,8 +833,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
btrfs_file_extent_num_bytes(leaf, fi); btrfs_file_extent_num_bytes(leaf, fi);
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
extent_end = key.offset + extent_end = key.offset +
btrfs_file_extent_inline_len(leaf, btrfs_file_extent_ram_bytes(leaf, fi);
path->slots[0], fi);
} else { } else {
/* can't happen */ /* can't happen */
BUG(); BUG();
......
...@@ -1443,8 +1443,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, ...@@ -1443,8 +1443,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
nocow = 1; nocow = 1;
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
extent_end = found_key.offset + extent_end = found_key.offset +
btrfs_file_extent_inline_len(leaf, btrfs_file_extent_ram_bytes(leaf, fi);
path->slots[0], fi);
extent_end = ALIGN(extent_end, extent_end = ALIGN(extent_end,
fs_info->sectorsize); fs_info->sectorsize);
} else { } else {
...@@ -4643,8 +4642,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, ...@@ -4643,8 +4642,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
BTRFS_I(inode), leaf, fi, BTRFS_I(inode), leaf, fi,
found_key.offset); found_key.offset);
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
item_end += btrfs_file_extent_inline_len(leaf, item_end += btrfs_file_extent_ram_bytes(leaf,
path->slots[0], fi); fi);
trace_btrfs_truncate_show_fi_inline( trace_btrfs_truncate_show_fi_inline(
BTRFS_I(inode), leaf, fi, path->slots[0], BTRFS_I(inode), leaf, fi, path->slots[0],
...@@ -6943,7 +6942,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, ...@@ -6943,7 +6942,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
extent_start); extent_start);
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) { } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
size_t size; 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, extent_end = ALIGN(extent_start + size,
fs_info->sectorsize); fs_info->sectorsize);
...@@ -6994,7 +6994,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, ...@@ -6994,7 +6994,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
if (new_inline) if (new_inline)
goto out; 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; extent_offset = page_offset(page) + pg_offset - extent_start;
copy_size = min_t(u64, PAGE_SIZE - pg_offset, copy_size = min_t(u64, PAGE_SIZE - pg_offset,
size - extent_offset); size - extent_offset);
......
...@@ -267,8 +267,8 @@ void btrfs_print_leaf(struct extent_buffer *l) ...@@ -267,8 +267,8 @@ void btrfs_print_leaf(struct extent_buffer *l)
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
if (btrfs_file_extent_type(l, fi) == if (btrfs_file_extent_type(l, fi) ==
BTRFS_FILE_EXTENT_INLINE) { BTRFS_FILE_EXTENT_INLINE) {
pr_info("\t\tinline extent data size %u\n", pr_info("\t\tinline extent data size %llu\n",
btrfs_file_extent_inline_len(l, i, fi)); btrfs_file_extent_ram_bytes(l, fi));
break; break;
} }
pr_info("\t\textent data disk bytenr %llu nr %llu\n", pr_info("\t\textent data disk bytenr %llu nr %llu\n",
......
...@@ -1500,7 +1500,7 @@ static int read_symlink(struct btrfs_root *root, ...@@ -1500,7 +1500,7 @@ static int read_symlink(struct btrfs_root *root,
BUG_ON(compression); BUG_ON(compression);
off = btrfs_file_extent_inline_start(ei); off = btrfs_file_extent_inline_start(ei);
len = btrfs_file_extent_inline_len(path->nodes[0], path->slots[0], ei); len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len); ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len);
...@@ -5160,7 +5160,7 @@ static int clone_range(struct send_ctx *sctx, ...@@ -5160,7 +5160,7 @@ static int clone_range(struct send_ctx *sctx,
ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
type = btrfs_file_extent_type(leaf, ei); type = btrfs_file_extent_type(leaf, ei);
if (type == BTRFS_FILE_EXTENT_INLINE) { if (type == BTRFS_FILE_EXTENT_INLINE) {
ext_len = btrfs_file_extent_inline_len(leaf, slot, ei); ext_len = btrfs_file_extent_ram_bytes(leaf, ei);
ext_len = PAGE_ALIGN(ext_len); ext_len = PAGE_ALIGN(ext_len);
} else { } else {
ext_len = btrfs_file_extent_num_bytes(leaf, ei); ext_len = btrfs_file_extent_num_bytes(leaf, ei);
...@@ -5236,8 +5236,7 @@ static int send_write_or_clone(struct send_ctx *sctx, ...@@ -5236,8 +5236,7 @@ static int send_write_or_clone(struct send_ctx *sctx,
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], ei); type = btrfs_file_extent_type(path->nodes[0], ei);
if (type == BTRFS_FILE_EXTENT_INLINE) { if (type == BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_inline_len(path->nodes[0], len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
path->slots[0], ei);
/* /*
* it is possible the inline item won't cover the whole page, * it is possible the inline item won't cover the whole page,
* but there may be items after this page. Make * but there may be items after this page. Make
...@@ -5375,7 +5374,7 @@ static int is_extent_unchanged(struct send_ctx *sctx, ...@@ -5375,7 +5374,7 @@ static int is_extent_unchanged(struct send_ctx *sctx,
} }
if (right_type == BTRFS_FILE_EXTENT_INLINE) { if (right_type == BTRFS_FILE_EXTENT_INLINE) {
right_len = btrfs_file_extent_inline_len(eb, slot, ei); right_len = btrfs_file_extent_ram_bytes(eb, ei);
right_len = PAGE_ALIGN(right_len); right_len = PAGE_ALIGN(right_len);
} else { } else {
right_len = btrfs_file_extent_num_bytes(eb, ei); right_len = btrfs_file_extent_num_bytes(eb, ei);
...@@ -5496,8 +5495,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset) ...@@ -5496,8 +5495,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], fi); type = btrfs_file_extent_type(path->nodes[0], fi);
if (type == BTRFS_FILE_EXTENT_INLINE) { if (type == BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_inline_len(path->nodes[0], u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
path->slots[0], fi);
extent_end = ALIGN(key.offset + size, extent_end = ALIGN(key.offset + size,
sctx->send_root->fs_info->sectorsize); sctx->send_root->fs_info->sectorsize);
} else { } else {
...@@ -5560,7 +5558,7 @@ static int range_is_hole_in_parent(struct send_ctx *sctx, ...@@ -5560,7 +5558,7 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
if (btrfs_file_extent_type(leaf, fi) == if (btrfs_file_extent_type(leaf, fi) ==
BTRFS_FILE_EXTENT_INLINE) { BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_inline_len(leaf, slot, fi); u64 size = btrfs_file_extent_ram_bytes(leaf, fi);
extent_end = ALIGN(key.offset + size, extent_end = ALIGN(key.offset + size,
root->fs_info->sectorsize); root->fs_info->sectorsize);
...@@ -5606,8 +5604,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, ...@@ -5606,8 +5604,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], fi); type = btrfs_file_extent_type(path->nodes[0], fi);
if (type == BTRFS_FILE_EXTENT_INLINE) { if (type == BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_inline_len(path->nodes[0], u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
path->slots[0], fi);
extent_end = ALIGN(key->offset + size, extent_end = ALIGN(key->offset + size,
sctx->send_root->fs_info->sectorsize); sctx->send_root->fs_info->sectorsize);
} else { } else {
......
...@@ -597,7 +597,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, ...@@ -597,7 +597,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
if (btrfs_file_extent_disk_bytenr(eb, item) == 0) if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
nbytes = 0; nbytes = 0;
} else if (found_type == BTRFS_FILE_EXTENT_INLINE) { } else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
size = btrfs_file_extent_inline_len(eb, slot, item); size = btrfs_file_extent_ram_bytes(eb, item);
nbytes = btrfs_file_extent_ram_bytes(eb, item); nbytes = btrfs_file_extent_ram_bytes(eb, item);
extent_end = ALIGN(start + size, extent_end = ALIGN(start + size,
fs_info->sectorsize); fs_info->sectorsize);
...@@ -3920,9 +3920,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, ...@@ -3920,9 +3920,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
struct btrfs_file_extent_item); struct btrfs_file_extent_item);
if (btrfs_file_extent_type(src, extent) == if (btrfs_file_extent_type(src, extent) ==
BTRFS_FILE_EXTENT_INLINE) { BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_inline_len(src, len = btrfs_file_extent_ram_bytes(src, extent);
src_path->slots[0],
extent);
*last_extent = ALIGN(key.offset + len, *last_extent = ALIGN(key.offset + len,
fs_info->sectorsize); fs_info->sectorsize);
} else { } else {
...@@ -3987,7 +3985,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, ...@@ -3987,7 +3985,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item); extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item);
if (btrfs_file_extent_type(src, extent) == if (btrfs_file_extent_type(src, extent) ==
BTRFS_FILE_EXTENT_INLINE) { BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_inline_len(src, i, extent); len = btrfs_file_extent_ram_bytes(src, extent);
extent_end = ALIGN(key.offset + len, extent_end = ALIGN(key.offset + len,
fs_info->sectorsize); fs_info->sectorsize);
} else { } else {
...@@ -4572,9 +4570,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans, ...@@ -4572,9 +4570,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
if (btrfs_file_extent_type(leaf, extent) == if (btrfs_file_extent_type(leaf, extent) ==
BTRFS_FILE_EXTENT_INLINE) { BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_inline_len(leaf, len = btrfs_file_extent_ram_bytes(leaf, extent);
path->slots[0],
extent);
ASSERT(len == i_size || ASSERT(len == i_size ||
(len == fs_info->sectorsize && (len == fs_info->sectorsize &&
btrfs_file_extent_compression(leaf, extent) != btrfs_file_extent_compression(leaf, extent) !=
......
...@@ -374,7 +374,7 @@ DECLARE_EVENT_CLASS( ...@@ -374,7 +374,7 @@ DECLARE_EVENT_CLASS(
__entry->extent_type = btrfs_file_extent_type(l, fi); __entry->extent_type = btrfs_file_extent_type(l, fi);
__entry->compression = btrfs_file_extent_compression(l, fi); __entry->compression = btrfs_file_extent_compression(l, fi);
__entry->extent_start = start; __entry->extent_start = start;
__entry->extent_end = (start + btrfs_file_extent_inline_len(l, slot, fi)); __entry->extent_end = (start + btrfs_file_extent_ram_bytes(l, fi));
), ),
TP_printk_btrfs( TP_printk_btrfs(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册