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,
 
        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;
 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
 };
 
 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
 
 
                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
 
  * 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;
 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
 };
 
 /*