diff options
| author | Yan Zheng <zheng.yan@oracle.com> | 2009-05-27 09:16:03 -0400 |
|---|---|---|
| committer | Chris Mason <chris.mason@oracle.com> | 2009-06-10 11:29:46 -0400 |
| commit | 5c939df56c3ea018b58e5aa76181284c2053d699 (patch) | |
| tree | 6d97449faa69c96998833fcb56a3b65050d34354 /fs | |
| parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff) | |
btrfs: Fix set/clear_extent_bit for 'end == (u64)-1'
There are some 'start = state->end + 1;' like code in set_extent_bit
and clear_extent_bit. They overflow when end == (u64)-1.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/extent_io.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index fe9eb990e44..68260180f58 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -476,6 +476,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, | |||
| 476 | struct extent_state *state; | 476 | struct extent_state *state; |
| 477 | struct extent_state *prealloc = NULL; | 477 | struct extent_state *prealloc = NULL; |
| 478 | struct rb_node *node; | 478 | struct rb_node *node; |
| 479 | u64 last_end; | ||
| 479 | int err; | 480 | int err; |
| 480 | int set = 0; | 481 | int set = 0; |
| 481 | 482 | ||
| @@ -498,6 +499,7 @@ again: | |||
| 498 | if (state->start > end) | 499 | if (state->start > end) |
| 499 | goto out; | 500 | goto out; |
| 500 | WARN_ON(state->end < start); | 501 | WARN_ON(state->end < start); |
| 502 | last_end = state->end; | ||
| 501 | 503 | ||
| 502 | /* | 504 | /* |
| 503 | * | ---- desired range ---- | | 505 | * | ---- desired range ---- | |
| @@ -524,9 +526,11 @@ again: | |||
| 524 | if (err) | 526 | if (err) |
| 525 | goto out; | 527 | goto out; |
| 526 | if (state->end <= end) { | 528 | if (state->end <= end) { |
| 527 | start = state->end + 1; | ||
| 528 | set |= clear_state_bit(tree, state, bits, | 529 | set |= clear_state_bit(tree, state, bits, |
| 529 | wake, delete); | 530 | wake, delete); |
| 531 | if (last_end == (u64)-1) | ||
| 532 | goto out; | ||
| 533 | start = last_end + 1; | ||
| 530 | } else { | 534 | } else { |
| 531 | start = state->start; | 535 | start = state->start; |
| 532 | } | 536 | } |
| @@ -552,8 +556,10 @@ again: | |||
| 552 | goto out; | 556 | goto out; |
| 553 | } | 557 | } |
| 554 | 558 | ||
| 555 | start = state->end + 1; | ||
| 556 | set |= clear_state_bit(tree, state, bits, wake, delete); | 559 | set |= clear_state_bit(tree, state, bits, wake, delete); |
| 560 | if (last_end == (u64)-1) | ||
| 561 | goto out; | ||
| 562 | start = last_end + 1; | ||
| 557 | goto search_again; | 563 | goto search_again; |
| 558 | 564 | ||
| 559 | out: | 565 | out: |
| @@ -707,8 +713,10 @@ again: | |||
| 707 | goto out; | 713 | goto out; |
| 708 | } | 714 | } |
| 709 | set_state_bits(tree, state, bits); | 715 | set_state_bits(tree, state, bits); |
| 710 | start = state->end + 1; | ||
| 711 | merge_state(tree, state); | 716 | merge_state(tree, state); |
| 717 | if (last_end == (u64)-1) | ||
| 718 | goto out; | ||
| 719 | start = last_end + 1; | ||
| 712 | goto search_again; | 720 | goto search_again; |
| 713 | } | 721 | } |
| 714 | 722 | ||
| @@ -742,8 +750,10 @@ again: | |||
| 742 | goto out; | 750 | goto out; |
| 743 | if (state->end <= end) { | 751 | if (state->end <= end) { |
| 744 | set_state_bits(tree, state, bits); | 752 | set_state_bits(tree, state, bits); |
| 745 | start = state->end + 1; | ||
| 746 | merge_state(tree, state); | 753 | merge_state(tree, state); |
| 754 | if (last_end == (u64)-1) | ||
| 755 | goto out; | ||
| 756 | start = last_end + 1; | ||
| 747 | } else { | 757 | } else { |
| 748 | start = state->start; | 758 | start = state->start; |
| 749 | } | 759 | } |
