diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 139 |
1 files changed, 43 insertions, 96 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 067b1747421b..d418164a35f1 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -254,14 +254,14 @@ static void merge_cb(struct extent_io_tree *tree, struct extent_state *new, | |||
254 | * | 254 | * |
255 | * This should be called with the tree lock held. | 255 | * This should be called with the tree lock held. |
256 | */ | 256 | */ |
257 | static int merge_state(struct extent_io_tree *tree, | 257 | static void merge_state(struct extent_io_tree *tree, |
258 | struct extent_state *state) | 258 | struct extent_state *state) |
259 | { | 259 | { |
260 | struct extent_state *other; | 260 | struct extent_state *other; |
261 | struct rb_node *other_node; | 261 | struct rb_node *other_node; |
262 | 262 | ||
263 | if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) | 263 | if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) |
264 | return 0; | 264 | return; |
265 | 265 | ||
266 | other_node = rb_prev(&state->rb_node); | 266 | other_node = rb_prev(&state->rb_node); |
267 | if (other_node) { | 267 | if (other_node) { |
@@ -287,19 +287,13 @@ static int merge_state(struct extent_io_tree *tree, | |||
287 | free_extent_state(other); | 287 | free_extent_state(other); |
288 | } | 288 | } |
289 | } | 289 | } |
290 | |||
291 | return 0; | ||
292 | } | 290 | } |
293 | 291 | ||
294 | static int set_state_cb(struct extent_io_tree *tree, | 292 | static void set_state_cb(struct extent_io_tree *tree, |
295 | struct extent_state *state, int *bits) | 293 | struct extent_state *state, int *bits) |
296 | { | 294 | { |
297 | if (tree->ops && tree->ops->set_bit_hook) { | 295 | if (tree->ops && tree->ops->set_bit_hook) |
298 | return tree->ops->set_bit_hook(tree->mapping->host, | 296 | tree->ops->set_bit_hook(tree->mapping->host, state, bits); |
299 | state, bits); | ||
300 | } | ||
301 | |||
302 | return 0; | ||
303 | } | 297 | } |
304 | 298 | ||
305 | static void clear_state_cb(struct extent_io_tree *tree, | 299 | static void clear_state_cb(struct extent_io_tree *tree, |
@@ -309,6 +303,9 @@ static void clear_state_cb(struct extent_io_tree *tree, | |||
309 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); | 303 | tree->ops->clear_bit_hook(tree->mapping->host, state, bits); |
310 | } | 304 | } |
311 | 305 | ||
306 | static void set_state_bits(struct extent_io_tree *tree, | ||
307 | struct extent_state *state, int *bits); | ||
308 | |||
312 | /* | 309 | /* |
313 | * insert an extent_state struct into the tree. 'bits' are set on the | 310 | * insert an extent_state struct into the tree. 'bits' are set on the |
314 | * struct before it is inserted. | 311 | * struct before it is inserted. |
@@ -324,8 +321,6 @@ static int insert_state(struct extent_io_tree *tree, | |||
324 | int *bits) | 321 | int *bits) |
325 | { | 322 | { |
326 | struct rb_node *node; | 323 | struct rb_node *node; |
327 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | ||
328 | int ret; | ||
329 | 324 | ||
330 | if (end < start) { | 325 | if (end < start) { |
331 | printk(KERN_ERR "btrfs end < start %llu %llu\n", | 326 | printk(KERN_ERR "btrfs end < start %llu %llu\n", |
@@ -335,13 +330,9 @@ static int insert_state(struct extent_io_tree *tree, | |||
335 | } | 330 | } |
336 | state->start = start; | 331 | state->start = start; |
337 | state->end = end; | 332 | state->end = end; |
338 | ret = set_state_cb(tree, state, bits); | ||
339 | if (ret) | ||
340 | return ret; | ||
341 | 333 | ||
342 | if (bits_to_set & EXTENT_DIRTY) | 334 | set_state_bits(tree, state, bits); |
343 | tree->dirty_bytes += end - start + 1; | 335 | |
344 | state->state |= bits_to_set; | ||
345 | node = tree_insert(&tree->state, end, &state->rb_node); | 336 | node = tree_insert(&tree->state, end, &state->rb_node); |
346 | if (node) { | 337 | if (node) { |
347 | struct extent_state *found; | 338 | struct extent_state *found; |
@@ -357,13 +348,11 @@ static int insert_state(struct extent_io_tree *tree, | |||
357 | return 0; | 348 | return 0; |
358 | } | 349 | } |
359 | 350 | ||
360 | static int split_cb(struct extent_io_tree *tree, struct extent_state *orig, | 351 | static void split_cb(struct extent_io_tree *tree, struct extent_state *orig, |
361 | u64 split) | 352 | u64 split) |
362 | { | 353 | { |
363 | if (tree->ops && tree->ops->split_extent_hook) | 354 | if (tree->ops && tree->ops->split_extent_hook) |
364 | return tree->ops->split_extent_hook(tree->mapping->host, | 355 | tree->ops->split_extent_hook(tree->mapping->host, orig, split); |
365 | orig, split); | ||
366 | return 0; | ||
367 | } | 356 | } |
368 | 357 | ||
369 | /* | 358 | /* |
@@ -659,34 +648,25 @@ again: | |||
659 | if (start > end) | 648 | if (start > end) |
660 | break; | 649 | break; |
661 | 650 | ||
662 | if (need_resched()) { | 651 | cond_resched_lock(&tree->lock); |
663 | spin_unlock(&tree->lock); | ||
664 | cond_resched(); | ||
665 | spin_lock(&tree->lock); | ||
666 | } | ||
667 | } | 652 | } |
668 | out: | 653 | out: |
669 | spin_unlock(&tree->lock); | 654 | spin_unlock(&tree->lock); |
670 | return 0; | 655 | return 0; |
671 | } | 656 | } |
672 | 657 | ||
673 | static int set_state_bits(struct extent_io_tree *tree, | 658 | static void set_state_bits(struct extent_io_tree *tree, |
674 | struct extent_state *state, | 659 | struct extent_state *state, |
675 | int *bits) | 660 | int *bits) |
676 | { | 661 | { |
677 | int ret; | ||
678 | int bits_to_set = *bits & ~EXTENT_CTLBITS; | 662 | int bits_to_set = *bits & ~EXTENT_CTLBITS; |
679 | 663 | ||
680 | ret = set_state_cb(tree, state, bits); | 664 | set_state_cb(tree, state, bits); |
681 | if (ret) | ||
682 | return ret; | ||
683 | if ((bits_to_set & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { | 665 | if ((bits_to_set & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { |
684 | u64 range = state->end - state->start + 1; | 666 | u64 range = state->end - state->start + 1; |
685 | tree->dirty_bytes += range; | 667 | tree->dirty_bytes += range; |
686 | } | 668 | } |
687 | state->state |= bits_to_set; | 669 | state->state |= bits_to_set; |
688 | |||
689 | return 0; | ||
690 | } | 670 | } |
691 | 671 | ||
692 | static void cache_state(struct extent_state *state, | 672 | static void cache_state(struct extent_state *state, |
@@ -779,9 +759,7 @@ hit_next: | |||
779 | goto out; | 759 | goto out; |
780 | } | 760 | } |
781 | 761 | ||
782 | err = set_state_bits(tree, state, &bits); | 762 | set_state_bits(tree, state, &bits); |
783 | if (err) | ||
784 | goto out; | ||
785 | 763 | ||
786 | cache_state(state, cached_state); | 764 | cache_state(state, cached_state); |
787 | merge_state(tree, state); | 765 | merge_state(tree, state); |
@@ -830,9 +808,7 @@ hit_next: | |||
830 | if (err) | 808 | if (err) |
831 | goto out; | 809 | goto out; |
832 | if (state->end <= end) { | 810 | if (state->end <= end) { |
833 | err = set_state_bits(tree, state, &bits); | 811 | set_state_bits(tree, state, &bits); |
834 | if (err) | ||
835 | goto out; | ||
836 | cache_state(state, cached_state); | 812 | cache_state(state, cached_state); |
837 | merge_state(tree, state); | 813 | merge_state(tree, state); |
838 | if (last_end == (u64)-1) | 814 | if (last_end == (u64)-1) |
@@ -893,11 +869,7 @@ hit_next: | |||
893 | err = split_state(tree, state, prealloc, end + 1); | 869 | err = split_state(tree, state, prealloc, end + 1); |
894 | BUG_ON(err == -EEXIST); | 870 | BUG_ON(err == -EEXIST); |
895 | 871 | ||
896 | err = set_state_bits(tree, prealloc, &bits); | 872 | set_state_bits(tree, prealloc, &bits); |
897 | if (err) { | ||
898 | prealloc = NULL; | ||
899 | goto out; | ||
900 | } | ||
901 | cache_state(prealloc, cached_state); | 873 | cache_state(prealloc, cached_state); |
902 | merge_state(tree, prealloc); | 874 | merge_state(tree, prealloc); |
903 | prealloc = NULL; | 875 | prealloc = NULL; |
@@ -1059,46 +1031,6 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) | |||
1059 | return 0; | 1031 | return 0; |
1060 | } | 1032 | } |
1061 | 1033 | ||
1062 | /* | ||
1063 | * find the first offset in the io tree with 'bits' set. zero is | ||
1064 | * returned if we find something, and *start_ret and *end_ret are | ||
1065 | * set to reflect the state struct that was found. | ||
1066 | * | ||
1067 | * If nothing was found, 1 is returned, < 0 on error | ||
1068 | */ | ||
1069 | int find_first_extent_bit(struct extent_io_tree *tree, u64 start, | ||
1070 | u64 *start_ret, u64 *end_ret, int bits) | ||
1071 | { | ||
1072 | struct rb_node *node; | ||
1073 | struct extent_state *state; | ||
1074 | int ret = 1; | ||
1075 | |||
1076 | spin_lock(&tree->lock); | ||
1077 | /* | ||
1078 | * this search will find all the extents that end after | ||
1079 | * our range starts. | ||
1080 | */ | ||
1081 | node = tree_search(tree, start); | ||
1082 | if (!node) | ||
1083 | goto out; | ||
1084 | |||
1085 | while (1) { | ||
1086 | state = rb_entry(node, struct extent_state, rb_node); | ||
1087 | if (state->end >= start && (state->state & bits)) { | ||
1088 | *start_ret = state->start; | ||
1089 | *end_ret = state->end; | ||
1090 | ret = 0; | ||
1091 | break; | ||
1092 | } | ||
1093 | node = rb_next(node); | ||
1094 | if (!node) | ||
1095 | break; | ||
1096 | } | ||
1097 | out: | ||
1098 | spin_unlock(&tree->lock); | ||
1099 | return ret; | ||
1100 | } | ||
1101 | |||
1102 | /* find the first state struct with 'bits' set after 'start', and | 1034 | /* find the first state struct with 'bits' set after 'start', and |
1103 | * return it. tree->lock must be held. NULL will returned if | 1035 | * return it. tree->lock must be held. NULL will returned if |
1104 | * nothing was found after 'start' | 1036 | * nothing was found after 'start' |
@@ -1131,6 +1063,30 @@ out: | |||
1131 | } | 1063 | } |
1132 | 1064 | ||
1133 | /* | 1065 | /* |
1066 | * find the first offset in the io tree with 'bits' set. zero is | ||
1067 | * returned if we find something, and *start_ret and *end_ret are | ||
1068 | * set to reflect the state struct that was found. | ||
1069 | * | ||
1070 | * If nothing was found, 1 is returned, < 0 on error | ||
1071 | */ | ||
1072 | int find_first_extent_bit(struct extent_io_tree *tree, u64 start, | ||
1073 | u64 *start_ret, u64 *end_ret, int bits) | ||
1074 | { | ||
1075 | struct extent_state *state; | ||
1076 | int ret = 1; | ||
1077 | |||
1078 | spin_lock(&tree->lock); | ||
1079 | state = find_first_extent_bit_state(tree, start, bits); | ||
1080 | if (state) { | ||
1081 | *start_ret = state->start; | ||
1082 | *end_ret = state->end; | ||
1083 | ret = 0; | ||
1084 | } | ||
1085 | spin_unlock(&tree->lock); | ||
1086 | return ret; | ||
1087 | } | ||
1088 | |||
1089 | /* | ||
1134 | * find a contiguous range of bytes in the file marked as delalloc, not | 1090 | * find a contiguous range of bytes in the file marked as delalloc, not |
1135 | * more than 'max_bytes'. start and end are used to return the range, | 1091 | * more than 'max_bytes'. start and end are used to return the range, |
1136 | * | 1092 | * |
@@ -2546,7 +2502,6 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page, | |||
2546 | struct writeback_control *wbc) | 2502 | struct writeback_control *wbc) |
2547 | { | 2503 | { |
2548 | int ret; | 2504 | int ret; |
2549 | struct address_space *mapping = page->mapping; | ||
2550 | struct extent_page_data epd = { | 2505 | struct extent_page_data epd = { |
2551 | .bio = NULL, | 2506 | .bio = NULL, |
2552 | .tree = tree, | 2507 | .tree = tree, |
@@ -2554,17 +2509,9 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page, | |||
2554 | .extent_locked = 0, | 2509 | .extent_locked = 0, |
2555 | .sync_io = wbc->sync_mode == WB_SYNC_ALL, | 2510 | .sync_io = wbc->sync_mode == WB_SYNC_ALL, |
2556 | }; | 2511 | }; |
2557 | struct writeback_control wbc_writepages = { | ||
2558 | .sync_mode = wbc->sync_mode, | ||
2559 | .nr_to_write = 64, | ||
2560 | .range_start = page_offset(page) + PAGE_CACHE_SIZE, | ||
2561 | .range_end = (loff_t)-1, | ||
2562 | }; | ||
2563 | 2512 | ||
2564 | ret = __extent_writepage(page, wbc, &epd); | 2513 | ret = __extent_writepage(page, wbc, &epd); |
2565 | 2514 | ||
2566 | extent_write_cache_pages(tree, mapping, &wbc_writepages, | ||
2567 | __extent_writepage, &epd, flush_write_bio); | ||
2568 | flush_epd_write_bio(&epd); | 2515 | flush_epd_write_bio(&epd); |
2569 | return ret; | 2516 | return ret; |
2570 | } | 2517 | } |