diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 91 |
1 files changed, 63 insertions, 28 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3e18175248e0..92caa8035f36 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "locking.h" | 38 | #include "locking.h" |
39 | #include "ref-cache.h" | 39 | #include "ref-cache.h" |
40 | #include "tree-log.h" | 40 | #include "tree-log.h" |
41 | #include "free-space-cache.h" | ||
41 | 42 | ||
42 | static struct extent_io_ops btree_extent_io_ops; | 43 | static struct extent_io_ops btree_extent_io_ops; |
43 | static void end_workqueue_fn(struct btrfs_work *work); | 44 | static void end_workqueue_fn(struct btrfs_work *work); |
@@ -668,14 +669,31 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
668 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 669 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
669 | { | 670 | { |
670 | struct extent_io_tree *tree; | 671 | struct extent_io_tree *tree; |
672 | struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; | ||
673 | struct extent_buffer *eb; | ||
674 | int was_dirty; | ||
675 | |||
671 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 676 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
677 | if (!(current->flags & PF_MEMALLOC)) { | ||
678 | return extent_write_full_page(tree, page, | ||
679 | btree_get_extent, wbc); | ||
680 | } | ||
672 | 681 | ||
673 | if (current->flags & PF_MEMALLOC) { | 682 | redirty_page_for_writepage(wbc, page); |
674 | redirty_page_for_writepage(wbc, page); | 683 | eb = btrfs_find_tree_block(root, page_offset(page), |
675 | unlock_page(page); | 684 | PAGE_CACHE_SIZE); |
676 | return 0; | 685 | WARN_ON(!eb); |
686 | |||
687 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); | ||
688 | if (!was_dirty) { | ||
689 | spin_lock(&root->fs_info->delalloc_lock); | ||
690 | root->fs_info->dirty_metadata_bytes += PAGE_CACHE_SIZE; | ||
691 | spin_unlock(&root->fs_info->delalloc_lock); | ||
677 | } | 692 | } |
678 | return extent_write_full_page(tree, page, btree_get_extent, wbc); | 693 | free_extent_buffer(eb); |
694 | |||
695 | unlock_page(page); | ||
696 | return 0; | ||
679 | } | 697 | } |
680 | 698 | ||
681 | static int btree_writepages(struct address_space *mapping, | 699 | static int btree_writepages(struct address_space *mapping, |
@@ -684,15 +702,15 @@ static int btree_writepages(struct address_space *mapping, | |||
684 | struct extent_io_tree *tree; | 702 | struct extent_io_tree *tree; |
685 | tree = &BTRFS_I(mapping->host)->io_tree; | 703 | tree = &BTRFS_I(mapping->host)->io_tree; |
686 | if (wbc->sync_mode == WB_SYNC_NONE) { | 704 | if (wbc->sync_mode == WB_SYNC_NONE) { |
705 | struct btrfs_root *root = BTRFS_I(mapping->host)->root; | ||
687 | u64 num_dirty; | 706 | u64 num_dirty; |
688 | u64 start = 0; | ||
689 | unsigned long thresh = 32 * 1024 * 1024; | 707 | unsigned long thresh = 32 * 1024 * 1024; |
690 | 708 | ||
691 | if (wbc->for_kupdate) | 709 | if (wbc->for_kupdate) |
692 | return 0; | 710 | return 0; |
693 | 711 | ||
694 | num_dirty = count_range_bits(tree, &start, (u64)-1, | 712 | /* this is a bit racy, but that's ok */ |
695 | thresh, EXTENT_DIRTY); | 713 | num_dirty = root->fs_info->dirty_metadata_bytes; |
696 | if (num_dirty < thresh) | 714 | if (num_dirty < thresh) |
697 | return 0; | 715 | return 0; |
698 | } | 716 | } |
@@ -859,9 +877,17 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
859 | root->fs_info->running_transaction->transid) { | 877 | root->fs_info->running_transaction->transid) { |
860 | btrfs_assert_tree_locked(buf); | 878 | btrfs_assert_tree_locked(buf); |
861 | 879 | ||
862 | /* ugh, clear_extent_buffer_dirty can be expensive */ | 880 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) { |
863 | btrfs_set_lock_blocking(buf); | 881 | spin_lock(&root->fs_info->delalloc_lock); |
882 | if (root->fs_info->dirty_metadata_bytes >= buf->len) | ||
883 | root->fs_info->dirty_metadata_bytes -= buf->len; | ||
884 | else | ||
885 | WARN_ON(1); | ||
886 | spin_unlock(&root->fs_info->delalloc_lock); | ||
887 | } | ||
864 | 888 | ||
889 | /* ugh, clear_extent_buffer_dirty needs to lock the page */ | ||
890 | btrfs_set_lock_blocking(buf); | ||
865 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, | 891 | clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, |
866 | buf); | 892 | buf); |
867 | } | 893 | } |
@@ -1387,8 +1413,6 @@ static int bio_ready_for_csum(struct bio *bio) | |||
1387 | 1413 | ||
1388 | ret = extent_range_uptodate(io_tree, start + length, | 1414 | ret = extent_range_uptodate(io_tree, start + length, |
1389 | start + buf_len - 1); | 1415 | start + buf_len - 1); |
1390 | if (ret == 1) | ||
1391 | return ret; | ||
1392 | return ret; | 1416 | return ret; |
1393 | } | 1417 | } |
1394 | 1418 | ||
@@ -1471,12 +1495,6 @@ static int transaction_kthread(void *arg) | |||
1471 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 1495 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); |
1472 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1496 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
1473 | 1497 | ||
1474 | if (root->fs_info->total_ref_cache_size > 20 * 1024 * 1024) { | ||
1475 | printk(KERN_INFO "btrfs: total reference cache " | ||
1476 | "size %llu\n", | ||
1477 | root->fs_info->total_ref_cache_size); | ||
1478 | } | ||
1479 | |||
1480 | mutex_lock(&root->fs_info->trans_mutex); | 1498 | mutex_lock(&root->fs_info->trans_mutex); |
1481 | cur = root->fs_info->running_transaction; | 1499 | cur = root->fs_info->running_transaction; |
1482 | if (!cur) { | 1500 | if (!cur) { |
@@ -1493,6 +1511,7 @@ static int transaction_kthread(void *arg) | |||
1493 | mutex_unlock(&root->fs_info->trans_mutex); | 1511 | mutex_unlock(&root->fs_info->trans_mutex); |
1494 | trans = btrfs_start_transaction(root, 1); | 1512 | trans = btrfs_start_transaction(root, 1); |
1495 | ret = btrfs_commit_transaction(trans, root); | 1513 | ret = btrfs_commit_transaction(trans, root); |
1514 | |||
1496 | sleep: | 1515 | sleep: |
1497 | wake_up_process(root->fs_info->cleaner_kthread); | 1516 | wake_up_process(root->fs_info->cleaner_kthread); |
1498 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1517 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
@@ -1552,6 +1571,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1552 | INIT_LIST_HEAD(&fs_info->dead_roots); | 1571 | INIT_LIST_HEAD(&fs_info->dead_roots); |
1553 | INIT_LIST_HEAD(&fs_info->hashers); | 1572 | INIT_LIST_HEAD(&fs_info->hashers); |
1554 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 1573 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); |
1574 | INIT_LIST_HEAD(&fs_info->ordered_operations); | ||
1555 | spin_lock_init(&fs_info->delalloc_lock); | 1575 | spin_lock_init(&fs_info->delalloc_lock); |
1556 | spin_lock_init(&fs_info->new_trans_lock); | 1576 | spin_lock_init(&fs_info->new_trans_lock); |
1557 | spin_lock_init(&fs_info->ref_cache_lock); | 1577 | spin_lock_init(&fs_info->ref_cache_lock); |
@@ -1611,10 +1631,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1611 | 1631 | ||
1612 | extent_io_tree_init(&fs_info->pinned_extents, | 1632 | extent_io_tree_init(&fs_info->pinned_extents, |
1613 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 1633 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
1614 | extent_io_tree_init(&fs_info->pending_del, | ||
1615 | fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
1616 | extent_io_tree_init(&fs_info->extent_ins, | ||
1617 | fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
1618 | fs_info->do_barriers = 1; | 1634 | fs_info->do_barriers = 1; |
1619 | 1635 | ||
1620 | INIT_LIST_HEAD(&fs_info->dead_reloc_roots); | 1636 | INIT_LIST_HEAD(&fs_info->dead_reloc_roots); |
@@ -1627,15 +1643,18 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1627 | insert_inode_hash(fs_info->btree_inode); | 1643 | insert_inode_hash(fs_info->btree_inode); |
1628 | 1644 | ||
1629 | mutex_init(&fs_info->trans_mutex); | 1645 | mutex_init(&fs_info->trans_mutex); |
1646 | mutex_init(&fs_info->ordered_operations_mutex); | ||
1630 | mutex_init(&fs_info->tree_log_mutex); | 1647 | mutex_init(&fs_info->tree_log_mutex); |
1631 | mutex_init(&fs_info->drop_mutex); | 1648 | mutex_init(&fs_info->drop_mutex); |
1632 | mutex_init(&fs_info->extent_ins_mutex); | ||
1633 | mutex_init(&fs_info->pinned_mutex); | ||
1634 | mutex_init(&fs_info->chunk_mutex); | 1649 | mutex_init(&fs_info->chunk_mutex); |
1635 | mutex_init(&fs_info->transaction_kthread_mutex); | 1650 | mutex_init(&fs_info->transaction_kthread_mutex); |
1636 | mutex_init(&fs_info->cleaner_mutex); | 1651 | mutex_init(&fs_info->cleaner_mutex); |
1637 | mutex_init(&fs_info->volume_mutex); | 1652 | mutex_init(&fs_info->volume_mutex); |
1638 | mutex_init(&fs_info->tree_reloc_mutex); | 1653 | mutex_init(&fs_info->tree_reloc_mutex); |
1654 | |||
1655 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | ||
1656 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | ||
1657 | |||
1639 | init_waitqueue_head(&fs_info->transaction_throttle); | 1658 | init_waitqueue_head(&fs_info->transaction_throttle); |
1640 | init_waitqueue_head(&fs_info->transaction_wait); | 1659 | init_waitqueue_head(&fs_info->transaction_wait); |
1641 | init_waitqueue_head(&fs_info->async_submit_wait); | 1660 | init_waitqueue_head(&fs_info->async_submit_wait); |
@@ -2358,8 +2377,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
2358 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | 2377 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; |
2359 | u64 transid = btrfs_header_generation(buf); | 2378 | u64 transid = btrfs_header_generation(buf); |
2360 | struct inode *btree_inode = root->fs_info->btree_inode; | 2379 | struct inode *btree_inode = root->fs_info->btree_inode; |
2361 | 2380 | int was_dirty; | |
2362 | btrfs_set_lock_blocking(buf); | ||
2363 | 2381 | ||
2364 | btrfs_assert_tree_locked(buf); | 2382 | btrfs_assert_tree_locked(buf); |
2365 | if (transid != root->fs_info->generation) { | 2383 | if (transid != root->fs_info->generation) { |
@@ -2370,7 +2388,13 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
2370 | (unsigned long long)root->fs_info->generation); | 2388 | (unsigned long long)root->fs_info->generation); |
2371 | WARN_ON(1); | 2389 | WARN_ON(1); |
2372 | } | 2390 | } |
2373 | set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, buf); | 2391 | was_dirty = set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, |
2392 | buf); | ||
2393 | if (!was_dirty) { | ||
2394 | spin_lock(&root->fs_info->delalloc_lock); | ||
2395 | root->fs_info->dirty_metadata_bytes += buf->len; | ||
2396 | spin_unlock(&root->fs_info->delalloc_lock); | ||
2397 | } | ||
2374 | } | 2398 | } |
2375 | 2399 | ||
2376 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | 2400 | void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) |
@@ -2385,7 +2409,7 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | |||
2385 | unsigned long thresh = 32 * 1024 * 1024; | 2409 | unsigned long thresh = 32 * 1024 * 1024; |
2386 | tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; | 2410 | tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; |
2387 | 2411 | ||
2388 | if (current_is_pdflush() || current->flags & PF_MEMALLOC) | 2412 | if (current->flags & PF_MEMALLOC) |
2389 | return; | 2413 | return; |
2390 | 2414 | ||
2391 | num_dirty = count_range_bits(tree, &start, (u64)-1, | 2415 | num_dirty = count_range_bits(tree, &start, (u64)-1, |
@@ -2410,6 +2434,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
2410 | int btree_lock_page_hook(struct page *page) | 2434 | int btree_lock_page_hook(struct page *page) |
2411 | { | 2435 | { |
2412 | struct inode *inode = page->mapping->host; | 2436 | struct inode *inode = page->mapping->host; |
2437 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
2413 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 2438 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
2414 | struct extent_buffer *eb; | 2439 | struct extent_buffer *eb; |
2415 | unsigned long len; | 2440 | unsigned long len; |
@@ -2425,6 +2450,16 @@ int btree_lock_page_hook(struct page *page) | |||
2425 | 2450 | ||
2426 | btrfs_tree_lock(eb); | 2451 | btrfs_tree_lock(eb); |
2427 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); | 2452 | btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); |
2453 | |||
2454 | if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { | ||
2455 | spin_lock(&root->fs_info->delalloc_lock); | ||
2456 | if (root->fs_info->dirty_metadata_bytes >= eb->len) | ||
2457 | root->fs_info->dirty_metadata_bytes -= eb->len; | ||
2458 | else | ||
2459 | WARN_ON(1); | ||
2460 | spin_unlock(&root->fs_info->delalloc_lock); | ||
2461 | } | ||
2462 | |||
2428 | btrfs_tree_unlock(eb); | 2463 | btrfs_tree_unlock(eb); |
2429 | free_extent_buffer(eb); | 2464 | free_extent_buffer(eb); |
2430 | out: | 2465 | out: |