Linux Kernels

Btrfs: Limit btree writeback to prevent seeks

This change “Btrfs: Limit btree writeback to prevent seeks” (commit 793955b) in Linux kernel is authored by Chris Mason <chris.mason [at] oracle.com> on Mon Nov 26 16:34:41 2007 -0800.

Description of "Btrfs: Limit btree writeback to prevent seeks"

The change “Btrfs: Limit btree writeback to prevent seeks” introduces changes as follows.

Btrfs: Limit btree writeback to prevent seeks

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Linux kernel releases containing commit 793955b

The Linux kernel releases containing this commit are as follows.

Linux kernel code changes from "Btrfs: Limit btree writeback to prevent seeks"

There are 51 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 fs/btrfs/disk-io.c    |  9 +++++++++
 fs/btrfs/extent_map.c | 39 +++++++++++++++++++++++++++++++++++++++
 fs/btrfs/extent_map.h |  3 +++
 3 files changed, 51 insertions(+)
 
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,
 {
 	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);
 }
 
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 @@ u64 find_lock_delalloc_range(struct extent_map_tree *tree,
 	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.
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,
 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,

The commit for this change in Linux stable tree is 793955b (patch).

Last modified: 2020/01/11 09:50