aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-11-06 03:05:08 -0500
committerChris Mason <chris.mason@oracle.com>2011-11-06 03:05:08 -0500
commit531f4b1ae5e0fc8c9b3f03838218e5ea178f80d3 (patch)
tree63efdfe9b192243fefb76be3921b9a2aaa26291e /fs/btrfs/disk-io.c
parentc06a0e120a4e381a1c291c1fce3c6155c5791cae (diff)
parent7a26285eea8eb92e0088db011571d887d4551b0f (diff)
Merge branch 'for-chris' of git://github.com/sensille/linux into integration
Conflicts: fs/btrfs/ctree.h Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 23b6776477b7..cedfbfb278eb 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -366,7 +366,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
366 clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); 366 clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
367 io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; 367 io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
368 while (1) { 368 while (1) {
369 ret = read_extent_buffer_pages(io_tree, eb, start, 1, 369 ret = read_extent_buffer_pages(io_tree, eb, start,
370 WAIT_COMPLETE,
370 btree_get_extent, mirror_num); 371 btree_get_extent, mirror_num);
371 if (!ret && 372 if (!ret &&
372 !verify_parent_transid(io_tree, eb, parent_transid)) 373 !verify_parent_transid(io_tree, eb, parent_transid))
@@ -607,11 +608,47 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
607 end = min_t(u64, eb->len, PAGE_CACHE_SIZE); 608 end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
608 end = eb->start + end - 1; 609 end = eb->start + end - 1;
609err: 610err:
611 if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
612 clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
613 btree_readahead_hook(root, eb, eb->start, ret);
614 }
615
610 free_extent_buffer(eb); 616 free_extent_buffer(eb);
611out: 617out:
612 return ret; 618 return ret;
613} 619}
614 620
621static int btree_io_failed_hook(struct bio *failed_bio,
622 struct page *page, u64 start, u64 end,
623 struct extent_state *state)
624{
625 struct extent_io_tree *tree;
626 unsigned long len;
627 struct extent_buffer *eb;
628 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
629
630 tree = &BTRFS_I(page->mapping->host)->io_tree;
631 if (page->private == EXTENT_PAGE_PRIVATE)
632 goto out;
633 if (!page->private)
634 goto out;
635
636 len = page->private >> 2;
637 WARN_ON(len == 0);
638
639 eb = alloc_extent_buffer(tree, start, len, page);
640 if (eb == NULL)
641 goto out;
642
643 if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
644 clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
645 btree_readahead_hook(root, eb, eb->start, -EIO);
646 }
647
648out:
649 return -EIO; /* we fixed nothing */
650}
651
615static void end_workqueue_bio(struct bio *bio, int err) 652static void end_workqueue_bio(struct bio *bio, int err)
616{ 653{
617 struct end_io_wq *end_io_wq = bio->bi_private; 654 struct end_io_wq *end_io_wq = bio->bi_private;
@@ -973,11 +1010,43 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
973 if (!buf) 1010 if (!buf)
974 return 0; 1011 return 0;
975 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, 1012 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
976 buf, 0, 0, btree_get_extent, 0); 1013 buf, 0, WAIT_NONE, btree_get_extent, 0);
977 free_extent_buffer(buf); 1014 free_extent_buffer(buf);
978 return ret; 1015 return ret;
979} 1016}
980 1017
1018int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
1019 int mirror_num, struct extent_buffer **eb)
1020{
1021 struct extent_buffer *buf = NULL;
1022 struct inode *btree_inode = root->fs_info->btree_inode;
1023 struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree;
1024 int ret;
1025
1026 buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
1027 if (!buf)
1028 return 0;
1029
1030 set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
1031
1032 ret = read_extent_buffer_pages(io_tree, buf, 0, WAIT_PAGE_LOCK,
1033 btree_get_extent, mirror_num);
1034 if (ret) {
1035 free_extent_buffer(buf);
1036 return ret;
1037 }
1038
1039 if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) {
1040 free_extent_buffer(buf);
1041 return -EIO;
1042 } else if (extent_buffer_uptodate(io_tree, buf, NULL)) {
1043 *eb = buf;
1044 } else {
1045 free_extent_buffer(buf);
1046 }
1047 return 0;
1048}
1049
981struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, 1050struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
982 u64 bytenr, u32 blocksize) 1051 u64 bytenr, u32 blocksize)
983{ 1052{
@@ -1904,6 +1973,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1904 fs_info->trans_no_join = 0; 1973 fs_info->trans_no_join = 0;
1905 fs_info->free_chunk_space = 0; 1974 fs_info->free_chunk_space = 0;
1906 1975
1976 /* readahead state */
1977 INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);
1978 spin_lock_init(&fs_info->reada_lock);
1979
1907 fs_info->thread_pool_size = min_t(unsigned long, 1980 fs_info->thread_pool_size = min_t(unsigned long,
1908 num_online_cpus() + 2, 8); 1981 num_online_cpus() + 2, 8);
1909 1982
@@ -2103,6 +2176,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
2103 btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta", 2176 btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta",
2104 fs_info->thread_pool_size, 2177 fs_info->thread_pool_size,
2105 &fs_info->generic_worker); 2178 &fs_info->generic_worker);
2179 btrfs_init_workers(&fs_info->readahead_workers, "readahead",
2180 fs_info->thread_pool_size,
2181 &fs_info->generic_worker);
2106 2182
2107 /* 2183 /*
2108 * endios are largely parallel and should have a very 2184 * endios are largely parallel and should have a very
@@ -2113,6 +2189,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
2113 2189
2114 fs_info->endio_write_workers.idle_thresh = 2; 2190 fs_info->endio_write_workers.idle_thresh = 2;
2115 fs_info->endio_meta_write_workers.idle_thresh = 2; 2191 fs_info->endio_meta_write_workers.idle_thresh = 2;
2192 fs_info->readahead_workers.idle_thresh = 2;
2116 2193
2117 btrfs_start_workers(&fs_info->workers, 1); 2194 btrfs_start_workers(&fs_info->workers, 1);
2118 btrfs_start_workers(&fs_info->generic_worker, 1); 2195 btrfs_start_workers(&fs_info->generic_worker, 1);
@@ -2126,6 +2203,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
2126 btrfs_start_workers(&fs_info->endio_freespace_worker, 1); 2203 btrfs_start_workers(&fs_info->endio_freespace_worker, 1);
2127 btrfs_start_workers(&fs_info->delayed_workers, 1); 2204 btrfs_start_workers(&fs_info->delayed_workers, 1);
2128 btrfs_start_workers(&fs_info->caching_workers, 1); 2205 btrfs_start_workers(&fs_info->caching_workers, 1);
2206 btrfs_start_workers(&fs_info->readahead_workers, 1);
2129 2207
2130 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 2208 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
2131 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 2209 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -2855,6 +2933,7 @@ int close_ctree(struct btrfs_root *root)
2855 btrfs_stop_workers(&fs_info->submit_workers); 2933 btrfs_stop_workers(&fs_info->submit_workers);
2856 btrfs_stop_workers(&fs_info->delayed_workers); 2934 btrfs_stop_workers(&fs_info->delayed_workers);
2857 btrfs_stop_workers(&fs_info->caching_workers); 2935 btrfs_stop_workers(&fs_info->caching_workers);
2936 btrfs_stop_workers(&fs_info->readahead_workers);
2858 2937
2859 btrfs_close_devices(fs_info->fs_devices); 2938 btrfs_close_devices(fs_info->fs_devices);
2860 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2939 btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@ -3363,6 +3442,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
3363static struct extent_io_ops btree_extent_io_ops = { 3442static struct extent_io_ops btree_extent_io_ops = {
3364 .write_cache_pages_lock_hook = btree_lock_page_hook, 3443 .write_cache_pages_lock_hook = btree_lock_page_hook,
3365 .readpage_end_io_hook = btree_readpage_end_io_hook, 3444 .readpage_end_io_hook = btree_readpage_end_io_hook,
3445 .readpage_io_failed_hook = btree_io_failed_hook,
3366 .submit_bio_hook = btree_submit_bio_hook, 3446 .submit_bio_hook = btree_submit_bio_hook,
3367 /* note we're sharing with inode.c for the merge bio hook */ 3447 /* note we're sharing with inode.c for the merge bio hook */
3368 .merge_bio_hook = btrfs_merge_bio_hook, 3448 .merge_bio_hook = btrfs_merge_bio_hook,