diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:17:04 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | 09e71a326341f40111400c88aaf0498ef622824b (patch) | |
tree | 82e8f8a412a4403155fe17399456d2f8898715c0 | |
parent | 14048ed0c415b8729b194e92c16d31c61628d216 (diff) |
Btrfs: Use an array of pages in the extent buffers to reduce the cost of find_get_page
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r-- | fs/btrfs/disk-io.c | 6 | ||||
-rw-r--r-- | fs/btrfs/extent_map.c | 22 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 4 |
3 files changed, 13 insertions, 19 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index fad9298c6962..0636f79672e9 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -647,20 +647,20 @@ int close_ctree(struct btrfs_root *root) | |||
647 | 647 | ||
648 | int btrfs_buffer_uptodate(struct extent_buffer *buf) | 648 | int btrfs_buffer_uptodate(struct extent_buffer *buf) |
649 | { | 649 | { |
650 | struct inode *btree_inode = buf->first_page->mapping->host; | 650 | struct inode *btree_inode = buf->pages[0]->mapping->host; |
651 | return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf); | 651 | return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf); |
652 | } | 652 | } |
653 | 653 | ||
654 | int btrfs_set_buffer_uptodate(struct extent_buffer *buf) | 654 | int btrfs_set_buffer_uptodate(struct extent_buffer *buf) |
655 | { | 655 | { |
656 | struct inode *btree_inode = buf->first_page->mapping->host; | 656 | struct inode *btree_inode = buf->pages[0]->mapping->host; |
657 | return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, | 657 | return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, |
658 | buf); | 658 | buf); |
659 | } | 659 | } |
660 | 660 | ||
661 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | 661 | void btrfs_mark_buffer_dirty(struct extent_buffer *buf) |
662 | { | 662 | { |
663 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | 663 | struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; |
664 | u64 transid = btrfs_header_generation(buf); | 664 | u64 transid = btrfs_header_generation(buf); |
665 | struct inode *btree_inode = root->fs_info->btree_inode; | 665 | struct inode *btree_inode = root->fs_info->btree_inode; |
666 | 666 | ||
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index ea6ee68ef53c..7ef3397a266d 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -1961,16 +1961,12 @@ static void __free_extent_buffer(struct extent_buffer *eb) | |||
1961 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, int i) | 1961 | static inline struct page *extent_buffer_page(struct extent_buffer *eb, int i) |
1962 | { | 1962 | { |
1963 | struct page *p; | 1963 | struct page *p; |
1964 | if (i == 0) | ||
1965 | return eb->first_page; | ||
1966 | 1964 | ||
1965 | if (i < EXTENT_INLINE_PAGES) | ||
1966 | return eb->pages[i]; | ||
1967 | i += eb->start >> PAGE_CACHE_SHIFT; | 1967 | i += eb->start >> PAGE_CACHE_SHIFT; |
1968 | if (eb->last_page && eb->last_page->index == i) | 1968 | p = find_get_page(eb->pages[0]->mapping, i); |
1969 | return eb->last_page; | ||
1970 | |||
1971 | p = find_get_page(eb->first_page->mapping, i); | ||
1972 | page_cache_release(p); | 1969 | page_cache_release(p); |
1973 | eb->last_page = p; | ||
1974 | return p; | 1970 | return p; |
1975 | } | 1971 | } |
1976 | 1972 | ||
@@ -2012,8 +2008,8 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
2012 | goto fail; | 2008 | goto fail; |
2013 | } | 2009 | } |
2014 | set_page_extent_mapped(p); | 2010 | set_page_extent_mapped(p); |
2015 | if (i == 0) | 2011 | if (i < EXTENT_INLINE_PAGES) |
2016 | eb->first_page = p; | 2012 | eb->pages[i] = p; |
2017 | if (!PageUptodate(p)) | 2013 | if (!PageUptodate(p)) |
2018 | uptodate = 0; | 2014 | uptodate = 0; |
2019 | unlock_page(p); | 2015 | unlock_page(p); |
@@ -2059,8 +2055,8 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
2059 | goto fail; | 2055 | goto fail; |
2060 | } | 2056 | } |
2061 | set_page_extent_mapped(p); | 2057 | set_page_extent_mapped(p); |
2062 | if (i == 0) | 2058 | if (i < EXTENT_INLINE_PAGES) |
2063 | eb->first_page = p; | 2059 | eb->pages[i] = p; |
2064 | if (!PageUptodate(p)) | 2060 | if (!PageUptodate(p)) |
2065 | uptodate = 0; | 2061 | uptodate = 0; |
2066 | unlock_page(p); | 2062 | unlock_page(p); |
@@ -2087,9 +2083,7 @@ void free_extent_buffer(struct extent_buffer *eb) | |||
2087 | 2083 | ||
2088 | num_pages = num_extent_pages(eb->start, eb->len); | 2084 | num_pages = num_extent_pages(eb->start, eb->len); |
2089 | 2085 | ||
2090 | if (eb->first_page) | 2086 | for (i = 0; i < num_pages; i++) { |
2091 | page_cache_release(eb->first_page); | ||
2092 | for (i = 1; i < num_pages; i++) { | ||
2093 | page_cache_release(extent_buffer_page(eb, i)); | 2087 | page_cache_release(extent_buffer_page(eb, i)); |
2094 | } | 2088 | } |
2095 | __free_extent_buffer(eb); | 2089 | __free_extent_buffer(eb); |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 4ef8bdd68348..d74a2b3e3b5d 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -62,6 +62,7 @@ struct extent_state { | |||
62 | struct list_head list; | 62 | struct list_head list; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | #define EXTENT_INLINE_PAGES 32 | ||
65 | struct extent_buffer { | 66 | struct extent_buffer { |
66 | u64 start; | 67 | u64 start; |
67 | unsigned long len; | 68 | unsigned long len; |
@@ -69,13 +70,12 @@ struct extent_buffer { | |||
69 | int flags; | 70 | int flags; |
70 | struct list_head list; | 71 | struct list_head list; |
71 | struct list_head leak_list; | 72 | struct list_head leak_list; |
72 | struct page *first_page; | ||
73 | struct page *last_page; | ||
74 | unsigned long alloc_addr; | 73 | unsigned long alloc_addr; |
75 | char *map_token; | 74 | char *map_token; |
76 | char *kaddr; | 75 | char *kaddr; |
77 | unsigned long map_start; | 76 | unsigned long map_start; |
78 | unsigned long map_len; | 77 | unsigned long map_len; |
78 | struct page *pages[EXTENT_INLINE_PAGES]; | ||
79 | }; | 79 | }; |
80 | 80 | ||
81 | typedef struct extent_map *(get_extent_t)(struct inode *inode, | 81 | typedef struct extent_map *(get_extent_t)(struct inode *inode, |