summaryrefslogtreecommitdiff
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-05-16 15:46:23 +0200
committerDavid Sterba <dsterba@suse.com>2016-05-16 15:46:23 +0200
commit73d32ce21e1701eaafcea3cbc2a8f27ab1967abe (patch)
tree136c03e4be575e4466ef9df119b8debdf768a56a /fs/btrfs/disk-io.c
parent02da2d72174c61988eb4456b53f405e3ebdebce4 (diff)
parent4673272f43ae790ab9ec04e38a7542f82bb8f020 (diff)
Merge branch 'misc-4.7' into for-chris-4.7-20160516
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4e47849d7427..070c1dad42bd 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2517,6 +2517,7 @@ int open_ctree(struct super_block *sb,
int num_backups_tried = 0;
int backup_index = 0;
int max_active;
+ bool cleaner_mutex_locked = false;
tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
@@ -2997,6 +2998,13 @@ retry_root_backup:
goto fail_sysfs;
}
+ /*
+ * Hold the cleaner_mutex thread here so that we don't block
+ * for a long time on btrfs_recover_relocation. cleaner_kthread
+ * will wait for us to finish mounting the filesystem.
+ */
+ mutex_lock(&fs_info->cleaner_mutex);
+ cleaner_mutex_locked = true;
fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
"btrfs-cleaner");
if (IS_ERR(fs_info->cleaner_kthread))
@@ -3056,10 +3064,8 @@ retry_root_backup:
ret = btrfs_cleanup_fs_roots(fs_info);
if (ret)
goto fail_qgroup;
-
- mutex_lock(&fs_info->cleaner_mutex);
+ /* We locked cleaner_mutex before creating cleaner_kthread. */
ret = btrfs_recover_relocation(tree_root);
- mutex_unlock(&fs_info->cleaner_mutex);
if (ret < 0) {
printk(KERN_WARNING
"BTRFS: failed to recover relocation\n");
@@ -3067,6 +3073,8 @@ retry_root_backup:
goto fail_qgroup;
}
}
+ mutex_unlock(&fs_info->cleaner_mutex);
+ cleaner_mutex_locked = false;
location.objectid = BTRFS_FS_TREE_OBJECTID;
location.type = BTRFS_ROOT_ITEM_KEY;
@@ -3180,6 +3188,10 @@ fail_cleaner:
filemap_write_and_wait(fs_info->btree_inode->i_mapping);
fail_sysfs:
+ if (cleaner_mutex_locked) {
+ mutex_unlock(&fs_info->cleaner_mutex);
+ cleaner_mutex_locked = false;
+ }
btrfs_sysfs_remove_mounted(fs_info);
fail_fsdev_sysfs: