We restructured btrfs_merge_bio_hook(). And the new function will be used to
fix a panic problem that caused by direct IO.
Signed-off-by: Miao Xie <[email protected]>
---
fs/btrfs/inode.c | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3906e48..32b68fa 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1353,6 +1353,22 @@ static int btrfs_clear_bit_hook(struct inode *inode,
return 0;
}
+static int __btrfs_can_merge_page_to_bio(struct btrfs_mapping_tree *map_tree,
+ size_t size, struct bio *bio)
+{
+ u64 logical = (u64)bio->bi_sector << 9;
+ u64 map_length;
+ int ret;
+
+ map_length = bio->bi_size;
+ ret = btrfs_map_block(map_tree, READ, logical,
+ &map_length, NULL, 0);
+
+ if (map_length < bio->bi_size + size)
+ return 1;
+ return ret;
+}
+
/*
* extent_io.c merge_bio_hook, this must check the chunk tree to make sure
* we don't create bios that span stripes or chunks
@@ -1363,23 +1379,12 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
{
struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
struct btrfs_mapping_tree *map_tree;
- u64 logical = (u64)bio->bi_sector << 9;
- u64 length = 0;
- u64 map_length;
- int ret;
if (bio_flags & EXTENT_BIO_COMPRESSED)
return 0;
- length = bio->bi_size;
map_tree = &root->fs_info->mapping_tree;
- map_length = length;
- ret = btrfs_map_block(map_tree, READ, logical,
- &map_length, NULL, 0);
-
- if (map_length < length + size)
- return 1;
- return ret;
+ return __btrfs_can_merge_page_to_bio(map_tree, size, bio);
}
/*
--
1.7.0.1