diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-11-26 19:34:41 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | 793955bca66c99defdffc857ae6eb7e8431d6bbe (patch) | |
tree | 2f8376247033fced7289038b8d82e10a6cc55f22 /fs/btrfs | |
parent | 015a739c7c238768fbfa4eea8ea2ebc1a35e7bb1 (diff) |
Btrfs: Limit btree writeback to prevent seeks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/disk-io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 39 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 3 |
3 files changed, 51 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3e16cca72b49..28e9ef8a3253 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -210,6 +210,15 @@ static int btree_writepages(struct address_space *mapping, | |||
210 | { | 210 | { |
211 | struct extent_map_tree *tree; | 211 | struct extent_map_tree *tree; |
212 | tree = &BTRFS_I(mapping->host)->extent_tree; | 212 | tree = &BTRFS_I(mapping->host)->extent_tree; |
213 | if (wbc->sync_mode == WB_SYNC_NONE) { | ||
214 | u64 num_dirty; | ||
215 | u64 start = 0; | ||
216 | unsigned long thresh = 96 * 1024 * 1024; | ||
217 | num_dirty = count_range_bits(tree, &start, thresh, EXTENT_DIRTY); | ||
218 | if (num_dirty < thresh) { | ||
219 | return 0; | ||
220 | } | ||
221 | } | ||
213 | return extent_writepages(tree, mapping, btree_get_extent, wbc); | 222 | return extent_writepages(tree, mapping, btree_get_extent, wbc); |
214 | } | 223 | } |
215 | 224 | ||
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 55f272c335c6..b6a4974ecc23 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -1106,6 +1106,45 @@ out: | |||
1106 | return found; | 1106 | return found; |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | u64 count_range_bits(struct extent_map_tree *tree, | ||
1110 | u64 *start, u64 max_bytes, unsigned long bits) | ||
1111 | { | ||
1112 | struct rb_node *node; | ||
1113 | struct extent_state *state; | ||
1114 | u64 cur_start = *start; | ||
1115 | u64 total_bytes = 0; | ||
1116 | int found = 0; | ||
1117 | |||
1118 | write_lock_irq(&tree->lock); | ||
1119 | /* | ||
1120 | * this search will find all the extents that end after | ||
1121 | * our range starts. | ||
1122 | */ | ||
1123 | node = tree_search(&tree->state, cur_start); | ||
1124 | if (!node || IS_ERR(node)) { | ||
1125 | goto out; | ||
1126 | } | ||
1127 | |||
1128 | while(1) { | ||
1129 | state = rb_entry(node, struct extent_state, rb_node); | ||
1130 | if ((state->state & bits)) { | ||
1131 | total_bytes += state->end - state->start + 1; | ||
1132 | if (total_bytes >= max_bytes) | ||
1133 | break; | ||
1134 | if (!found) { | ||
1135 | *start = state->start; | ||
1136 | found = 1; | ||
1137 | } | ||
1138 | } | ||
1139 | node = rb_next(node); | ||
1140 | if (!node) | ||
1141 | break; | ||
1142 | } | ||
1143 | out: | ||
1144 | write_unlock_irq(&tree->lock); | ||
1145 | return total_bytes; | ||
1146 | } | ||
1147 | |||
1109 | /* | 1148 | /* |
1110 | * helper function to lock both pages and extents in the tree. | 1149 | * helper function to lock both pages and extents in the tree. |
1111 | * pages must be locked first. | 1150 | * pages must be locked first. |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 24ddc8c93461..13c562f7cb6f 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -113,6 +113,9 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page, | |||
113 | int __init extent_map_init(void); | 113 | int __init extent_map_init(void); |
114 | void __exit extent_map_exit(void); | 114 | void __exit extent_map_exit(void); |
115 | 115 | ||
116 | u64 count_range_bits(struct extent_map_tree *tree, | ||
117 | u64 *start, u64 max_bytes, unsigned long bits); | ||
118 | |||
116 | int test_range_bit(struct extent_map_tree *tree, u64 start, u64 end, | 119 | int test_range_bit(struct extent_map_tree *tree, u64 start, u64 end, |
117 | int bits, int filled); | 120 | int bits, int filled); |
118 | int clear_extent_bits(struct extent_map_tree *tree, u64 start, u64 end, | 121 | int clear_extent_bits(struct extent_map_tree *tree, u64 start, u64 end, |