From e41ca5897489b1c18af75ff0cc8f5c80260b3281 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Wed, 6 Jun 2018 15:41:49 +0800 Subject: 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: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/send.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'fs/btrfs/send.c') diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index c47f62b19226..6ff7a1315e52 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -1500,7 +1500,7 @@ static int read_symlink(struct btrfs_root *root, BUG_ON(compression); 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); @@ -5160,7 +5160,7 @@ static int clone_range(struct send_ctx *sctx, ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); type = btrfs_file_extent_type(leaf, ei); 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); } else { ext_len = btrfs_file_extent_num_bytes(leaf, ei); @@ -5236,8 +5236,7 @@ static int send_write_or_clone(struct send_ctx *sctx, struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], ei); if (type == BTRFS_FILE_EXTENT_INLINE) { - len = btrfs_file_extent_inline_len(path->nodes[0], - path->slots[0], ei); + len = btrfs_file_extent_ram_bytes(path->nodes[0], ei); /* * it is possible the inline item won't cover the whole page, * but there may be items after this page. Make @@ -5375,7 +5374,7 @@ static int is_extent_unchanged(struct send_ctx *sctx, } 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); } else { right_len = btrfs_file_extent_num_bytes(eb, ei); @@ -5496,8 +5495,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset) struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], fi); if (type == BTRFS_FILE_EXTENT_INLINE) { - u64 size = btrfs_file_extent_inline_len(path->nodes[0], - path->slots[0], fi); + u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi); extent_end = ALIGN(key.offset + size, sctx->send_root->fs_info->sectorsize); } else { @@ -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); if (btrfs_file_extent_type(leaf, fi) == 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, root->fs_info->sectorsize); @@ -5606,8 +5604,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, struct btrfs_file_extent_item); type = btrfs_file_extent_type(path->nodes[0], fi); if (type == BTRFS_FILE_EXTENT_INLINE) { - u64 size = btrfs_file_extent_inline_len(path->nodes[0], - path->slots[0], fi); + u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi); extent_end = ALIGN(key->offset + size, sctx->send_root->fs_info->sectorsize); } else { -- cgit v1.2.3