aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5547607681f4..e40fb318ad99 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -46,27 +46,6 @@ static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
46 46
47static struct extent_io_ops btree_extent_io_ops; 47static struct extent_io_ops btree_extent_io_ops;
48 48
49struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
50 u64 bytenr, u32 blocksize)
51{
52 struct inode *btree_inode = root->fs_info->btree_inode;
53 struct extent_buffer *eb;
54 eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
55 bytenr, blocksize, GFP_NOFS);
56 return eb;
57}
58
59struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
60 u64 bytenr, u32 blocksize)
61{
62 struct inode *btree_inode = root->fs_info->btree_inode;
63 struct extent_buffer *eb;
64
65 eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
66 bytenr, blocksize, NULL, GFP_NOFS);
67 return eb;
68}
69
70struct extent_map *btree_get_extent(struct inode *inode, struct page *page, 49struct extent_map *btree_get_extent(struct inode *inode, struct page *page,
71 size_t page_offset, u64 start, u64 len, 50 size_t page_offset, u64 start, u64 len,
72 int create) 51 int create)
@@ -380,36 +359,29 @@ static int close_all_devices(struct btrfs_fs_info *fs_info)
380 return 0; 359 return 0;
381} 360}
382 361
383struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, 362int btrfs_verify_block_csum(struct btrfs_root *root,
384 u32 blocksize) 363 struct extent_buffer *buf)
385{ 364{
386 struct extent_buffer *buf = NULL;
387 struct inode *btree_inode = root->fs_info->btree_inode;
388 struct extent_io_tree *io_tree; 365 struct extent_io_tree *io_tree;
389 u64 end; 366 u64 end;
390 int ret; 367 int ret;
391 368
392 io_tree = &BTRFS_I(btree_inode)->io_tree; 369 io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
393
394 buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
395 if (!buf)
396 return NULL;
397 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, buf, 0, 1,
398 btree_get_extent);
399
400 if (buf->flags & EXTENT_CSUM) 370 if (buf->flags & EXTENT_CSUM)
401 return buf; 371 return 0;
402 372
403 end = buf->start + PAGE_CACHE_SIZE - 1; 373 end = min_t(u64, buf->len, PAGE_CACHE_SIZE);
374 end = buf->start + end - 1;
404 if (test_range_bit(io_tree, buf->start, end, EXTENT_CSUM, 1)) { 375 if (test_range_bit(io_tree, buf->start, end, EXTENT_CSUM, 1)) {
405 buf->flags |= EXTENT_CSUM; 376 buf->flags |= EXTENT_CSUM;
406 return buf; 377 return 0;
407 } 378 }
408 379
409 lock_extent(io_tree, buf->start, end, GFP_NOFS); 380 lock_extent(io_tree, buf->start, end, GFP_NOFS);
410 381
411 if (test_range_bit(io_tree, buf->start, end, EXTENT_CSUM, 1)) { 382 if (test_range_bit(io_tree, buf->start, end, EXTENT_CSUM, 1)) {
412 buf->flags |= EXTENT_CSUM; 383 buf->flags |= EXTENT_CSUM;
384 ret = 0;
413 goto out_unlock; 385 goto out_unlock;
414 } 386 }
415 387
@@ -419,6 +391,48 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
419 391
420out_unlock: 392out_unlock:
421 unlock_extent(io_tree, buf->start, end, GFP_NOFS); 393 unlock_extent(io_tree, buf->start, end, GFP_NOFS);
394 return ret;
395}
396
397struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
398 u64 bytenr, u32 blocksize)
399{
400 struct inode *btree_inode = root->fs_info->btree_inode;
401 struct extent_buffer *eb;
402 eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
403 bytenr, blocksize, GFP_NOFS);
404 return eb;
405}
406
407struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
408 u64 bytenr, u32 blocksize)
409{
410 struct inode *btree_inode = root->fs_info->btree_inode;
411 struct extent_buffer *eb;
412
413 eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
414 bytenr, blocksize, NULL, GFP_NOFS);
415 return eb;
416}
417
418
419struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
420 u32 blocksize)
421{
422 struct extent_buffer *buf = NULL;
423 struct inode *btree_inode = root->fs_info->btree_inode;
424 struct extent_io_tree *io_tree;
425 int ret;
426
427 io_tree = &BTRFS_I(btree_inode)->io_tree;
428
429 buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
430 if (!buf)
431 return NULL;
432 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, buf, 0, 1,
433 btree_get_extent);
434
435 ret = btrfs_verify_block_csum(root, buf);
422 return buf; 436 return buf;
423} 437}
424 438