]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jun 2013 05:34:14 +0000 (22:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jun 2013 05:34:14 +0000 (22:34 -0700)
Pull btrfs fixes from Chris Mason:
 "This is an assortment of crash fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: stop all workers before cleaning up roots
  Btrfs: fix use-after-free bug during umount
  Btrfs: init relocate extent_io_tree with a mapping
  btrfs: Drop inode if inode root is NULL
  Btrfs: don't delete fs_roots until after we cleanup the transaction

fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/relocation.c

index e7b3cb5286a5a699c4716a8a5dc2ae6a0e54f622..b8b60b660c8f833cb38bf93823e1a3738e32669a 100644 (file)
@@ -2859,8 +2859,8 @@ fail_qgroup:
        btrfs_free_qgroup_config(fs_info);
 fail_trans_kthread:
        kthread_stop(fs_info->transaction_kthread);
-       del_fs_roots(fs_info);
        btrfs_cleanup_transaction(fs_info->tree_root);
+       del_fs_roots(fs_info);
 fail_cleaner:
        kthread_stop(fs_info->cleaner_kthread);
 
@@ -3512,15 +3512,15 @@ int close_ctree(struct btrfs_root *root)
                       percpu_counter_sum(&fs_info->delalloc_bytes));
        }
 
-       free_root_pointers(fs_info, 1);
-
        btrfs_free_block_groups(fs_info);
 
+       btrfs_stop_all_workers(fs_info);
+
        del_fs_roots(fs_info);
 
-       iput(fs_info->btree_inode);
+       free_root_pointers(fs_info, 1);
 
-       btrfs_stop_all_workers(fs_info);
+       iput(fs_info->btree_inode);
 
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        if (btrfs_test_opt(root, CHECK_INTEGRITY))
index af978f7682b3441282b0f54e62a60b7534d51203..17f3064b4a3ebf7b65188be58b66713670f00ca9 100644 (file)
@@ -8012,6 +8012,9 @@ int btrfs_drop_inode(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
+       if (root == NULL)
+               return 1;
+
        /* the snap/subvol tree is on deleting */
        if (btrfs_root_refs(&root->root_item) == 0 &&
            root != root->fs_info->tree_root)
index 395b82031a4286f2a8a1481bc87a684172468b96..4febca4fc2de7fe79fb9239a5e44f9ce3ad4eba0 100644 (file)
@@ -4082,7 +4082,7 @@ out:
        return inode;
 }
 
-static struct reloc_control *alloc_reloc_control(void)
+static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
 {
        struct reloc_control *rc;
 
@@ -4093,7 +4093,8 @@ static struct reloc_control *alloc_reloc_control(void)
        INIT_LIST_HEAD(&rc->reloc_roots);
        backref_cache_init(&rc->backref_cache);
        mapping_tree_init(&rc->reloc_root_tree);
-       extent_io_tree_init(&rc->processed_blocks, NULL);
+       extent_io_tree_init(&rc->processed_blocks,
+                           fs_info->btree_inode->i_mapping);
        return rc;
 }
 
@@ -4110,7 +4111,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        int rw = 0;
        int err = 0;
 
-       rc = alloc_reloc_control();
+       rc = alloc_reloc_control(fs_info);
        if (!rc)
                return -ENOMEM;
 
@@ -4311,7 +4312,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
        if (list_empty(&reloc_roots))
                goto out;
 
-       rc = alloc_reloc_control();
+       rc = alloc_reloc_control(root->fs_info);
        if (!rc) {
                err = -ENOMEM;
                goto out;