aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-20 09:44:52 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commit4d1b5fb4d7075f862848dbff8873e22382abd482 (patch)
tree2b68d05910f50c9e385890816e78eda6e8e6e55a /fs
parent7c2fe32a238eb12422beca5cbd5194a594baa559 (diff)
Btrfs: Lookup readpage checksums on bio submission again
This optimization had been removed because I thought it was triggering csum errors. The real cause of the errors was elsewhere, and so this optimization is back. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/file-item.c4
-rw-r--r--fs/btrfs/inode.c62
2 files changed, 6 insertions, 60 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 9454e0a07c89..f861bd506928 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -134,7 +134,6 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
134 return ret; 134 return ret;
135} 135}
136 136
137#if 0 /* broken */
138int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 137int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
139 struct bio *bio) 138 struct bio *bio)
140{ 139{
@@ -151,6 +150,8 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
151 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 150 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
152 151
153 path = btrfs_alloc_path(); 152 path = btrfs_alloc_path();
153 if (bio->bi_size > PAGE_CACHE_SIZE * 8)
154 path->reada = 2;
154 155
155 WARN_ON(bio->bi_vcnt <= 0); 156 WARN_ON(bio->bi_vcnt <= 0);
156 157
@@ -211,7 +212,6 @@ found:
211 btrfs_free_path(path); 212 btrfs_free_path(path);
212 return 0; 213 return 0;
213} 214}
214#endif
215 215
216int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, 216int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
217 struct bio *bio) 217 struct bio *bio)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 6c778043207d..38d7a81763cd 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -389,15 +389,15 @@ int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
389 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 389 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
390 BUG_ON(ret); 390 BUG_ON(ret);
391 391
392 if (!(rw & (1 << BIO_RW))) {
393 goto mapit;
394 }
395
396 if (btrfs_test_opt(root, NODATASUM) || 392 if (btrfs_test_opt(root, NODATASUM) ||
397 btrfs_test_flag(inode, NODATASUM)) { 393 btrfs_test_flag(inode, NODATASUM)) {
398 goto mapit; 394 goto mapit;
399 } 395 }
400 396
397 if (!(rw & (1 << BIO_RW))) {
398 btrfs_lookup_bio_sums(root, inode, bio);
399 goto mapit;
400 }
401 return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, 401 return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info,
402 inode, rw, bio, mirror_num, 402 inode, rw, bio, mirror_num,
403 __btrfs_submit_bio_hook); 403 __btrfs_submit_bio_hook);
@@ -603,59 +603,6 @@ int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
603 return btrfs_finish_ordered_io(page->mapping->host, start, end); 603 return btrfs_finish_ordered_io(page->mapping->host, start, end);
604} 604}
605 605
606int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
607{
608 int ret = 0;
609 struct inode *inode = page->mapping->host;
610 struct btrfs_root *root = BTRFS_I(inode)->root;
611 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
612 struct btrfs_csum_item *item;
613 struct btrfs_path *path = NULL;
614 u32 csum;
615
616 if (btrfs_test_opt(root, NODATASUM) ||
617 btrfs_test_flag(inode, NODATASUM))
618 return 0;
619
620 /*
621 * It is possible there is an ordered extent that has
622 * not yet finished for this range in the file. If so,
623 * that extent will have a csum cached, and it will insert
624 * the sum after all the blocks in the extent are fully
625 * on disk. So, look for an ordered extent and use the
626 * sum if found. We have to do this before looking in the
627 * btree because csum items are pre-inserted based on
628 * the file size. btrfs_lookup_csum might find an item
629 * that still hasn't been fully filled.
630 */
631 ret = btrfs_find_ordered_sum(inode, start, &csum);
632 if (ret == 0)
633 goto found;
634
635 ret = 0;
636 path = btrfs_alloc_path();
637 item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
638 if (IS_ERR(item)) {
639 ret = PTR_ERR(item);
640 /* a csum that isn't present is a preallocated region. */
641 if (ret == -ENOENT || ret == -EFBIG)
642 ret = 0;
643 csum = 0;
644 if (printk_ratelimit())
645 printk("no csum found for inode %lu start %Lu\n", inode->i_ino,
646 start);
647 goto out;
648 }
649 read_extent_buffer(path->nodes[0], &csum, (unsigned long)item,
650 BTRFS_CRC32_SIZE);
651found:
652 set_state_private(io_tree, start, csum);
653out:
654 if (path)
655 btrfs_free_path(path);
656 return ret;
657}
658
659struct io_failure_record { 606struct io_failure_record {
660 struct page *page; 607 struct page *page;
661 u64 start; 608 u64 start;
@@ -3669,7 +3616,6 @@ static struct extent_io_ops btrfs_extent_io_ops = {
3669 .fill_delalloc = run_delalloc_range, 3616 .fill_delalloc = run_delalloc_range,
3670 .submit_bio_hook = btrfs_submit_bio_hook, 3617 .submit_bio_hook = btrfs_submit_bio_hook,
3671 .merge_bio_hook = btrfs_merge_bio_hook, 3618 .merge_bio_hook = btrfs_merge_bio_hook,
3672 .readpage_io_hook = btrfs_readpage_io_hook,
3673 .readpage_end_io_hook = btrfs_readpage_end_io_hook, 3619 .readpage_end_io_hook = btrfs_readpage_end_io_hook,
3674 .writepage_end_io_hook = btrfs_writepage_end_io_hook, 3620 .writepage_end_io_hook = btrfs_writepage_end_io_hook,
3675 .writepage_start_hook = btrfs_writepage_start_hook, 3621 .writepage_start_hook = btrfs_writepage_start_hook,