Btrfs: Limit btree writeback to prevent seeks
authorChris Mason <chris.mason@oracle.com>
Tue, 27 Nov 2007 00:34:41 +0000 (16:34 -0800)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:58 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/disk-io.c
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h

index 3e16cca..28e9ef8 100644 (file)
@@ -210,6 +210,15 @@ static int btree_writepages(struct address_space *mapping,
 {
        struct extent_map_tree *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);
 }
 
index 55f272c..b6a4974 100644 (file)
@@ -1106,6 +1106,45 @@ out:
        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.
  * pages must be locked first.
index 24ddc8c..13c562f 100644 (file)
@@ -113,6 +113,9 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
 int __init extent_map_init(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 bits, int filled);
 int clear_extent_bits(struct extent_map_tree *tree, u64 start, u64 end,