Btrfs: Limit btree writeback to prevent seeks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
Родитель
015a739c7c
Коммит
793955bca6
|
@ -210,6 +210,15 @@ static int btree_writepages(struct address_space *mapping,
|
||||||
{
|
{
|
||||||
struct extent_map_tree *tree;
|
struct extent_map_tree *tree;
|
||||||
tree = &BTRFS_I(mapping->host)->extent_tree;
|
tree = &BTRFS_I(mapping->host)->extent_tree;
|
||||||
|
if (wbc->sync_mode == WB_SYNC_NONE) {
|
||||||
|
u64 num_dirty;
|
||||||
|
u64 start = 0;
|
||||||
|
unsigned long thresh = 96 * 1024 * 1024;
|
||||||
|
num_dirty = count_range_bits(tree, &start, thresh, EXTENT_DIRTY);
|
||||||
|
if (num_dirty < thresh) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return extent_writepages(tree, mapping, btree_get_extent, wbc);
|
return extent_writepages(tree, mapping, btree_get_extent, wbc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1106,6 +1106,45 @@ out:
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 count_range_bits(struct extent_map_tree *tree,
|
||||||
|
u64 *start, u64 max_bytes, unsigned long bits)
|
||||||
|
{
|
||||||
|
struct rb_node *node;
|
||||||
|
struct extent_state *state;
|
||||||
|
u64 cur_start = *start;
|
||||||
|
u64 total_bytes = 0;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
write_lock_irq(&tree->lock);
|
||||||
|
/*
|
||||||
|
* this search will find all the extents that end after
|
||||||
|
* our range starts.
|
||||||
|
*/
|
||||||
|
node = tree_search(&tree->state, cur_start);
|
||||||
|
if (!node || IS_ERR(node)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
state = rb_entry(node, struct extent_state, rb_node);
|
||||||
|
if ((state->state & bits)) {
|
||||||
|
total_bytes += state->end - state->start + 1;
|
||||||
|
if (total_bytes >= max_bytes)
|
||||||
|
break;
|
||||||
|
if (!found) {
|
||||||
|
*start = state->start;
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = rb_next(node);
|
||||||
|
if (!node)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
write_unlock_irq(&tree->lock);
|
||||||
|
return total_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* helper function to lock both pages and extents in the tree.
|
* helper function to lock both pages and extents in the tree.
|
||||||
* pages must be locked first.
|
* pages must be locked first.
|
||||||
|
|
|
@ -113,6 +113,9 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
|
||||||
int __init extent_map_init(void);
|
int __init extent_map_init(void);
|
||||||
void __exit extent_map_exit(void);
|
void __exit extent_map_exit(void);
|
||||||
|
|
||||||
|
u64 count_range_bits(struct extent_map_tree *tree,
|
||||||
|
u64 *start, u64 max_bytes, unsigned long bits);
|
||||||
|
|
||||||
int test_range_bit(struct extent_map_tree *tree, u64 start, u64 end,
|
int test_range_bit(struct extent_map_tree *tree, u64 start, u64 end,
|
||||||
int bits, int filled);
|
int bits, int filled);
|
||||||
int clear_extent_bits(struct extent_map_tree *tree, u64 start, u64 end,
|
int clear_extent_bits(struct extent_map_tree *tree, u64 start, u64 end,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче