Commit e44163e1 authored by Jeff Mahoney's avatar Jeff Mahoney Committed by Chris Mason

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: default avatarJeff Mahoney <jeffm@suse.com>
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Tested-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 499f377f
...@@ -3767,6 +3767,15 @@ void close_ctree(struct btrfs_root *root) ...@@ -3767,6 +3767,15 @@ void close_ctree(struct btrfs_root *root)
cancel_work_sync(&fs_info->async_reclaim_work); cancel_work_sync(&fs_info->async_reclaim_work);
if (!(fs_info->sb->s_flags & MS_RDONLY)) { if (!(fs_info->sb->s_flags & MS_RDONLY)) {
/*
* If the cleaner thread is stopped and there are
* block groups queued for removal, the deletion will be
* skipped when we quit the cleaner thread.
*/
mutex_lock(&root->fs_info->cleaner_mutex);
btrfs_delete_unused_bgs(root->fs_info);
mutex_unlock(&root->fs_info->cleaner_mutex);
ret = btrfs_commit_super(root); ret = btrfs_commit_super(root);
if (ret) if (ret)
btrfs_err(fs_info, "commit super ret %d", ret); btrfs_err(fs_info, "commit super ret %d", ret);
......
...@@ -1650,6 +1650,17 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -1650,6 +1650,17 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
sb->s_flags |= MS_RDONLY; sb->s_flags |= MS_RDONLY;
/*
* Setting MS_RDONLY will put the cleaner thread to
* sleep at the next loop if it's already active.
* If it's already asleep, we'll leave unused block
* groups on disk until we're mounted read-write again
* unless we clean them up here.
*/
mutex_lock(&root->fs_info->cleaner_mutex);
btrfs_delete_unused_bgs(fs_info);
mutex_unlock(&root->fs_info->cleaner_mutex);
btrfs_dev_replace_suspend_for_unmount(fs_info); btrfs_dev_replace_suspend_for_unmount(fs_info);
btrfs_scrub_cancel(fs_info); btrfs_scrub_cancel(fs_info);
btrfs_pause_balance(fs_info); btrfs_pause_balance(fs_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment