If we remount the fs to be readonly or umount it, we should not continue
defraging the files, it is because
- the auto defragment will introduce lots of dirty pages, it breaks the rule
  of a readonly file system.
- it make the time of remount/umount become longer.

Signed-off-by: Miao Xie <[email protected]>
---
 fs/btrfs/disk-io.c |   12 +++++++-----
 fs/btrfs/file.c    |    3 ++-
 fs/btrfs/super.c   |    5 +++++
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 20196f4..9a571f7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1529,6 +1529,9 @@ static int cleaner_kthread(void *arg)
        do {
                vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
 
+               if (!down_read_trylock(&root->fs_info->sb->s_umount))
+                       goto skip;
+
                if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
                    mutex_trylock(&root->fs_info->cleaner_mutex)) {
                        btrfs_run_delayed_iputs(root);
@@ -1536,7 +1539,8 @@ static int cleaner_kthread(void *arg)
                        mutex_unlock(&root->fs_info->cleaner_mutex);
                        btrfs_run_defrag_inodes(root->fs_info);
                }
-
+               up_read(&root->fs_info->sb->s_umount);
+skip:
                if (!try_to_freeze()) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        if (!kthread_should_stop())
@@ -3049,13 +3053,11 @@ int close_ctree(struct btrfs_root *root)
 
        btrfs_scrub_cancel(root);
 
-       /* wait for any defraggers to finish */
-       wait_event(fs_info->transaction_wait,
-                  (atomic_read(&fs_info->defrag_running) == 0));
-
        /* clear out the rbtree of defraggable inodes */
        btrfs_run_defrag_inodes(fs_info);
 
+       BUG_ON(atomic_read(&fs_info->defrag_running));
+
        /*
         * Here come 2 situations when btrfs is broken to flip readonly:
         *
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index d83260d..23364c1 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -230,7 +230,8 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
                first_ino = defrag->ino + 1;
                rb_erase(&defrag->rb_node, &fs_info->defrag_inodes);
 
-               if (btrfs_fs_closing(fs_info))
+               if (btrfs_fs_closing(fs_info) ||
+                   (fs_info->sb->s_flags & MS_RDONLY))
                        goto next_free;
 
                spin_unlock(&fs_info->defrag_inodes_lock);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 84571d7..7deb00e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1151,6 +1151,11 @@ static int btrfs_remount(struct super_block *sb, int 
*flags, char *data)
                ret = btrfs_commit_super(root);
                if (ret)
                        goto restore;
+
+               /* clear out the rbtree of defraggable inodes */
+               btrfs_run_defrag_inodes(fs_info);
+
+               BUG_ON(atomic_read(&fs_info->defrag_running));
        } else {
                if (fs_info->fs_devices->rw_devices == 0)
                        ret = -EACCES;
-- 
1.7.6.5
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to