aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-05-14 06:20:40 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:29:32 -0400
commitd027824564c5fcee19109530b87c94c9908e910a (patch)
tree9ee6f6b7c9eaeee8494536061f868e732d607198 /fs/btrfs/disk-io.c
parent3c64a1aba7cfcb04f79e76f859b3d66660275d59 (diff)
Btrfs: remove unnecessary ->s_umount in cleaner_kthread()
In order to avoid the R/O remount, we acquired ->s_umount lock during we deleted the dead snapshots and subvolumes. But it is unnecessary, because we have cleaner_mutex. We use cleaner_mutex to protect the process of the dead snapshots/subvolumes deletion. And when we remount the fs to be R/O, we also acquire this mutex to do cleanup after we change the status of the fs. That is this lock can serialize the above operations, the cleaner can be aware of the status of the fs, and if the cleaner is deleting the dead snapshots/subvolumes, the remount task will wait for it. So it is safe to remove ->s_umount in cleaner_kthread(). Cc: David Sterba <dsterba@suse.cz> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index bc2ea9b53048..7a54b8e7d124 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1673,24 +1673,40 @@ static void end_workqueue_fn(struct btrfs_work *work)
1673 bio_endio(bio, error); 1673 bio_endio(bio, error);
1674} 1674}
1675 1675
1676/*
1677 * If we remount the fs to be R/O, the cleaner needn't do anything except
1678 * sleeping. This function is used to check the status of the fs.
1679 */
1680static inline int need_cleaner_sleep(struct btrfs_root *root)
1681{
1682 return root->fs_info->sb->s_flags & MS_RDONLY;
1683}
1684
1676static int cleaner_kthread(void *arg) 1685static int cleaner_kthread(void *arg)
1677{ 1686{
1678 struct btrfs_root *root = arg; 1687 struct btrfs_root *root = arg;
1688 int again;
1679 1689
1680 do { 1690 do {
1681 int again = 0; 1691 again = 0;
1682
1683 if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
1684 down_read_trylock(&root->fs_info->sb->s_umount)) {
1685 if (mutex_trylock(&root->fs_info->cleaner_mutex)) {
1686 btrfs_run_delayed_iputs(root);
1687 again = btrfs_clean_one_deleted_snapshot(root);
1688 mutex_unlock(&root->fs_info->cleaner_mutex);
1689 }
1690 btrfs_run_defrag_inodes(root->fs_info);
1691 up_read(&root->fs_info->sb->s_umount);
1692 }
1693 1692
1693 /* Make the cleaner go to sleep early. */
1694 if (need_cleaner_sleep(root))
1695 goto sleep;
1696
1697 if (!mutex_trylock(&root->fs_info->cleaner_mutex))
1698 goto sleep;
1699
1700 btrfs_run_delayed_iputs(root);
1701 again = btrfs_clean_one_deleted_snapshot(root);
1702 mutex_unlock(&root->fs_info->cleaner_mutex);
1703
1704 /*
1705 * The defragger has dealt with the R/O remount, needn't
1706 * do anything special here.
1707 */
1708 btrfs_run_defrag_inodes(root->fs_info);
1709sleep:
1694 if (!try_to_freeze() && !again) { 1710 if (!try_to_freeze() && !again) {
1695 set_current_state(TASK_INTERRUPTIBLE); 1711 set_current_state(TASK_INTERRUPTIBLE);
1696 if (!kthread_should_stop()) 1712 if (!kthread_should_stop())