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/btrfs/extent_io.c | |
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/btrfs/extent_io.c')
-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 fe9eb990e443..68260180f587 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 | } |