aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c113
1 files changed, 65 insertions, 48 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index fcf77e1ded40..a55fbe6252de 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -513,6 +513,15 @@ hit_next:
513 WARN_ON(state->end < start); 513 WARN_ON(state->end < start);
514 last_end = state->end; 514 last_end = state->end;
515 515
516 if (state->end < end && !need_resched())
517 next_node = rb_next(&state->rb_node);
518 else
519 next_node = NULL;
520
521 /* the state doesn't have the wanted bits, go ahead */
522 if (!(state->state & bits))
523 goto next;
524
516 /* 525 /*
517 * | ---- desired range ---- | 526 * | ---- desired range ---- |
518 * | state | or 527 * | state | or
@@ -565,20 +574,15 @@ hit_next:
565 goto out; 574 goto out;
566 } 575 }
567 576
568 if (state->end < end && prealloc && !need_resched())
569 next_node = rb_next(&state->rb_node);
570 else
571 next_node = NULL;
572
573 set |= clear_state_bit(tree, state, &bits, wake); 577 set |= clear_state_bit(tree, state, &bits, wake);
578next:
574 if (last_end == (u64)-1) 579 if (last_end == (u64)-1)
575 goto out; 580 goto out;
576 start = last_end + 1; 581 start = last_end + 1;
577 if (start <= end && next_node) { 582 if (start <= end && next_node) {
578 state = rb_entry(next_node, struct extent_state, 583 state = rb_entry(next_node, struct extent_state,
579 rb_node); 584 rb_node);
580 if (state->start == start) 585 goto hit_next;
581 goto hit_next;
582 } 586 }
583 goto search_again; 587 goto search_again;
584 588
@@ -961,8 +965,6 @@ hit_next:
961 965
962 set_state_bits(tree, state, &bits); 966 set_state_bits(tree, state, &bits);
963 clear_state_bit(tree, state, &clear_bits, 0); 967 clear_state_bit(tree, state, &clear_bits, 0);
964
965 merge_state(tree, state);
966 if (last_end == (u64)-1) 968 if (last_end == (u64)-1)
967 goto out; 969 goto out;
968 970
@@ -1007,7 +1009,6 @@ hit_next:
1007 if (state->end <= end) { 1009 if (state->end <= end) {
1008 set_state_bits(tree, state, &bits); 1010 set_state_bits(tree, state, &bits);
1009 clear_state_bit(tree, state, &clear_bits, 0); 1011 clear_state_bit(tree, state, &clear_bits, 0);
1010 merge_state(tree, state);
1011 if (last_end == (u64)-1) 1012 if (last_end == (u64)-1)
1012 goto out; 1013 goto out;
1013 start = last_end + 1; 1014 start = last_end + 1;
@@ -1068,8 +1069,6 @@ hit_next:
1068 1069
1069 set_state_bits(tree, prealloc, &bits); 1070 set_state_bits(tree, prealloc, &bits);
1070 clear_state_bit(tree, prealloc, &clear_bits, 0); 1071 clear_state_bit(tree, prealloc, &clear_bits, 0);
1071
1072 merge_state(tree, prealloc);
1073 prealloc = NULL; 1072 prealloc = NULL;
1074 goto out; 1073 goto out;
1075 } 1074 }
@@ -2154,13 +2153,46 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
2154 "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode, 2153 "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode,
2155 failrec->this_mirror, num_copies, failrec->in_validation); 2154 failrec->this_mirror, num_copies, failrec->in_validation);
2156 2155
2157 tree->ops->submit_bio_hook(inode, read_mode, bio, failrec->this_mirror, 2156 ret = tree->ops->submit_bio_hook(inode, read_mode, bio,
2158 failrec->bio_flags, 0); 2157 failrec->this_mirror,
2159 return 0; 2158 failrec->bio_flags, 0);
2159 return ret;
2160} 2160}
2161 2161
2162/* lots and lots of room for performance fixes in the end_bio funcs */ 2162/* lots and lots of room for performance fixes in the end_bio funcs */
2163 2163
2164int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
2165{
2166 int uptodate = (err == 0);
2167 struct extent_io_tree *tree;
2168 int ret;
2169
2170 tree = &BTRFS_I(page->mapping->host)->io_tree;
2171
2172 if (tree->ops && tree->ops->writepage_end_io_hook) {
2173 ret = tree->ops->writepage_end_io_hook(page, start,
2174 end, NULL, uptodate);
2175 if (ret)
2176 uptodate = 0;
2177 }
2178
2179 if (!uptodate && tree->ops &&
2180 tree->ops->writepage_io_failed_hook) {
2181 ret = tree->ops->writepage_io_failed_hook(NULL, page,
2182 start, end, NULL);
2183 /* Writeback already completed */
2184 if (ret == 0)
2185 return 1;
2186 }
2187
2188 if (!uptodate) {
2189 clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
2190 ClearPageUptodate(page);
2191 SetPageError(page);
2192 }
2193 return 0;
2194}
2195
2164/* 2196/*
2165 * after a writepage IO is done, we need to: 2197 * after a writepage IO is done, we need to:
2166 * clear the uptodate bits on error 2198 * clear the uptodate bits on error
@@ -2172,13 +2204,11 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
2172 */ 2204 */
2173static void end_bio_extent_writepage(struct bio *bio, int err) 2205static void end_bio_extent_writepage(struct bio *bio, int err)
2174{ 2206{
2175 int uptodate = err == 0;
2176 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; 2207 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
2177 struct extent_io_tree *tree; 2208 struct extent_io_tree *tree;
2178 u64 start; 2209 u64 start;
2179 u64 end; 2210 u64 end;
2180 int whole_page; 2211 int whole_page;
2181 int ret;
2182 2212
2183 do { 2213 do {
2184 struct page *page = bvec->bv_page; 2214 struct page *page = bvec->bv_page;
@@ -2195,28 +2225,9 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
2195 2225
2196 if (--bvec >= bio->bi_io_vec) 2226 if (--bvec >= bio->bi_io_vec)
2197 prefetchw(&bvec->bv_page->flags); 2227 prefetchw(&bvec->bv_page->flags);
2198 if (tree->ops && tree->ops->writepage_end_io_hook) {
2199 ret = tree->ops->writepage_end_io_hook(page, start,
2200 end, NULL, uptodate);
2201 if (ret)
2202 uptodate = 0;
2203 }
2204
2205 if (!uptodate && tree->ops &&
2206 tree->ops->writepage_io_failed_hook) {
2207 ret = tree->ops->writepage_io_failed_hook(bio, page,
2208 start, end, NULL);
2209 if (ret == 0) {
2210 uptodate = (err == 0);
2211 continue;
2212 }
2213 }
2214 2228
2215 if (!uptodate) { 2229 if (end_extent_writepage(page, err, start, end))
2216 clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS); 2230 continue;
2217 ClearPageUptodate(page);
2218 SetPageError(page);
2219 }
2220 2231
2221 if (whole_page) 2232 if (whole_page)
2222 end_page_writeback(page); 2233 end_page_writeback(page);
@@ -2779,9 +2790,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2779 delalloc_start = delalloc_end + 1; 2790 delalloc_start = delalloc_end + 1;
2780 continue; 2791 continue;
2781 } 2792 }
2782 tree->ops->fill_delalloc(inode, page, delalloc_start, 2793 ret = tree->ops->fill_delalloc(inode, page,
2783 delalloc_end, &page_started, 2794 delalloc_start,
2784 &nr_written); 2795 delalloc_end,
2796 &page_started,
2797 &nr_written);
2798 BUG_ON(ret);
2785 /* 2799 /*
2786 * delalloc_end is already one less than the total 2800 * delalloc_end is already one less than the total
2787 * length, so we don't subtract one from 2801 * length, so we don't subtract one from
@@ -2818,8 +2832,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2818 if (tree->ops && tree->ops->writepage_start_hook) { 2832 if (tree->ops && tree->ops->writepage_start_hook) {
2819 ret = tree->ops->writepage_start_hook(page, start, 2833 ret = tree->ops->writepage_start_hook(page, start,
2820 page_end); 2834 page_end);
2821 if (ret == -EAGAIN) { 2835 if (ret) {
2822 redirty_page_for_writepage(wbc, page); 2836 /* Fixup worker will requeue */
2837 if (ret == -EBUSY)
2838 wbc->pages_skipped++;
2839 else
2840 redirty_page_for_writepage(wbc, page);
2823 update_nr_written(page, wbc, nr_written); 2841 update_nr_written(page, wbc, nr_written);
2824 unlock_page(page); 2842 unlock_page(page);
2825 ret = 0; 2843 ret = 0;
@@ -3289,7 +3307,7 @@ int try_release_extent_mapping(struct extent_map_tree *map,
3289 len = end - start + 1; 3307 len = end - start + 1;
3290 write_lock(&map->lock); 3308 write_lock(&map->lock);
3291 em = lookup_extent_mapping(map, start, len); 3309 em = lookup_extent_mapping(map, start, len);
3292 if (IS_ERR_OR_NULL(em)) { 3310 if (!em) {
3293 write_unlock(&map->lock); 3311 write_unlock(&map->lock);
3294 break; 3312 break;
3295 } 3313 }
@@ -3853,10 +3871,9 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
3853 num_pages = num_extent_pages(eb->start, eb->len); 3871 num_pages = num_extent_pages(eb->start, eb->len);
3854 clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); 3872 clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
3855 3873
3856 if (eb_straddles_pages(eb)) { 3874 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
3857 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, 3875 cached_state, GFP_NOFS);
3858 cached_state, GFP_NOFS); 3876
3859 }
3860 for (i = 0; i < num_pages; i++) { 3877 for (i = 0; i < num_pages; i++) {
3861 page = extent_buffer_page(eb, i); 3878 page = extent_buffer_page(eb, i);
3862 if (page) 3879 if (page)