aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8a405a5fa6a3..99121a55ffbe 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -382,12 +382,6 @@ int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
382 BUG_ON(ret); 382 BUG_ON(ret);
383 383
384 if (!(rw & (1 << BIO_RW))) { 384 if (!(rw & (1 << BIO_RW))) {
385 if (!btrfs_test_opt(root, NODATASUM) &&
386 !btrfs_test_flag(inode, NODATASUM)) {
387 mutex_lock(&BTRFS_I(inode)->csum_mutex);
388 btrfs_lookup_bio_sums(root, inode, bio);
389 mutex_unlock(&BTRFS_I(inode)->csum_mutex);
390 }
391 goto mapit; 385 goto mapit;
392 } 386 }
393 387
@@ -595,6 +589,58 @@ int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
595 return btrfs_finish_ordered_io(page->mapping->host, start, end); 589 return btrfs_finish_ordered_io(page->mapping->host, start, end);
596} 590}
597 591
592int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
593{
594 int ret = 0;
595 struct inode *inode = page->mapping->host;
596 struct btrfs_root *root = BTRFS_I(inode)->root;
597 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
598 struct btrfs_csum_item *item;
599 struct btrfs_path *path = NULL;
600 u32 csum;
601
602 if (btrfs_test_opt(root, NODATASUM) ||
603 btrfs_test_flag(inode, NODATASUM))
604 return 0;
605
606 /*
607 * It is possible there is an ordered extent that has
608 * not yet finished for this range in the file. If so,
609 * that extent will have a csum cached, and it will insert
610 * the sum after all the blocks in the extent are fully
611 * on disk. So, look for an ordered extent and use the
612 * sum if found. We have to do this before looking in the
613 * btree because csum items are pre-inserted based on
614 * the file size. btrfs_lookup_csum might find an item
615 * that still hasn't been fully filled.
616 */
617 ret = btrfs_find_ordered_sum(inode, start, &csum);
618 if (ret == 0)
619 goto found;
620
621 ret = 0;
622 path = btrfs_alloc_path();
623 item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
624 if (IS_ERR(item)) {
625 ret = PTR_ERR(item);
626 /* a csum that isn't present is a preallocated region. */
627 if (ret == -ENOENT || ret == -EFBIG)
628 ret = 0;
629 csum = 0;
630 printk("no csum found for inode %lu start %Lu\n", inode->i_ino,
631 start);
632 goto out;
633 }
634 read_extent_buffer(path->nodes[0], &csum, (unsigned long)item,
635 BTRFS_CRC32_SIZE);
636found:
637 set_state_private(io_tree, start, csum);
638out:
639 if (path)
640 btrfs_free_path(path);
641 return ret;
642}
643
598struct io_failure_record { 644struct io_failure_record {
599 struct page *page; 645 struct page *page;
600 u64 start; 646 u64 start;
@@ -3580,6 +3626,7 @@ static struct extent_io_ops btrfs_extent_io_ops = {
3580 .fill_delalloc = run_delalloc_range, 3626 .fill_delalloc = run_delalloc_range,
3581 .submit_bio_hook = btrfs_submit_bio_hook, 3627 .submit_bio_hook = btrfs_submit_bio_hook,
3582 .merge_bio_hook = btrfs_merge_bio_hook, 3628 .merge_bio_hook = btrfs_merge_bio_hook,
3629 .readpage_io_hook = btrfs_readpage_io_hook,
3583 .readpage_end_io_hook = btrfs_readpage_end_io_hook, 3630 .readpage_end_io_hook = btrfs_readpage_end_io_hook,
3584 .writepage_end_io_hook = btrfs_writepage_end_io_hook, 3631 .writepage_end_io_hook = btrfs_writepage_end_io_hook,
3585 .writepage_start_hook = btrfs_writepage_start_hook, 3632 .writepage_start_hook = btrfs_writepage_start_hook,