aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-10-15 16:19:22 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:56 -0400
commit19c00ddcc31ad4bdfb86b57085e06d6135b9b1d7 (patch)
treea48cbaac47070057912c1b35d270b61b7e14386c /fs/btrfs/extent_map.c
parent0f82731fc56448c2733f58e1f5db6c2cbfc90652 (diff)
Btrfs: Add back metadata checksumming
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c83
1 files changed, 68 insertions, 15 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index f8aaba8a30a..2a8bc4bd43a 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -81,7 +81,7 @@ void extent_map_tree_init(struct extent_map_tree *tree,
81} 81}
82EXPORT_SYMBOL(extent_map_tree_init); 82EXPORT_SYMBOL(extent_map_tree_init);
83 83
84void extent_map_tree_cleanup(struct extent_map_tree *tree) 84void extent_map_tree_empty_lru(struct extent_map_tree *tree)
85{ 85{
86 struct extent_buffer *eb; 86 struct extent_buffer *eb;
87 while(!list_empty(&tree->buffer_lru)) { 87 while(!list_empty(&tree->buffer_lru)) {
@@ -91,7 +91,7 @@ void extent_map_tree_cleanup(struct extent_map_tree *tree)
91 free_extent_buffer(eb); 91 free_extent_buffer(eb);
92 } 92 }
93} 93}
94EXPORT_SYMBOL(extent_map_tree_cleanup); 94EXPORT_SYMBOL(extent_map_tree_empty_lru);
95 95
96struct extent_map *alloc_extent_map(gfp_t mask) 96struct extent_map *alloc_extent_map(gfp_t mask)
97{ 97{
@@ -1464,7 +1464,7 @@ void set_page_extent_mapped(struct page *page)
1464 if (!PagePrivate(page)) { 1464 if (!PagePrivate(page)) {
1465 SetPagePrivate(page); 1465 SetPagePrivate(page);
1466 WARN_ON(!page->mapping->a_ops->invalidatepage); 1466 WARN_ON(!page->mapping->a_ops->invalidatepage);
1467 set_page_private(page, 1); 1467 set_page_private(page, EXTENT_PAGE_PRIVATE);
1468 page_cache_get(page); 1468 page_cache_get(page);
1469 } 1469 }
1470} 1470}
@@ -1979,8 +1979,9 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_map_tree *tree,
1979 1979
1980 spin_lock(&tree->lru_lock); 1980 spin_lock(&tree->lru_lock);
1981 eb = find_lru(tree, start, len); 1981 eb = find_lru(tree, start, len);
1982 if (eb) 1982 if (eb) {
1983 goto lru_add; 1983 goto lru_add;
1984 }
1984 spin_unlock(&tree->lru_lock); 1985 spin_unlock(&tree->lru_lock);
1985 1986
1986 if (eb) { 1987 if (eb) {
@@ -2007,6 +2008,7 @@ static void __free_extent_buffer(struct extent_buffer *eb)
2007 2008
2008struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, 2009struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
2009 u64 start, unsigned long len, 2010 u64 start, unsigned long len,
2011 struct page *page0,
2010 gfp_t mask) 2012 gfp_t mask)
2011{ 2013{
2012 unsigned long num_pages = num_extent_pages(start, len); 2014 unsigned long num_pages = num_extent_pages(start, len);
@@ -2024,7 +2026,18 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
2024 if (eb->flags & EXTENT_BUFFER_FILLED) 2026 if (eb->flags & EXTENT_BUFFER_FILLED)
2025 return eb; 2027 return eb;
2026 2028
2027 for (i = 0; i < num_pages; i++, index++) { 2029 if (page0) {
2030 eb->first_page = page0;
2031 i = 1;
2032 index++;
2033 page_cache_get(page0);
2034 set_page_extent_mapped(page0);
2035 set_page_private(page0, EXTENT_PAGE_PRIVATE_FIRST_PAGE |
2036 len << 2);
2037 } else {
2038 i = 0;
2039 }
2040 for (; i < num_pages; i++, index++) {
2028 p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM); 2041 p = find_or_create_page(mapping, index, mask | __GFP_HIGHMEM);
2029 if (!p) { 2042 if (!p) {
2030 WARN_ON(1); 2043 WARN_ON(1);
@@ -2036,8 +2049,13 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
2036 goto fail; 2049 goto fail;
2037 } 2050 }
2038 set_page_extent_mapped(p); 2051 set_page_extent_mapped(p);
2039 if (i == 0) 2052 if (i == 0) {
2040 eb->first_page = p; 2053 eb->first_page = p;
2054 set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE |
2055 len << 2);
2056 } else {
2057 set_page_private(p, EXTENT_PAGE_PRIVATE);
2058 }
2041 if (!PageUptodate(p)) 2059 if (!PageUptodate(p))
2042 uptodate = 0; 2060 uptodate = 0;
2043 unlock_page(p); 2061 unlock_page(p);
@@ -2057,8 +2075,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
2057 gfp_t mask) 2075 gfp_t mask)
2058{ 2076{
2059 unsigned long num_pages = num_extent_pages(start, len); 2077 unsigned long num_pages = num_extent_pages(start, len);
2060 unsigned long i; 2078 unsigned long i; unsigned long index = start >> PAGE_CACHE_SHIFT;
2061 unsigned long index = start >> PAGE_CACHE_SHIFT;
2062 struct extent_buffer *eb; 2079 struct extent_buffer *eb;
2063 struct page *p; 2080 struct page *p;
2064 struct address_space *mapping = tree->mapping; 2081 struct address_space *mapping = tree->mapping;
@@ -2082,8 +2099,15 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
2082 goto fail; 2099 goto fail;
2083 } 2100 }
2084 set_page_extent_mapped(p); 2101 set_page_extent_mapped(p);
2085 if (i == 0) 2102
2103 if (i == 0) {
2086 eb->first_page = p; 2104 eb->first_page = p;
2105 set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE |
2106 len << 2);
2107 } else {
2108 set_page_private(p, EXTENT_PAGE_PRIVATE);
2109 }
2110
2087 if (!PageUptodate(p)) 2111 if (!PageUptodate(p))
2088 uptodate = 0; 2112 uptodate = 0;
2089 unlock_page(p); 2113 unlock_page(p);
@@ -2174,7 +2198,21 @@ int set_extent_buffer_dirty(struct extent_map_tree *tree,
2174 2198
2175 num_pages = num_extent_pages(eb->start, eb->len); 2199 num_pages = num_extent_pages(eb->start, eb->len);
2176 for (i = 0; i < num_pages; i++) { 2200 for (i = 0; i < num_pages; i++) {
2201 struct page *page = extent_buffer_page(eb, i);
2202 /* writepage may need to do something special for the
2203 * first page, we have to make sure page->private is
2204 * properly set. releasepage may drop page->private
2205 * on us if the page isn't already dirty.
2206 */
2207 if (i == 0) {
2208 lock_page(page);
2209 set_page_private(page,
2210 EXTENT_PAGE_PRIVATE_FIRST_PAGE |
2211 eb->len << 2);
2212 }
2177 __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); 2213 __set_page_dirty_nobuffers(extent_buffer_page(eb, i));
2214 if (i == 0)
2215 unlock_page(page);
2178 } 2216 }
2179 return set_extent_dirty(tree, eb->start, 2217 return set_extent_dirty(tree, eb->start,
2180 eb->start + eb->len - 1, GFP_NOFS); 2218 eb->start + eb->len - 1, GFP_NOFS);
@@ -2217,9 +2255,12 @@ int extent_buffer_uptodate(struct extent_map_tree *tree,
2217EXPORT_SYMBOL(extent_buffer_uptodate); 2255EXPORT_SYMBOL(extent_buffer_uptodate);
2218 2256
2219int read_extent_buffer_pages(struct extent_map_tree *tree, 2257int read_extent_buffer_pages(struct extent_map_tree *tree,
2220 struct extent_buffer *eb, int wait) 2258 struct extent_buffer *eb,
2259 u64 start,
2260 int wait)
2221{ 2261{
2222 unsigned long i; 2262 unsigned long i;
2263 unsigned long start_i;
2223 struct page *page; 2264 struct page *page;
2224 int err; 2265 int err;
2225 int ret = 0; 2266 int ret = 0;
@@ -2232,9 +2273,16 @@ int read_extent_buffer_pages(struct extent_map_tree *tree,
2232 EXTENT_UPTODATE, 1)) { 2273 EXTENT_UPTODATE, 1)) {
2233 return 0; 2274 return 0;
2234 } 2275 }
2276 if (start) {
2277 WARN_ON(start < eb->start);
2278 start_i = (start >> PAGE_CACHE_SHIFT) -
2279 (eb->start >> PAGE_CACHE_SHIFT);
2280 } else {
2281 start_i = 0;
2282 }
2235 2283
2236 num_pages = num_extent_pages(eb->start, eb->len); 2284 num_pages = num_extent_pages(eb->start, eb->len);
2237 for (i = 0; i < num_pages; i++) { 2285 for (i = start_i; i < num_pages; i++) {
2238 page = extent_buffer_page(eb, i); 2286 page = extent_buffer_page(eb, i);
2239 if (PageUptodate(page)) { 2287 if (PageUptodate(page)) {
2240 continue; 2288 continue;
@@ -2260,7 +2308,7 @@ int read_extent_buffer_pages(struct extent_map_tree *tree,
2260 return ret; 2308 return ret;
2261 } 2309 }
2262 2310
2263 for (i = 0; i < num_pages; i++) { 2311 for (i = start_i; i < num_pages; i++) {
2264 page = extent_buffer_page(eb, i); 2312 page = extent_buffer_page(eb, i);
2265 wait_on_page_locked(page); 2313 wait_on_page_locked(page);
2266 if (!PageUptodate(page)) { 2314 if (!PageUptodate(page)) {
@@ -2314,7 +2362,7 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
2314} 2362}
2315EXPORT_SYMBOL(read_extent_buffer); 2363EXPORT_SYMBOL(read_extent_buffer);
2316 2364
2317static int __map_extent_buffer(struct extent_buffer *eb, unsigned long start, 2365int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
2318 unsigned long min_len, char **token, char **map, 2366 unsigned long min_len, char **token, char **map,
2319 unsigned long *map_start, 2367 unsigned long *map_start,
2320 unsigned long *map_len, int km) 2368 unsigned long *map_len, int km)
@@ -2337,6 +2385,10 @@ static int __map_extent_buffer(struct extent_buffer *eb, unsigned long start,
2337 offset = 0; 2385 offset = 0;
2338 *map_start = (i << PAGE_CACHE_SHIFT) - start_offset; 2386 *map_start = (i << PAGE_CACHE_SHIFT) - start_offset;
2339 } 2387 }
2388 if (start + min_len >= eb->len) {
2389printk("bad mapping eb start %Lu len %lu, wanted %lu %lu\n", eb->start, eb->len, start, min_len);
2390 WARN_ON(1);
2391 }
2340 2392
2341 p = extent_buffer_page(eb, i); 2393 p = extent_buffer_page(eb, i);
2342 WARN_ON(!PageUptodate(p)); 2394 WARN_ON(!PageUptodate(p));
@@ -2346,6 +2398,7 @@ static int __map_extent_buffer(struct extent_buffer *eb, unsigned long start,
2346 *map_len = PAGE_CACHE_SIZE - offset; 2398 *map_len = PAGE_CACHE_SIZE - offset;
2347 return 0; 2399 return 0;
2348} 2400}
2401EXPORT_SYMBOL(map_private_extent_buffer);
2349 2402
2350int map_extent_buffer(struct extent_buffer *eb, unsigned long start, 2403int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
2351 unsigned long min_len, 2404 unsigned long min_len,
@@ -2360,8 +2413,8 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
2360 eb->map_token = NULL; 2413 eb->map_token = NULL;
2361 save = 1; 2414 save = 1;
2362 } 2415 }
2363 err = __map_extent_buffer(eb, start, min_len, token, map, 2416 err = map_private_extent_buffer(eb, start, min_len, token, map,
2364 map_start, map_len, km); 2417 map_start, map_len, km);
2365 if (!err && save) { 2418 if (!err && save) {
2366 eb->map_token = *token; 2419 eb->map_token = *token;
2367 eb->kaddr = *map; 2420 eb->kaddr = *map;