btrfs: replace readpage_end_io_hook with direct calls
authorNikolay Borisov <nborisov@suse.com>
Fri, 18 Sep 2020 13:34:33 +0000 (16:34 +0300)
committerDavid Sterba <dsterba@suse.com>
Wed, 7 Oct 2020 10:13:24 +0000 (12:13 +0200)
Don't call readpage_end_io_hook for the btree inode.  Instead of relying
on indirect calls to implement metadata buffer validation simply check
if the inode whose page we are processing equals the btree inode. If it
does call the necessary function.

This is an improvement in 2 directions:

1. We aren't paying the penalty of indirect calls in a post-speculation
   attacks world.

2. The function is now named more explicitly so it's obvious what's
   going on

This is in preparation to removing struct extent_io_ops altogether.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent_io.c
fs/btrfs/inode.c

index 5cb8af6af25de57dae2c6ead7a33552eee7c7330..391c2b25cca1ad06e47ecf2029aced8e60cf855e 100644 (file)
@@ -2969,6 +2969,8 @@ void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size);
 u64 btrfs_file_extent_end(const struct btrfs_path *path);
 
 /* inode.c */
+int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset,
+                          struct page *page, u64 start, u64 end, int mirror);
 struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
                                           u64 start, u64 len);
 noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
index ebc110231f30ba192073b09c0a85ca548535bdef..1c84a7ea9894e1f5d25451b67ea72a54b2d499c3 100644 (file)
@@ -524,9 +524,9 @@ static int check_tree_block_fsid(struct extent_buffer *eb)
        return 1;
 }
 
-static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
-                                     u64 phy_offset, struct page *page,
-                                     u64 start, u64 end, int mirror)
+int btrfs_validate_metadata_buffer(struct btrfs_io_bio *io_bio, u64 phy_offset,
+                                  struct page *page, u64 start, u64 end,
+                                  int mirror)
 {
        u64 found_start;
        int found_level;
@@ -4638,5 +4638,5 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info)
 static const struct extent_io_ops btree_extent_io_ops = {
        /* mandatory callbacks */
        .submit_bio_hook = btree_submit_bio_hook,
-       .readpage_end_io_hook = btree_readpage_end_io_hook,
+       .readpage_end_io_hook = NULL
 };
index 89b6a709a184389e0adb0503d5551df2e5df136b..bc2e4924619954aacd092cfa4b92691f8b565575 100644 (file)
@@ -76,7 +76,9 @@ void btrfs_btree_balance_dirty(struct btrfs_fs_info *fs_info);
 void btrfs_btree_balance_dirty_nodelay(struct btrfs_fs_info *fs_info);
 void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
                                 struct btrfs_root *root);
-
+int btrfs_validate_metadata_buffer(struct btrfs_io_bio *io_bio, u64 phy_offset,
+                                  struct page *page, u64 start, u64 end,
+                                  int mirror);
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
 struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info);
 #endif
index afac70ef0cc5d051cfc2630604b4dd913e03c013..6cee6b611d0c8b4acb8e4a642c2c8ca9cea2a091 100644 (file)
@@ -2851,9 +2851,12 @@ static void end_bio_extent_readpage(struct bio *bio)
 
                mirror = io_bio->mirror_num;
                if (likely(uptodate)) {
-                       ret = tree->ops->readpage_end_io_hook(io_bio, offset,
-                                                             page, start, end,
-                                                             mirror);
+                       if (data_inode)
+                               ret = btrfs_verify_data_csum(io_bio, offset, page,
+                                                            start, end, mirror);
+                       else
+                               ret = btrfs_validate_metadata_buffer(io_bio,
+                                       offset, page, start, end, mirror);
                        if (ret)
                                uptodate = 0;
                        else
index b8481632dfc77126647a45b90b2192c3b0a41762..982187b0cd595ae54c74b459eab8008df739460b 100644 (file)
@@ -2832,9 +2832,8 @@ zeroit:
  * if there's a match, we allow the bio to finish.  If not, the code in
  * extent_io.c will try to find good copies for us.
  */
-static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
-                                     u64 phy_offset, struct page *page,
-                                     u64 start, u64 end, int mirror)
+int btrfs_verify_data_csum(struct btrfs_io_bio *io_bio, u64 phy_offset,
+                          struct page *page, u64 start, u64 end, int mirror)
 {
        size_t offset = start - page_offset(page);
        struct inode *inode = page->mapping->host;
@@ -10261,7 +10260,7 @@ static const struct file_operations btrfs_dir_file_operations = {
 static const struct extent_io_ops btrfs_extent_io_ops = {
        /* mandatory callbacks */
        .submit_bio_hook = btrfs_submit_bio_hook,
-       .readpage_end_io_hook = btrfs_readpage_end_io_hook,
+       .readpage_end_io_hook = NULL
 };
 
 /*