aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1f1d89b18818..9244cd7313d4 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -668,14 +668,31 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
668static int btree_writepage(struct page *page, struct writeback_control *wbc) 668static int btree_writepage(struct page *page, struct writeback_control *wbc)
669{ 669{
670 struct extent_io_tree *tree; 670 struct extent_io_tree *tree;
671 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
672 struct extent_buffer *eb;
673 int was_dirty;
674
671 tree = &BTRFS_I(page->mapping->host)->io_tree; 675 tree = &BTRFS_I(page->mapping->host)->io_tree;
676 if (!(current->flags & PF_MEMALLOC)) {
677 return extent_write_full_page(tree, page,
678 btree_get_extent, wbc);
679 }
672 680
673 if (current->flags & PF_MEMALLOC) { 681 redirty_page_for_writepage(wbc, page);
674 redirty_page_for_writepage(wbc, page); 682 eb = btrfs_find_tree_block(root, page_offset(page),
675 unlock_page(page); 683 PAGE_CACHE_SIZE);
676 return 0; 684 WARN_ON(!eb);
685
686 was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
687 if (!was_dirty) {
688 spin_lock(&root->fs_info->delalloc_lock);
689 root->fs_info->dirty_metadata_bytes += PAGE_CACHE_SIZE;
690 spin_unlock(&root->fs_info->delalloc_lock);
677 } 691 }
678 return extent_write_full_page(tree, page, btree_get_extent, wbc); 692 free_extent_buffer(eb);
693
694 unlock_page(page);
695 return 0;
679} 696}
680 697
681static int btree_writepages(struct address_space *mapping, 698static int btree_writepages(struct address_space *mapping,
@@ -684,15 +701,15 @@ static int btree_writepages(struct address_space *mapping,
684 struct extent_io_tree *tree; 701 struct extent_io_tree *tree;
685 tree = &BTRFS_I(mapping->host)->io_tree; 702 tree = &BTRFS_I(mapping->host)->io_tree;
686 if (wbc->sync_mode == WB_SYNC_NONE) { 703 if (wbc->sync_mode == WB_SYNC_NONE) {
704 struct btrfs_root *root = BTRFS_I(mapping->host)->root;
687 u64 num_dirty; 705 u64 num_dirty;
688 u64 start = 0;
689 unsigned long thresh = 32 * 1024 * 1024; 706 unsigned long thresh = 32 * 1024 * 1024;
690 707
691 if (wbc->for_kupdate) 708 if (wbc->for_kupdate)
692 return 0; 709 return 0;
693 710
694 num_dirty = count_range_bits(tree, &start, (u64)-1, 711 /* this is a bit racy, but that's ok */
695 thresh, EXTENT_DIRTY); 712 num_dirty = root->fs_info->dirty_metadata_bytes;
696 if (num_dirty < thresh) 713 if (num_dirty < thresh)
697 return 0; 714 return 0;
698 } 715 }
@@ -859,9 +876,17 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
859 root->fs_info->running_transaction->transid) { 876 root->fs_info->running_transaction->transid) {
860 btrfs_assert_tree_locked(buf); 877 btrfs_assert_tree_locked(buf);
861 878
862 /* ugh, clear_extent_buffer_dirty can be expensive */ 879 if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
863 btrfs_set_lock_blocking(buf); 880 spin_lock(&root->fs_info->delalloc_lock);
881 if (root->fs_info->dirty_metadata_bytes >= buf->len)
882 root->fs_info->dirty_metadata_bytes -= buf->len;
883 else
884 WARN_ON(1);
885 spin_unlock(&root->fs_info->delalloc_lock);
886 }
864 887
888 /* ugh, clear_extent_buffer_dirty needs to lock the page */
889 btrfs_set_lock_blocking(buf);
865 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, 890 clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
866 buf); 891 buf);
867 } 892 }
@@ -2348,8 +2373,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
2348 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; 2373 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
2349 u64 transid = btrfs_header_generation(buf); 2374 u64 transid = btrfs_header_generation(buf);
2350 struct inode *btree_inode = root->fs_info->btree_inode; 2375 struct inode *btree_inode = root->fs_info->btree_inode;
2351 2376 int was_dirty;
2352 btrfs_set_lock_blocking(buf);
2353 2377
2354 btrfs_assert_tree_locked(buf); 2378 btrfs_assert_tree_locked(buf);
2355 if (transid != root->fs_info->generation) { 2379 if (transid != root->fs_info->generation) {
@@ -2360,7 +2384,13 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
2360 (unsigned long long)root->fs_info->generation); 2384 (unsigned long long)root->fs_info->generation);
2361 WARN_ON(1); 2385 WARN_ON(1);
2362 } 2386 }
2363 set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, buf); 2387 was_dirty = set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
2388 buf);
2389 if (!was_dirty) {
2390 spin_lock(&root->fs_info->delalloc_lock);
2391 root->fs_info->dirty_metadata_bytes += buf->len;
2392 spin_unlock(&root->fs_info->delalloc_lock);
2393 }
2364} 2394}
2365 2395
2366void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) 2396void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
@@ -2400,6 +2430,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
2400int btree_lock_page_hook(struct page *page) 2430int btree_lock_page_hook(struct page *page)
2401{ 2431{
2402 struct inode *inode = page->mapping->host; 2432 struct inode *inode = page->mapping->host;
2433 struct btrfs_root *root = BTRFS_I(inode)->root;
2403 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 2434 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
2404 struct extent_buffer *eb; 2435 struct extent_buffer *eb;
2405 unsigned long len; 2436 unsigned long len;
@@ -2415,6 +2446,16 @@ int btree_lock_page_hook(struct page *page)
2415 2446
2416 btrfs_tree_lock(eb); 2447 btrfs_tree_lock(eb);
2417 btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); 2448 btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
2449
2450 if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
2451 spin_lock(&root->fs_info->delalloc_lock);
2452 if (root->fs_info->dirty_metadata_bytes >= eb->len)
2453 root->fs_info->dirty_metadata_bytes -= eb->len;
2454 else
2455 WARN_ON(1);
2456 spin_unlock(&root->fs_info->delalloc_lock);
2457 }
2458
2418 btrfs_tree_unlock(eb); 2459 btrfs_tree_unlock(eb);
2419 free_extent_buffer(eb); 2460 free_extent_buffer(eb);
2420out: 2461out: