diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:31 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:04 -0400 |
commit | 3f157a2fd2ad731e1ed9964fecdc5f459f04a4a4 (patch) | |
tree | df9421e7b1d0c06d5efb8659f4317438d3d511d7 /fs/btrfs/disk-io.c | |
parent | 1b1e2135dc1e4efbcf25ac9ac9979316d4e1193e (diff) |
Btrfs: Online btree defragmentation fixes
The btree defragger wasn't making forward progress because the new key wasn't
being saved by the btrfs_search_forward function.
This also disables the automatic btree defrag, it wasn't scaling well to
huge filesystems. The auto-defrag needs to be done differently.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 61 |
1 files changed, 3 insertions, 58 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 31ca9f89388d..4cdc0b6a2672 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -295,7 +295,6 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
295 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, | 295 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, |
296 | btrfs_header_generation(eb)); | 296 | btrfs_header_generation(eb)); |
297 | BUG_ON(ret); | 297 | BUG_ON(ret); |
298 | btrfs_clear_buffer_defrag(eb); | ||
299 | found_start = btrfs_header_bytenr(eb); | 298 | found_start = btrfs_header_bytenr(eb); |
300 | if (found_start != start) { | 299 | if (found_start != start) { |
301 | printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", | 300 | printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", |
@@ -355,7 +354,6 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
355 | } | 354 | } |
356 | eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); | 355 | eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); |
357 | 356 | ||
358 | btrfs_clear_buffer_defrag(eb); | ||
359 | found_start = btrfs_header_bytenr(eb); | 357 | found_start = btrfs_header_bytenr(eb); |
360 | if (found_start != start) { | 358 | if (found_start != start) { |
361 | ret = -EIO; | 359 | ret = -EIO; |
@@ -736,6 +734,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
736 | memset(&root->root_item, 0, sizeof(root->root_item)); | 734 | memset(&root->root_item, 0, sizeof(root->root_item)); |
737 | memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); | 735 | memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); |
738 | memset(&root->root_kobj, 0, sizeof(root->root_kobj)); | 736 | memset(&root->root_kobj, 0, sizeof(root->root_kobj)); |
737 | root->defrag_trans_start = fs_info->generation; | ||
739 | init_completion(&root->kobj_unregister); | 738 | init_completion(&root->kobj_unregister); |
740 | root->defrag_running = 0; | 739 | root->defrag_running = 0; |
741 | root->defrag_level = 0; | 740 | root->defrag_level = 0; |
@@ -1168,7 +1167,6 @@ static int transaction_kthread(void *arg) | |||
1168 | goto sleep; | 1167 | goto sleep; |
1169 | } | 1168 | } |
1170 | mutex_unlock(&root->fs_info->trans_mutex); | 1169 | mutex_unlock(&root->fs_info->trans_mutex); |
1171 | btrfs_defrag_dirty_roots(root->fs_info); | ||
1172 | trans = btrfs_start_transaction(root, 1); | 1170 | trans = btrfs_start_transaction(root, 1); |
1173 | ret = btrfs_commit_transaction(trans, root); | 1171 | ret = btrfs_commit_transaction(trans, root); |
1174 | sleep: | 1172 | sleep: |
@@ -1434,12 +1432,12 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1434 | tree_root, | 1432 | tree_root, |
1435 | "btrfs-transaction"); | 1433 | "btrfs-transaction"); |
1436 | if (!fs_info->transaction_kthread) | 1434 | if (!fs_info->transaction_kthread) |
1437 | goto fail_trans_kthread; | 1435 | goto fail_cleaner; |
1438 | 1436 | ||
1439 | 1437 | ||
1440 | return tree_root; | 1438 | return tree_root; |
1441 | 1439 | ||
1442 | fail_trans_kthread: | 1440 | fail_cleaner: |
1443 | kthread_stop(fs_info->cleaner_kthread); | 1441 | kthread_stop(fs_info->cleaner_kthread); |
1444 | fail_extent_root: | 1442 | fail_extent_root: |
1445 | free_extent_buffer(extent_root->node); | 1443 | free_extent_buffer(extent_root->node); |
@@ -1662,7 +1660,6 @@ int close_ctree(struct btrfs_root *root) | |||
1662 | kthread_stop(root->fs_info->transaction_kthread); | 1660 | kthread_stop(root->fs_info->transaction_kthread); |
1663 | kthread_stop(root->fs_info->cleaner_kthread); | 1661 | kthread_stop(root->fs_info->cleaner_kthread); |
1664 | 1662 | ||
1665 | btrfs_defrag_dirty_roots(root->fs_info); | ||
1666 | btrfs_clean_old_snapshots(root); | 1663 | btrfs_clean_old_snapshots(root); |
1667 | trans = btrfs_start_transaction(root, 1); | 1664 | trans = btrfs_start_transaction(root, 1); |
1668 | ret = btrfs_commit_transaction(trans, root); | 1665 | ret = btrfs_commit_transaction(trans, root); |
@@ -1794,58 +1791,6 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) | |||
1794 | return; | 1791 | return; |
1795 | } | 1792 | } |
1796 | 1793 | ||
1797 | void btrfs_set_buffer_defrag(struct extent_buffer *buf) | ||
1798 | { | ||
1799 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1800 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1801 | set_extent_bits(&BTRFS_I(btree_inode)->io_tree, buf->start, | ||
1802 | buf->start + buf->len - 1, EXTENT_DEFRAG, GFP_NOFS); | ||
1803 | } | ||
1804 | |||
1805 | void btrfs_set_buffer_defrag_done(struct extent_buffer *buf) | ||
1806 | { | ||
1807 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1808 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1809 | set_extent_bits(&BTRFS_I(btree_inode)->io_tree, buf->start, | ||
1810 | buf->start + buf->len - 1, EXTENT_DEFRAG_DONE, | ||
1811 | GFP_NOFS); | ||
1812 | } | ||
1813 | |||
1814 | int btrfs_buffer_defrag(struct extent_buffer *buf) | ||
1815 | { | ||
1816 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1817 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1818 | return test_range_bit(&BTRFS_I(btree_inode)->io_tree, | ||
1819 | buf->start, buf->start + buf->len - 1, EXTENT_DEFRAG, 0); | ||
1820 | } | ||
1821 | |||
1822 | int btrfs_buffer_defrag_done(struct extent_buffer *buf) | ||
1823 | { | ||
1824 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1825 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1826 | return test_range_bit(&BTRFS_I(btree_inode)->io_tree, | ||
1827 | buf->start, buf->start + buf->len - 1, | ||
1828 | EXTENT_DEFRAG_DONE, 0); | ||
1829 | } | ||
1830 | |||
1831 | int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf) | ||
1832 | { | ||
1833 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1834 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1835 | return clear_extent_bits(&BTRFS_I(btree_inode)->io_tree, | ||
1836 | buf->start, buf->start + buf->len - 1, | ||
1837 | EXTENT_DEFRAG_DONE, GFP_NOFS); | ||
1838 | } | ||
1839 | |||
1840 | int btrfs_clear_buffer_defrag(struct extent_buffer *buf) | ||
1841 | { | ||
1842 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | ||
1843 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
1844 | return clear_extent_bits(&BTRFS_I(btree_inode)->io_tree, | ||
1845 | buf->start, buf->start + buf->len - 1, | ||
1846 | EXTENT_DEFRAG, GFP_NOFS); | ||
1847 | } | ||
1848 | |||
1849 | int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | 1794 | int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) |
1850 | { | 1795 | { |
1851 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; | 1796 | struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; |