aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2015-06-15 09:41:18 -0400
committerChris Mason <clm@fb.com>2015-07-29 11:15:27 -0400
commite44163e177960ee60e32a73bffdd53c3a5827406 (patch)
treeffc55e93df052f4077f70ca996f2147dbb940237
parent499f377f49f085ee4aa214c738e948e88626f39b (diff)
btrfs: explictly delete unused block groups in close_ctree and ro-remount
The cleaner thread may already be sleeping by the time we enter close_ctree. If that's the case, we'll skip removing any unused block groups queued for removal, even during a normal umount. They'll be cleaned up automatically at next mount, but users expect a umount to be a clean synchronization point, especially when used on thin-provisioned storage with -odiscard. We also explicitly remove unused block groups in the ro-remount path for the same reason. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Tested-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/disk-io.c9
-rw-r--r--fs/btrfs/super.c11
2 files changed, 20 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 84cbbb2d562e..053109ba26b7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3767,6 +3767,15 @@ void close_ctree(struct btrfs_root *root)
3767 cancel_work_sync(&fs_info->async_reclaim_work); 3767 cancel_work_sync(&fs_info->async_reclaim_work);
3768 3768
3769 if (!(fs_info->sb->s_flags & MS_RDONLY)) { 3769 if (!(fs_info->sb->s_flags & MS_RDONLY)) {
3770 /*
3771 * If the cleaner thread is stopped and there are
3772 * block groups queued for removal, the deletion will be
3773 * skipped when we quit the cleaner thread.
3774 */
3775 mutex_lock(&root->fs_info->cleaner_mutex);
3776 btrfs_delete_unused_bgs(root->fs_info);
3777 mutex_unlock(&root->fs_info->cleaner_mutex);
3778
3770 ret = btrfs_commit_super(root); 3779 ret = btrfs_commit_super(root);
3771 if (ret) 3780 if (ret)
3772 btrfs_err(fs_info, "commit super ret %d", ret); 3781 btrfs_err(fs_info, "commit super ret %d", ret);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index cd7ef34d2dce..a1077e0ffaa8 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1650,6 +1650,17 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1650 1650
1651 sb->s_flags |= MS_RDONLY; 1651 sb->s_flags |= MS_RDONLY;
1652 1652
1653 /*
1654 * Setting MS_RDONLY will put the cleaner thread to
1655 * sleep at the next loop if it's already active.
1656 * If it's already asleep, we'll leave unused block
1657 * groups on disk until we're mounted read-write again
1658 * unless we clean them up here.
1659 */
1660 mutex_lock(&root->fs_info->cleaner_mutex);
1661 btrfs_delete_unused_bgs(fs_info);
1662 mutex_unlock(&root->fs_info->cleaner_mutex);
1663
1653 btrfs_dev_replace_suspend_for_unmount(fs_info); 1664 btrfs_dev_replace_suspend_for_unmount(fs_info);
1654 btrfs_scrub_cancel(fs_info); 1665 btrfs_scrub_cancel(fs_info);
1655 btrfs_pause_balance(fs_info); 1666 btrfs_pause_balance(fs_info);