* File system states
  */
 #define BTRFS_FS_STATE_ERROR           0
+#define BTRFS_FS_STATE_REMOUNTING      1
 
 /* Super block flags */
 /* Errors detected */
 
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
+#define btrfs_raw_test_opt(o, opt)     ((o) & BTRFS_MOUNT_##opt)
 #define btrfs_test_opt(root, opt)      ((root)->fs_info->mount_opt & \
                                         BTRFS_MOUNT_##opt)
 /*
 
                              new_pool_size);
 }
 
+static inline void btrfs_remount_prepare(struct btrfs_fs_info *fs_info,
+                                        unsigned long old_opts, int flags)
+{
+       set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
+
+       if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) &&
+           (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) ||
+            (flags & MS_RDONLY))) {
+               /* wait for any defraggers to finish */
+               wait_event(fs_info->transaction_wait,
+                          (atomic_read(&fs_info->defrag_running) == 0));
+               if (flags & MS_RDONLY)
+                       sync_filesystem(fs_info->sb);
+       }
+}
+
+static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info,
+                                        unsigned long old_opts)
+{
+       /*
+        * We need cleanup all defragable inodes if the autodefragment is
+        * close or the fs is R/O.
+        */
+       if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) &&
+           (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) ||
+            (fs_info->sb->s_flags & MS_RDONLY))) {
+               btrfs_cleanup_defrag_inodes(fs_info);
+       }
+
+       clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
+}
+
 static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(sb);
        unsigned int old_metadata_ratio = fs_info->metadata_ratio;
        int ret;
 
+       btrfs_remount_prepare(fs_info, old_opts, *flags);
+
        ret = btrfs_parse_options(root, data);
        if (ret) {
                ret = -EINVAL;
                fs_info->thread_pool_size, old_thread_pool_size);
 
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
-               return 0;
+               goto out;
 
        if (*flags & MS_RDONLY) {
                /*
                }
                sb->s_flags &= ~MS_RDONLY;
        }
-
+out:
+       btrfs_remount_cleanup(fs_info, old_opts);
        return 0;
 
 restore:
        btrfs_resize_thread_pool(fs_info,
                old_thread_pool_size, fs_info->thread_pool_size);
        fs_info->metadata_ratio = old_metadata_ratio;
+       btrfs_remount_cleanup(fs_info, old_opts);
        return ret;
 }