aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-09 15:55:33 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:59 -0400
commit55c69072d6bd5be170a85467f64a20963cddf490 (patch)
tree92f9f34c5d3a19df2bbfc662386ccd690a5f39fb /fs/btrfs
parent21ad10cf3e9c1ef42e725e5c3a593c49f779a16b (diff)
Btrfs: Fix extent_buffer usage when nodesize != leafsize
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/disk-io.c26
-rw-r--r--fs/btrfs/extent-tree.c13
-rw-r--r--fs/btrfs/extent_map.c30
3 files changed, 54 insertions, 15 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a481b970608c..0338f8fd382d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -197,9 +197,23 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
197 if (found_start != start) { 197 if (found_start != start) {
198 printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", 198 printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n",
199 start, found_start, len); 199 start, found_start, len);
200 WARN_ON(1);
201 goto err;
202 }
203 if (eb->first_page != page) {
204 printk("bad first page %lu %lu\n", eb->first_page->index,
205 page->index);
206 WARN_ON(1);
207 goto err;
208 }
209 if (!PageUptodate(page)) {
210 printk("csum not up to date page %lu\n", page->index);
211 WARN_ON(1);
212 goto err;
200 } 213 }
201 found_level = btrfs_header_level(eb); 214 found_level = btrfs_header_level(eb);
202 csum_tree_block(root, eb, 0); 215 csum_tree_block(root, eb, 0);
216err:
203 free_extent_buffer(eb); 217 free_extent_buffer(eb);
204out: 218out:
205 return 0; 219 return 0;
@@ -368,7 +382,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
368 struct extent_buffer *buf) 382 struct extent_buffer *buf)
369{ 383{
370 struct inode *btree_inode = root->fs_info->btree_inode; 384 struct inode *btree_inode = root->fs_info->btree_inode;
371 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); 385 if (btrfs_header_generation(buf) ==
386 root->fs_info->running_transaction->transid)
387 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree,
388 buf);
372 return 0; 389 return 0;
373} 390}
374 391
@@ -897,8 +914,11 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
897 914
898void btrfs_throttle(struct btrfs_root *root) 915void btrfs_throttle(struct btrfs_root *root)
899{ 916{
900 if (root->fs_info->throttles) 917 struct backing_dev_info *bdi;
901 congestion_wait(WRITE, HZ/10); 918
919 bdi = root->fs_info->sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
920 if (root->fs_info->throttles && bdi_write_congested(bdi))
921 congestion_wait(WRITE, HZ/20);
902} 922}
903 923
904void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) 924void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 99a8b0f0d318..2c569b4d59d4 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1212,6 +1212,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1212 u64 header_transid = 1212 u64 header_transid =
1213 btrfs_header_generation(buf); 1213 btrfs_header_generation(buf);
1214 if (header_transid == transid) { 1214 if (header_transid == transid) {
1215 clean_tree_block(NULL, root, buf);
1215 free_extent_buffer(buf); 1216 free_extent_buffer(buf);
1216 return 1; 1217 return 1;
1217 } 1218 }
@@ -1249,7 +1250,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
1249 key.objectid = bytenr; 1250 key.objectid = bytenr;
1250 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 1251 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
1251 key.offset = num_bytes; 1252 key.offset = num_bytes;
1252
1253 path = btrfs_alloc_path(); 1253 path = btrfs_alloc_path();
1254 if (!path) 1254 if (!path)
1255 return -ENOMEM; 1255 return -ENOMEM;
@@ -1648,8 +1648,6 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1648 search_start, search_end, hint_byte, ins, 1648 search_start, search_end, hint_byte, ins,
1649 trans->alloc_exclude_start, 1649 trans->alloc_exclude_start,
1650 trans->alloc_exclude_nr, data); 1650 trans->alloc_exclude_nr, data);
1651if (ret)
1652printk("find free extent returns %d\n", ret);
1653 BUG_ON(ret); 1651 BUG_ON(ret);
1654 if (ret) 1652 if (ret)
1655 return ret; 1653 return ret;
@@ -1764,7 +1762,16 @@ struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1764 0, 0, 0); 1762 0, 0, 0);
1765 return ERR_PTR(-ENOMEM); 1763 return ERR_PTR(-ENOMEM);
1766 } 1764 }
1765 btrfs_set_header_generation(buf, trans->transid);
1766 clean_tree_block(trans, root, buf);
1767 wait_on_tree_block_writeback(root, buf);
1767 btrfs_set_buffer_uptodate(buf); 1768 btrfs_set_buffer_uptodate(buf);
1769
1770 if (PageDirty(buf->first_page)) {
1771 printk("page %lu dirty\n", buf->first_page->index);
1772 WARN_ON(1);
1773 }
1774
1768 set_extent_dirty(&trans->transaction->dirty_pages, buf->start, 1775 set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
1769 buf->start + buf->len - 1, GFP_NOFS); 1776 buf->start + buf->len - 1, GFP_NOFS);
1770 set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree, 1777 set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree,
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 9d6aefa937c4..f3a384ed700c 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -1663,6 +1663,13 @@ void set_page_extent_mapped(struct page *page)
1663 } 1663 }
1664} 1664}
1665 1665
1666void set_page_extent_head(struct page *page, unsigned long len)
1667{
1668 WARN_ON(page->private && page->private == EXTENT_PAGE_PRIVATE &&
1669 PageDirty(page));
1670 set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2);
1671}
1672
1666/* 1673/*
1667 * basic readpage implementation. Locked extent state structs are inserted 1674 * basic readpage implementation. Locked extent state structs are inserted
1668 * into the tree that are removed when the IO is done (by the end_io 1675 * into the tree that are removed when the IO is done (by the end_io
@@ -2490,8 +2497,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
2490 mark_page_accessed(page0); 2497 mark_page_accessed(page0);
2491 set_page_extent_mapped(page0); 2498 set_page_extent_mapped(page0);
2492 WARN_ON(!PageUptodate(page0)); 2499 WARN_ON(!PageUptodate(page0));
2493 set_page_private(page0, EXTENT_PAGE_PRIVATE_FIRST_PAGE | 2500 set_page_extent_head(page0, len);
2494 len << 2);
2495 } else { 2501 } else {
2496 i = 0; 2502 i = 0;
2497 } 2503 }
@@ -2505,8 +2511,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
2505 mark_page_accessed(p); 2511 mark_page_accessed(p);
2506 if (i == 0) { 2512 if (i == 0) {
2507 eb->first_page = p; 2513 eb->first_page = p;
2508 set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | 2514 set_page_extent_head(p, len);
2509 len << 2);
2510 } else { 2515 } else {
2511 set_page_private(p, EXTENT_PAGE_PRIVATE); 2516 set_page_private(p, EXTENT_PAGE_PRIVATE);
2512 } 2517 }
@@ -2569,8 +2574,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
2569 2574
2570 if (i == 0) { 2575 if (i == 0) {
2571 eb->first_page = p; 2576 eb->first_page = p;
2572 set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | 2577 set_page_extent_head(p, len);
2573 len << 2);
2574 } else { 2578 } else {
2575 set_page_private(p, EXTENT_PAGE_PRIVATE); 2579 set_page_private(p, EXTENT_PAGE_PRIVATE);
2576 } 2580 }
@@ -2643,6 +2647,11 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree,
2643 for (i = 0; i < num_pages; i++) { 2647 for (i = 0; i < num_pages; i++) {
2644 page = extent_buffer_page(eb, i); 2648 page = extent_buffer_page(eb, i);
2645 lock_page(page); 2649 lock_page(page);
2650 if (i == 0)
2651 set_page_extent_head(page, eb->len);
2652 else
2653 set_page_private(page, EXTENT_PAGE_PRIVATE);
2654
2646 /* 2655 /*
2647 * if we're on the last page or the first page and the 2656 * if we're on the last page or the first page and the
2648 * block isn't aligned on a page boundary, do extra checks 2657 * block isn't aligned on a page boundary, do extra checks
@@ -2697,9 +2706,12 @@ int set_extent_buffer_dirty(struct extent_map_tree *tree,
2697 */ 2706 */
2698 if (i == 0) { 2707 if (i == 0) {
2699 lock_page(page); 2708 lock_page(page);
2700 set_page_private(page, 2709 set_page_extent_head(page, eb->len);
2701 EXTENT_PAGE_PRIVATE_FIRST_PAGE | 2710 } else if (PagePrivate(page) &&
2702 eb->len << 2); 2711 page->private != EXTENT_PAGE_PRIVATE) {
2712 lock_page(page);
2713 set_page_extent_mapped(page);
2714 unlock_page(page);
2703 } 2715 }
2704 __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); 2716 __set_page_dirty_nobuffers(extent_buffer_page(eb, i));
2705 if (i == 0) 2717 if (i == 0)