btrfs: Get rid of the confusing btrfs_file_extent_inline_len
authorQu Wenruo <wqu@suse.com>
Wed, 6 Jun 2018 07:41:49 +0000 (15:41 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2020 21:32:19 +0000 (16:32 -0500)
[ Upstream commit e41ca5897489b1c18af75ff0cc8f5c80260b3281 ]

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 <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/btrfs/ctree.h
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/print-tree.c
fs/btrfs/send.c
fs/btrfs/tree-log.c
include/trace/events/btrfs.h

index 588760c49fe28b8137d7a4136f035dd6d947e804..664710848e6f130ef8945c22d38ffa91bc2f3485 100644 (file)
@@ -2408,32 +2408,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,
index fdcb410026233ecc7c5ec475b8a5d711efc47b3c..702b3606ad0ec4818bf475fdef29e3220b7861c3 100644 (file)
@@ -955,7 +955,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);
        }
index c68ce3412dc1152e6da4d5000c715f4d813d10e1..725544ec9c842c4bfa598cea06cf05d25026b556 100644 (file)
@@ -784,8 +784,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();
index f2dc517768f02c0dad13b65bee86201363c0162d..abecc4724a3bc931ca4d4c4d8c984e58c4bcf53f 100644 (file)
@@ -1476,8 +1476,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 {
@@ -4651,8 +4650,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],
@@ -7167,7 +7166,8 @@ again:
                                                       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);
 
@@ -7218,7 +7218,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);
index 569205e651c7dd46c98a8fe3d0798140322d4ec3..47336d4b19d848f665db6e2549c4ad2c0d898253 100644 (file)
@@ -259,8 +259,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",
index 1211fdcd425dc867602ee488fc5fc0beab400c60..ca15d65a2070c089ba53d61c4afca06e20121578 100644 (file)
@@ -1545,7 +1545,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);
 
@@ -5195,7 +5195,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);
@@ -5271,8 +5271,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
@@ -5405,7 +5404,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);
@@ -5526,8 +5525,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 {
@@ -5590,7 +5588,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);
@@ -5636,8 +5634,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 {
index 98c397eb054c5fc9db04824fb219684b54074a39..65a986054f89e898ca33114a7a54238f83d7d104 100644 (file)
@@ -619,7 +619,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
                if (btrfs_file_extent_disk_bytenr(eb, item) == 0)
                        nbytes = 0;
        } 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);
                extent_end = ALIGN(start + size,
                                   fs_info->sectorsize);
@@ -3943,9 +3943,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
                                        struct btrfs_file_extent_item);
                if (btrfs_file_extent_type(src, extent) ==
                    BTRFS_FILE_EXTENT_INLINE) {
-                       len = btrfs_file_extent_inline_len(src,
-                                                          src_path->slots[0],
-                                                          extent);
+                       len = btrfs_file_extent_ram_bytes(src, extent);
                        *last_extent = ALIGN(key.offset + len,
                                             fs_info->sectorsize);
                } else {
@@ -4010,7 +4008,7 @@ fill_holes:
                extent = btrfs_item_ptr(src, i, struct btrfs_file_extent_item);
                if (btrfs_file_extent_type(src, extent) ==
                    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,
                                           fs_info->sectorsize);
                } else {
@@ -4730,9 +4728,7 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
 
                if (btrfs_file_extent_type(leaf, extent) ==
                    BTRFS_FILE_EXTENT_INLINE) {
-                       len = btrfs_file_extent_inline_len(leaf,
-                                                          path->slots[0],
-                                                          extent);
+                       len = btrfs_file_extent_ram_bytes(leaf, extent);
                        ASSERT(len == i_size ||
                               (len == fs_info->sectorsize &&
                                btrfs_file_extent_compression(leaf, extent) !=
index 32d0c1fe2bfa7d177ba63a1ca1613cd4f2144c0d..3ebada29a313e4dacb9d73e5446e33d5ae95e438 100644 (file)
@@ -325,7 +325,7 @@ DECLARE_EVENT_CLASS(
                __entry->extent_type    = btrfs_file_extent_type(l, fi);
                __entry->compression    = btrfs_file_extent_compression(l, fi);
                __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(