Merge tag 'v3.10.64' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / btrfs / disk-io.c
index e7b3cb5286a5a699c4716a8a5dc2ae6a0e54f622..d70ee41d08de58bc90960e183a9661ef5d09b64e 100644 (file)
@@ -1677,6 +1677,8 @@ static int cleaner_kthread(void *arg)
 {
        struct btrfs_root *root = arg;
 
+       set_freezable();
+
        do {
                int again = 0;
 
@@ -1693,11 +1695,11 @@ static int cleaner_kthread(void *arg)
 
                if (!try_to_freeze() && !again) {
                        set_current_state(TASK_INTERRUPTIBLE);
-                       if (!kthread_should_stop())
+                       if (!kthread_freezable_should_stop(NULL))
                                schedule();
                        __set_current_state(TASK_RUNNING);
                }
-       } while (!kthread_should_stop());
+       } while (!kthread_freezable_should_stop(NULL));
        return 0;
 }
 
@@ -1711,6 +1713,8 @@ static int transaction_kthread(void *arg)
        unsigned long delay;
        bool cannot_commit;
 
+       set_freezable();
+
        do {
                cannot_commit = false;
                delay = HZ * 30;
@@ -1751,13 +1755,13 @@ sleep:
 
                if (!try_to_freeze()) {
                        set_current_state(TASK_INTERRUPTIBLE);
-                       if (!kthread_should_stop() &&
+                       if (!kthread_freezable_should_stop(NULL) &&
                            (!btrfs_transaction_blocked(root->fs_info) ||
                             cannot_commit))
                                schedule_timeout(delay);
                        __set_current_state(TASK_RUNNING);
                }
-       } while (!kthread_should_stop());
+       } while (!kthread_freezable_should_stop(NULL));
        return 0;
 }
 
@@ -2859,8 +2863,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);
 
@@ -3161,6 +3165,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
        /* send down all the barriers */
        head = &info->fs_devices->devices;
        list_for_each_entry_rcu(dev, head, dev_list) {
+               if (dev->missing)
+                       continue;
                if (!dev->bdev) {
                        errors_send++;
                        continue;
@@ -3175,6 +3181,8 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
 
        /* wait for all the barriers */
        list_for_each_entry_rcu(dev, head, dev_list) {
+               if (dev->missing)
+                       continue;
                if (!dev->bdev) {
                        errors_wait++;
                        continue;
@@ -3512,15 +3520,20 @@ 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);
 
+       /*
+        * we must make sure there is not any read request to
+        * submit after we stopping all workers.
+        */
+       invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
+       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))
@@ -3848,12 +3861,6 @@ again:
                if (ret)
                        break;
 
-               /* opt_discard */
-               if (btrfs_test_opt(root, DISCARD))
-                       ret = btrfs_error_discard_extent(root, start,
-                                                        end + 1 - start,
-                                                        NULL);
-
                clear_extent_dirty(unpin, start, end, GFP_NOFS);
                btrfs_error_unpin_extent_range(root, start, end);
                cond_resched();