diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index cb9d1b8bfe7..a2eb3a3755d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "locking.h" | 42 | #include "locking.h" |
43 | #include "tree-log.h" | 43 | #include "tree-log.h" |
44 | #include "free-space-cache.h" | 44 | #include "free-space-cache.h" |
45 | #include "inode-map.h" | ||
45 | 46 | ||
46 | static struct extent_io_ops btree_extent_io_ops; | 47 | static struct extent_io_ops btree_extent_io_ops; |
47 | static void end_workqueue_fn(struct btrfs_work *work); | 48 | static void end_workqueue_fn(struct btrfs_work *work); |
@@ -1045,6 +1046,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1045 | root->name = NULL; | 1046 | root->name = NULL; |
1046 | root->in_sysfs = 0; | 1047 | root->in_sysfs = 0; |
1047 | root->inode_tree = RB_ROOT; | 1048 | root->inode_tree = RB_ROOT; |
1049 | INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC); | ||
1048 | root->block_rsv = NULL; | 1050 | root->block_rsv = NULL; |
1049 | root->orphan_block_rsv = NULL; | 1051 | root->orphan_block_rsv = NULL; |
1050 | 1052 | ||
@@ -1298,6 +1300,19 @@ again: | |||
1298 | if (IS_ERR(root)) | 1300 | if (IS_ERR(root)) |
1299 | return root; | 1301 | return root; |
1300 | 1302 | ||
1303 | root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS); | ||
1304 | if (!root->free_ino_ctl) | ||
1305 | goto fail; | ||
1306 | root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned), | ||
1307 | GFP_NOFS); | ||
1308 | if (!root->free_ino_pinned) | ||
1309 | goto fail; | ||
1310 | |||
1311 | btrfs_init_free_ino_ctl(root); | ||
1312 | mutex_init(&root->fs_commit_mutex); | ||
1313 | spin_lock_init(&root->cache_lock); | ||
1314 | init_waitqueue_head(&root->cache_wait); | ||
1315 | |||
1301 | set_anon_super(&root->anon_super, NULL); | 1316 | set_anon_super(&root->anon_super, NULL); |
1302 | 1317 | ||
1303 | if (btrfs_root_refs(&root->root_item) == 0) { | 1318 | if (btrfs_root_refs(&root->root_item) == 0) { |
@@ -1631,6 +1646,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1631 | 1646 | ||
1632 | INIT_LIST_HEAD(&fs_info->ordered_extents); | 1647 | INIT_LIST_HEAD(&fs_info->ordered_extents); |
1633 | spin_lock_init(&fs_info->ordered_extent_lock); | 1648 | spin_lock_init(&fs_info->ordered_extent_lock); |
1649 | fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root), | ||
1650 | GFP_NOFS); | ||
1651 | if (!fs_info->delayed_root) { | ||
1652 | err = -ENOMEM; | ||
1653 | goto fail_iput; | ||
1654 | } | ||
1655 | btrfs_init_delayed_root(fs_info->delayed_root); | ||
1634 | 1656 | ||
1635 | sb->s_blocksize = 4096; | 1657 | sb->s_blocksize = 4096; |
1636 | sb->s_blocksize_bits = blksize_bits(4096); | 1658 | sb->s_blocksize_bits = blksize_bits(4096); |
@@ -1696,7 +1718,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1696 | bh = btrfs_read_dev_super(fs_devices->latest_bdev); | 1718 | bh = btrfs_read_dev_super(fs_devices->latest_bdev); |
1697 | if (!bh) { | 1719 | if (!bh) { |
1698 | err = -EINVAL; | 1720 | err = -EINVAL; |
1699 | goto fail_iput; | 1721 | goto fail_alloc; |
1700 | } | 1722 | } |
1701 | 1723 | ||
1702 | memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy)); | 1724 | memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy)); |
@@ -1708,7 +1730,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1708 | 1730 | ||
1709 | disk_super = &fs_info->super_copy; | 1731 | disk_super = &fs_info->super_copy; |
1710 | if (!btrfs_super_root(disk_super)) | 1732 | if (!btrfs_super_root(disk_super)) |
1711 | goto fail_iput; | 1733 | goto fail_alloc; |
1712 | 1734 | ||
1713 | /* check FS state, whether FS is broken. */ | 1735 | /* check FS state, whether FS is broken. */ |
1714 | fs_info->fs_state |= btrfs_super_flags(disk_super); | 1736 | fs_info->fs_state |= btrfs_super_flags(disk_super); |
@@ -1724,7 +1746,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1724 | ret = btrfs_parse_options(tree_root, options); | 1746 | ret = btrfs_parse_options(tree_root, options); |
1725 | if (ret) { | 1747 | if (ret) { |
1726 | err = ret; | 1748 | err = ret; |
1727 | goto fail_iput; | 1749 | goto fail_alloc; |
1728 | } | 1750 | } |
1729 | 1751 | ||
1730 | features = btrfs_super_incompat_flags(disk_super) & | 1752 | features = btrfs_super_incompat_flags(disk_super) & |
@@ -1734,7 +1756,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1734 | "unsupported optional features (%Lx).\n", | 1756 | "unsupported optional features (%Lx).\n", |
1735 | (unsigned long long)features); | 1757 | (unsigned long long)features); |
1736 | err = -EINVAL; | 1758 | err = -EINVAL; |
1737 | goto fail_iput; | 1759 | goto fail_alloc; |
1738 | } | 1760 | } |
1739 | 1761 | ||
1740 | features = btrfs_super_incompat_flags(disk_super); | 1762 | features = btrfs_super_incompat_flags(disk_super); |
@@ -1750,7 +1772,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1750 | "unsupported option features (%Lx).\n", | 1772 | "unsupported option features (%Lx).\n", |
1751 | (unsigned long long)features); | 1773 | (unsigned long long)features); |
1752 | err = -EINVAL; | 1774 | err = -EINVAL; |
1753 | goto fail_iput; | 1775 | goto fail_alloc; |
1754 | } | 1776 | } |
1755 | 1777 | ||
1756 | btrfs_init_workers(&fs_info->generic_worker, | 1778 | btrfs_init_workers(&fs_info->generic_worker, |
@@ -1797,6 +1819,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1797 | &fs_info->generic_worker); | 1819 | &fs_info->generic_worker); |
1798 | btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write", | 1820 | btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write", |
1799 | 1, &fs_info->generic_worker); | 1821 | 1, &fs_info->generic_worker); |
1822 | btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta", | ||
1823 | fs_info->thread_pool_size, | ||
1824 | &fs_info->generic_worker); | ||
1800 | 1825 | ||
1801 | /* | 1826 | /* |
1802 | * endios are largely parallel and should have a very | 1827 | * endios are largely parallel and should have a very |
@@ -1818,6 +1843,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1818 | btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); | 1843 | btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); |
1819 | btrfs_start_workers(&fs_info->endio_write_workers, 1); | 1844 | btrfs_start_workers(&fs_info->endio_write_workers, 1); |
1820 | btrfs_start_workers(&fs_info->endio_freespace_worker, 1); | 1845 | btrfs_start_workers(&fs_info->endio_freespace_worker, 1); |
1846 | btrfs_start_workers(&fs_info->delayed_workers, 1); | ||
1821 | 1847 | ||
1822 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); | 1848 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); |
1823 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, | 1849 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, |
@@ -2074,6 +2100,9 @@ fail_sb_buffer: | |||
2074 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2100 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2075 | btrfs_stop_workers(&fs_info->endio_freespace_worker); | 2101 | btrfs_stop_workers(&fs_info->endio_freespace_worker); |
2076 | btrfs_stop_workers(&fs_info->submit_workers); | 2102 | btrfs_stop_workers(&fs_info->submit_workers); |
2103 | btrfs_stop_workers(&fs_info->delayed_workers); | ||
2104 | fail_alloc: | ||
2105 | kfree(fs_info->delayed_root); | ||
2077 | fail_iput: | 2106 | fail_iput: |
2078 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2107 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2079 | iput(fs_info->btree_inode); | 2108 | iput(fs_info->btree_inode); |
@@ -2338,12 +2367,15 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | |||
2338 | if (btrfs_root_refs(&root->root_item) == 0) | 2367 | if (btrfs_root_refs(&root->root_item) == 0) |
2339 | synchronize_srcu(&fs_info->subvol_srcu); | 2368 | synchronize_srcu(&fs_info->subvol_srcu); |
2340 | 2369 | ||
2370 | __btrfs_remove_free_space_cache(root->free_ino_pinned); | ||
2371 | __btrfs_remove_free_space_cache(root->free_ino_ctl); | ||
2341 | free_fs_root(root); | 2372 | free_fs_root(root); |
2342 | return 0; | 2373 | return 0; |
2343 | } | 2374 | } |
2344 | 2375 | ||
2345 | static void free_fs_root(struct btrfs_root *root) | 2376 | static void free_fs_root(struct btrfs_root *root) |
2346 | { | 2377 | { |
2378 | iput(root->cache_inode); | ||
2347 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); | 2379 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); |
2348 | if (root->anon_super.s_dev) { | 2380 | if (root->anon_super.s_dev) { |
2349 | down_write(&root->anon_super.s_umount); | 2381 | down_write(&root->anon_super.s_umount); |
@@ -2351,6 +2383,8 @@ static void free_fs_root(struct btrfs_root *root) | |||
2351 | } | 2383 | } |
2352 | free_extent_buffer(root->node); | 2384 | free_extent_buffer(root->node); |
2353 | free_extent_buffer(root->commit_root); | 2385 | free_extent_buffer(root->commit_root); |
2386 | kfree(root->free_ino_ctl); | ||
2387 | kfree(root->free_ino_pinned); | ||
2354 | kfree(root->name); | 2388 | kfree(root->name); |
2355 | kfree(root); | 2389 | kfree(root); |
2356 | } | 2390 | } |
@@ -2512,6 +2546,7 @@ int close_ctree(struct btrfs_root *root) | |||
2512 | del_fs_roots(fs_info); | 2546 | del_fs_roots(fs_info); |
2513 | 2547 | ||
2514 | iput(fs_info->btree_inode); | 2548 | iput(fs_info->btree_inode); |
2549 | kfree(fs_info->delayed_root); | ||
2515 | 2550 | ||
2516 | btrfs_stop_workers(&fs_info->generic_worker); | 2551 | btrfs_stop_workers(&fs_info->generic_worker); |
2517 | btrfs_stop_workers(&fs_info->fixup_workers); | 2552 | btrfs_stop_workers(&fs_info->fixup_workers); |
@@ -2523,6 +2558,7 @@ int close_ctree(struct btrfs_root *root) | |||
2523 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2558 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2524 | btrfs_stop_workers(&fs_info->endio_freespace_worker); | 2559 | btrfs_stop_workers(&fs_info->endio_freespace_worker); |
2525 | btrfs_stop_workers(&fs_info->submit_workers); | 2560 | btrfs_stop_workers(&fs_info->submit_workers); |
2561 | btrfs_stop_workers(&fs_info->delayed_workers); | ||
2526 | 2562 | ||
2527 | btrfs_close_devices(fs_info->fs_devices); | 2563 | btrfs_close_devices(fs_info->fs_devices); |
2528 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 2564 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
@@ -2599,6 +2635,29 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | |||
2599 | if (current->flags & PF_MEMALLOC) | 2635 | if (current->flags & PF_MEMALLOC) |
2600 | return; | 2636 | return; |
2601 | 2637 | ||
2638 | btrfs_balance_delayed_items(root); | ||
2639 | |||
2640 | num_dirty = root->fs_info->dirty_metadata_bytes; | ||
2641 | |||
2642 | if (num_dirty > thresh) { | ||
2643 | balance_dirty_pages_ratelimited_nr( | ||
2644 | root->fs_info->btree_inode->i_mapping, 1); | ||
2645 | } | ||
2646 | return; | ||
2647 | } | ||
2648 | |||
2649 | void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | ||
2650 | { | ||
2651 | /* | ||
2652 | * looks as though older kernels can get into trouble with | ||
2653 | * this code, they end up stuck in balance_dirty_pages forever | ||
2654 | */ | ||
2655 | u64 num_dirty; | ||
2656 | unsigned long thresh = 32 * 1024 * 1024; | ||
2657 | |||
2658 | if (current->flags & PF_MEMALLOC) | ||
2659 | return; | ||
2660 | |||
2602 | num_dirty = root->fs_info->dirty_metadata_bytes; | 2661 | num_dirty = root->fs_info->dirty_metadata_bytes; |
2603 | 2662 | ||
2604 | if (num_dirty > thresh) { | 2663 | if (num_dirty > thresh) { |