diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 86 |
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 | ||
47 | static struct extent_io_ops btree_extent_io_ops; | 47 | static struct extent_io_ops btree_extent_io_ops; |
48 | 48 | ||
49 | struct 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 | |||
59 | struct 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 | |||
70 | struct extent_map *btree_get_extent(struct inode *inode, struct page *page, | 49 | struct 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 | ||
383 | struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, | 362 | int 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 | ||
420 | out_unlock: | 392 | out_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 | |||
397 | struct 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 | |||
407 | struct 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 | |||
419 | struct 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 | ||