aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-05-22 07:07:01 -0400
committerChris Mason <chris.mason@oracle.com>2011-05-22 07:07:01 -0400
commitdcc6d073225b6b732a52477c91bd4edc9b4d5502 (patch)
tree71da6844bb03c940c87c01a2a1f8c2e11cf85238 /fs/btrfs/disk-io.c
parent0965537308ac3b267ea16e731bd73870a51c53b8 (diff)
parent16cdcec736cd214350cdb591bf1091f8beedefa0 (diff)
Merge branch 'delayed_inode' into inode_numbers
Conflicts: fs/btrfs/inode.c fs/btrfs/ioctl.c fs/btrfs/transaction.c Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index ac1cd20d1c0d..087eed85c250 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1059,6 +1059,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
1059 root->name = NULL; 1059 root->name = NULL;
1060 root->in_sysfs = 0; 1060 root->in_sysfs = 0;
1061 root->inode_tree = RB_ROOT; 1061 root->inode_tree = RB_ROOT;
1062 INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC);
1062 root->block_rsv = NULL; 1063 root->block_rsv = NULL;
1063 root->orphan_block_rsv = NULL; 1064 root->orphan_block_rsv = NULL;
1064 1065
@@ -1707,6 +1708,13 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1707 1708
1708 INIT_LIST_HEAD(&fs_info->ordered_extents); 1709 INIT_LIST_HEAD(&fs_info->ordered_extents);
1709 spin_lock_init(&fs_info->ordered_extent_lock); 1710 spin_lock_init(&fs_info->ordered_extent_lock);
1711 fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root),
1712 GFP_NOFS);
1713 if (!fs_info->delayed_root) {
1714 err = -ENOMEM;
1715 goto fail_iput;
1716 }
1717 btrfs_init_delayed_root(fs_info->delayed_root);
1710 1718
1711 sb->s_blocksize = 4096; 1719 sb->s_blocksize = 4096;
1712 sb->s_blocksize_bits = blksize_bits(4096); 1720 sb->s_blocksize_bits = blksize_bits(4096);
@@ -1774,7 +1782,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1774 bh = btrfs_read_dev_super(fs_devices->latest_bdev); 1782 bh = btrfs_read_dev_super(fs_devices->latest_bdev);
1775 if (!bh) { 1783 if (!bh) {
1776 err = -EINVAL; 1784 err = -EINVAL;
1777 goto fail_iput; 1785 goto fail_alloc;
1778 } 1786 }
1779 1787
1780 memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy)); 1788 memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy));
@@ -1786,7 +1794,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1786 1794
1787 disk_super = &fs_info->super_copy; 1795 disk_super = &fs_info->super_copy;
1788 if (!btrfs_super_root(disk_super)) 1796 if (!btrfs_super_root(disk_super))
1789 goto fail_iput; 1797 goto fail_alloc;
1790 1798
1791 /* check FS state, whether FS is broken. */ 1799 /* check FS state, whether FS is broken. */
1792 fs_info->fs_state |= btrfs_super_flags(disk_super); 1800 fs_info->fs_state |= btrfs_super_flags(disk_super);
@@ -1802,7 +1810,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1802 ret = btrfs_parse_options(tree_root, options); 1810 ret = btrfs_parse_options(tree_root, options);
1803 if (ret) { 1811 if (ret) {
1804 err = ret; 1812 err = ret;
1805 goto fail_iput; 1813 goto fail_alloc;
1806 } 1814 }
1807 1815
1808 features = btrfs_super_incompat_flags(disk_super) & 1816 features = btrfs_super_incompat_flags(disk_super) &
@@ -1812,7 +1820,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1812 "unsupported optional features (%Lx).\n", 1820 "unsupported optional features (%Lx).\n",
1813 (unsigned long long)features); 1821 (unsigned long long)features);
1814 err = -EINVAL; 1822 err = -EINVAL;
1815 goto fail_iput; 1823 goto fail_alloc;
1816 } 1824 }
1817 1825
1818 features = btrfs_super_incompat_flags(disk_super); 1826 features = btrfs_super_incompat_flags(disk_super);
@@ -1828,7 +1836,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1828 "unsupported option features (%Lx).\n", 1836 "unsupported option features (%Lx).\n",
1829 (unsigned long long)features); 1837 (unsigned long long)features);
1830 err = -EINVAL; 1838 err = -EINVAL;
1831 goto fail_iput; 1839 goto fail_alloc;
1832 } 1840 }
1833 1841
1834 btrfs_init_workers(&fs_info->generic_worker, 1842 btrfs_init_workers(&fs_info->generic_worker,
@@ -1875,6 +1883,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1875 &fs_info->generic_worker); 1883 &fs_info->generic_worker);
1876 btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write", 1884 btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write",
1877 1, &fs_info->generic_worker); 1885 1, &fs_info->generic_worker);
1886 btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta",
1887 fs_info->thread_pool_size,
1888 &fs_info->generic_worker);
1878 1889
1879 /* 1890 /*
1880 * endios are largely parallel and should have a very 1891 * endios are largely parallel and should have a very
@@ -1896,6 +1907,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1896 btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); 1907 btrfs_start_workers(&fs_info->endio_meta_write_workers, 1);
1897 btrfs_start_workers(&fs_info->endio_write_workers, 1); 1908 btrfs_start_workers(&fs_info->endio_write_workers, 1);
1898 btrfs_start_workers(&fs_info->endio_freespace_worker, 1); 1909 btrfs_start_workers(&fs_info->endio_freespace_worker, 1);
1910 btrfs_start_workers(&fs_info->delayed_workers, 1);
1899 1911
1900 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 1912 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
1901 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 1913 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -2152,6 +2164,9 @@ fail_sb_buffer:
2152 btrfs_stop_workers(&fs_info->endio_write_workers); 2164 btrfs_stop_workers(&fs_info->endio_write_workers);
2153 btrfs_stop_workers(&fs_info->endio_freespace_worker); 2165 btrfs_stop_workers(&fs_info->endio_freespace_worker);
2154 btrfs_stop_workers(&fs_info->submit_workers); 2166 btrfs_stop_workers(&fs_info->submit_workers);
2167 btrfs_stop_workers(&fs_info->delayed_workers);
2168fail_alloc:
2169 kfree(fs_info->delayed_root);
2155fail_iput: 2170fail_iput:
2156 invalidate_inode_pages2(fs_info->btree_inode->i_mapping); 2171 invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
2157 iput(fs_info->btree_inode); 2172 iput(fs_info->btree_inode);
@@ -2597,6 +2612,7 @@ int close_ctree(struct btrfs_root *root)
2597 del_fs_roots(fs_info); 2612 del_fs_roots(fs_info);
2598 2613
2599 iput(fs_info->btree_inode); 2614 iput(fs_info->btree_inode);
2615 kfree(fs_info->delayed_root);
2600 2616
2601 btrfs_stop_workers(&fs_info->generic_worker); 2617 btrfs_stop_workers(&fs_info->generic_worker);
2602 btrfs_stop_workers(&fs_info->fixup_workers); 2618 btrfs_stop_workers(&fs_info->fixup_workers);
@@ -2608,6 +2624,7 @@ int close_ctree(struct btrfs_root *root)
2608 btrfs_stop_workers(&fs_info->endio_write_workers); 2624 btrfs_stop_workers(&fs_info->endio_write_workers);
2609 btrfs_stop_workers(&fs_info->endio_freespace_worker); 2625 btrfs_stop_workers(&fs_info->endio_freespace_worker);
2610 btrfs_stop_workers(&fs_info->submit_workers); 2626 btrfs_stop_workers(&fs_info->submit_workers);
2627 btrfs_stop_workers(&fs_info->delayed_workers);
2611 2628
2612 btrfs_close_devices(fs_info->fs_devices); 2629 btrfs_close_devices(fs_info->fs_devices);
2613 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2630 btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@ -2684,6 +2701,29 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
2684 if (current->flags & PF_MEMALLOC) 2701 if (current->flags & PF_MEMALLOC)
2685 return; 2702 return;
2686 2703
2704 btrfs_balance_delayed_items(root);
2705
2706 num_dirty = root->fs_info->dirty_metadata_bytes;
2707
2708 if (num_dirty > thresh) {
2709 balance_dirty_pages_ratelimited_nr(
2710 root->fs_info->btree_inode->i_mapping, 1);
2711 }
2712 return;
2713}
2714
2715void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
2716{
2717 /*
2718 * looks as though older kernels can get into trouble with
2719 * this code, they end up stuck in balance_dirty_pages forever
2720 */
2721 u64 num_dirty;
2722 unsigned long thresh = 32 * 1024 * 1024;
2723
2724 if (current->flags & PF_MEMALLOC)
2725 return;
2726
2687 num_dirty = root->fs_info->dirty_metadata_bytes; 2727 num_dirty = root->fs_info->dirty_metadata_bytes;
2688 2728
2689 if (num_dirty > thresh) { 2729 if (num_dirty > thresh) {