aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/relocation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r--fs/btrfs/relocation.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index cfcc93c93a7b..e558dd941ded 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -21,6 +21,7 @@
21#include <linux/writeback.h> 21#include <linux/writeback.h>
22#include <linux/blkdev.h> 22#include <linux/blkdev.h>
23#include <linux/rbtree.h> 23#include <linux/rbtree.h>
24#include <linux/slab.h>
24#include "ctree.h" 25#include "ctree.h"
25#include "disk-io.h" 26#include "disk-io.h"
26#include "transaction.h" 27#include "transaction.h"
@@ -170,14 +171,14 @@ struct async_merge {
170 171
171static void mapping_tree_init(struct mapping_tree *tree) 172static void mapping_tree_init(struct mapping_tree *tree)
172{ 173{
173 tree->rb_root.rb_node = NULL; 174 tree->rb_root = RB_ROOT;
174 spin_lock_init(&tree->lock); 175 spin_lock_init(&tree->lock);
175} 176}
176 177
177static void backref_cache_init(struct backref_cache *cache) 178static void backref_cache_init(struct backref_cache *cache)
178{ 179{
179 int i; 180 int i;
180 cache->rb_root.rb_node = NULL; 181 cache->rb_root = RB_ROOT;
181 for (i = 0; i < BTRFS_MAX_LEVEL; i++) 182 for (i = 0; i < BTRFS_MAX_LEVEL; i++)
182 INIT_LIST_HEAD(&cache->pending[i]); 183 INIT_LIST_HEAD(&cache->pending[i]);
183 spin_lock_init(&cache->lock); 184 spin_lock_init(&cache->lock);
@@ -1561,6 +1562,20 @@ static int invalidate_extent_cache(struct btrfs_root *root,
1561 return 0; 1562 return 0;
1562} 1563}
1563 1564
1565static void put_inodes(struct list_head *list)
1566{
1567 struct inodevec *ivec;
1568 while (!list_empty(list)) {
1569 ivec = list_entry(list->next, struct inodevec, list);
1570 list_del(&ivec->list);
1571 while (ivec->nr > 0) {
1572 ivec->nr--;
1573 iput(ivec->inode[ivec->nr]);
1574 }
1575 kfree(ivec);
1576 }
1577}
1578
1564static int find_next_key(struct btrfs_path *path, int level, 1579static int find_next_key(struct btrfs_path *path, int level,
1565 struct btrfs_key *key) 1580 struct btrfs_key *key)
1566 1581
@@ -1723,6 +1738,11 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
1723 1738
1724 btrfs_btree_balance_dirty(root, nr); 1739 btrfs_btree_balance_dirty(root, nr);
1725 1740
1741 /*
1742 * put inodes outside transaction, otherwise we may deadlock.
1743 */
1744 put_inodes(&inode_list);
1745
1726 if (replaced && rc->stage == UPDATE_DATA_PTRS) 1746 if (replaced && rc->stage == UPDATE_DATA_PTRS)
1727 invalidate_extent_cache(root, &key, &next_key); 1747 invalidate_extent_cache(root, &key, &next_key);
1728 } 1748 }
@@ -1752,19 +1772,7 @@ out:
1752 1772
1753 btrfs_btree_balance_dirty(root, nr); 1773 btrfs_btree_balance_dirty(root, nr);
1754 1774
1755 /* 1775 put_inodes(&inode_list);
1756 * put inodes while we aren't holding the tree locks
1757 */
1758 while (!list_empty(&inode_list)) {
1759 struct inodevec *ivec;
1760 ivec = list_entry(inode_list.next, struct inodevec, list);
1761 list_del(&ivec->list);
1762 while (ivec->nr > 0) {
1763 ivec->nr--;
1764 iput(ivec->inode[ivec->nr]);
1765 }
1766 kfree(ivec);
1767 }
1768 1776
1769 if (replaced && rc->stage == UPDATE_DATA_PTRS) 1777 if (replaced && rc->stage == UPDATE_DATA_PTRS)
1770 invalidate_extent_cache(root, &key, &next_key); 1778 invalidate_extent_cache(root, &key, &next_key);
@@ -2652,7 +2660,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
2652 EXTENT_BOUNDARY, GFP_NOFS); 2660 EXTENT_BOUNDARY, GFP_NOFS);
2653 nr++; 2661 nr++;
2654 } 2662 }
2655 btrfs_set_extent_delalloc(inode, page_start, page_end); 2663 btrfs_set_extent_delalloc(inode, page_start, page_end, NULL);
2656 2664
2657 set_page_dirty(page); 2665 set_page_dirty(page);
2658 dirty_page++; 2666 dirty_page++;
@@ -3274,8 +3282,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3274 return -ENOMEM; 3282 return -ENOMEM;
3275 3283
3276 path = btrfs_alloc_path(); 3284 path = btrfs_alloc_path();
3277 if (!path) 3285 if (!path) {
3286 kfree(cluster);
3278 return -ENOMEM; 3287 return -ENOMEM;
3288 }
3279 3289
3280 rc->extents_found = 0; 3290 rc->extents_found = 0;
3281 rc->extents_skipped = 0; 3291 rc->extents_skipped = 0;
@@ -3478,7 +3488,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
3478 key.objectid = objectid; 3488 key.objectid = objectid;
3479 key.type = BTRFS_INODE_ITEM_KEY; 3489 key.type = BTRFS_INODE_ITEM_KEY;
3480 key.offset = 0; 3490 key.offset = 0;
3481 inode = btrfs_iget(root->fs_info->sb, &key, root); 3491 inode = btrfs_iget(root->fs_info->sb, &key, root, NULL);
3482 BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); 3492 BUG_ON(IS_ERR(inode) || is_bad_inode(inode));
3483 BTRFS_I(inode)->index_cnt = group->key.objectid; 3493 BTRFS_I(inode)->index_cnt = group->key.objectid;
3484 3494
@@ -3534,8 +3544,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3534 (unsigned long long)rc->block_group->key.objectid, 3544 (unsigned long long)rc->block_group->key.objectid,
3535 (unsigned long long)rc->block_group->flags); 3545 (unsigned long long)rc->block_group->flags);
3536 3546
3537 btrfs_start_delalloc_inodes(fs_info->tree_root); 3547 btrfs_start_delalloc_inodes(fs_info->tree_root, 0);
3538 btrfs_wait_ordered_extents(fs_info->tree_root, 0); 3548 btrfs_wait_ordered_extents(fs_info->tree_root, 0, 0);
3539 3549
3540 while (1) { 3550 while (1) {
3541 rc->extents_found = 0; 3551 rc->extents_found = 0;
@@ -3755,6 +3765,8 @@ out:
3755 BTRFS_DATA_RELOC_TREE_OBJECTID); 3765 BTRFS_DATA_RELOC_TREE_OBJECTID);
3756 if (IS_ERR(fs_root)) 3766 if (IS_ERR(fs_root))
3757 err = PTR_ERR(fs_root); 3767 err = PTR_ERR(fs_root);
3768 else
3769 btrfs_orphan_cleanup(fs_root);
3758 } 3770 }
3759 return err; 3771 return err;
3760} 3772}