Skip to content

Commit

Permalink
Btrfs: reduce extent_state lock contention for metadata
Browse files Browse the repository at this point in the history
For metadata buffers that don't straddle pages (all of them), btrfs
can safely use the page uptodate bits and extent_buffer uptodate bit
instead of needing to use the extent_state tree.

This greatly reduces contention on the state tree lock.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Jul 27, 2011
1 parent 31533fb commit 19b6caf
Showing 1 changed file with 41 additions and 14 deletions.
55 changes: 41 additions & 14 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,22 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
return was_dirty;
}

static int __eb_straddles_pages(u64 start, u64 len)
{
if (len < PAGE_CACHE_SIZE)
return 1;
if (start & (PAGE_CACHE_SIZE - 1))
return 1;
if ((start + len) & (PAGE_CACHE_SIZE - 1))
return 1;
return 0;
}

static int eb_straddles_pages(struct extent_buffer *eb)
{
return __eb_straddles_pages(eb->start, eb->len);
}

int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
struct extent_buffer *eb,
struct extent_state **cached_state)
Expand All @@ -3279,8 +3295,10 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
num_pages = num_extent_pages(eb->start, eb->len);
clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);

clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
cached_state, GFP_NOFS);
if (eb_straddles_pages(eb)) {
clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
cached_state, GFP_NOFS);
}
for (i = 0; i < num_pages; i++) {
page = extent_buffer_page(eb, i);
if (page)
Expand All @@ -3298,8 +3316,10 @@ int set_extent_buffer_uptodate(struct extent_io_tree *tree,

num_pages = num_extent_pages(eb->start, eb->len);

set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
NULL, GFP_NOFS);
if (eb_straddles_pages(eb)) {
set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
NULL, GFP_NOFS);
}
for (i = 0; i < num_pages; i++) {
page = extent_buffer_page(eb, i);
if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) ||
Expand All @@ -3322,9 +3342,12 @@ int extent_range_uptodate(struct extent_io_tree *tree,
int uptodate;
unsigned long index;

ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL);
if (ret)
return 1;
if (__eb_straddles_pages(start, end - start + 1)) {
ret = test_range_bit(tree, start, end,
EXTENT_UPTODATE, 1, NULL);
if (ret)
return 1;
}
while (start <= end) {
index = start >> PAGE_CACHE_SHIFT;
page = find_get_page(tree->mapping, index);
Expand Down Expand Up @@ -3352,10 +3375,12 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
return 1;

ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
EXTENT_UPTODATE, 1, cached_state);
if (ret)
return ret;
if (eb_straddles_pages(eb)) {
ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
EXTENT_UPTODATE, 1, cached_state);
if (ret)
return ret;
}

num_pages = num_extent_pages(eb->start, eb->len);
for (i = 0; i < num_pages; i++) {
Expand Down Expand Up @@ -3388,9 +3413,11 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
return 0;

if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
EXTENT_UPTODATE, 1, NULL)) {
return 0;
if (eb_straddles_pages(eb)) {
if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
EXTENT_UPTODATE, 1, NULL)) {
return 0;
}
}

if (start) {
Expand Down

0 comments on commit 19b6caf

Please sign in to comment.