|
@@ -980,6 +980,38 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
|
|
|
+ int mirror_num, struct extent_buffer **eb)
|
|
|
+{
|
|
|
+ struct extent_buffer *buf = NULL;
|
|
|
+ struct inode *btree_inode = root->fs_info->btree_inode;
|
|
|
+ struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
|
|
|
+ if (!buf)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
|
|
|
+
|
|
|
+ ret = read_extent_buffer_pages(io_tree, buf, 0, WAIT_PAGE_LOCK,
|
|
|
+ btree_get_extent, mirror_num);
|
|
|
+ if (ret) {
|
|
|
+ free_extent_buffer(buf);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) {
|
|
|
+ free_extent_buffer(buf);
|
|
|
+ return -EIO;
|
|
|
+ } else if (extent_buffer_uptodate(io_tree, buf, NULL)) {
|
|
|
+ *eb = buf;
|
|
|
+ } else {
|
|
|
+ free_extent_buffer(buf);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
|
|
|
u64 bytenr, u32 blocksize)
|
|
|
{
|