summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode-map.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2019-07-04 11:24:32 -0400
committerDavid Sterba <dsterba@suse.com>2019-09-09 08:59:01 -0400
commita68ebe0790fc88b4314d17984a2cf99ce2361901 (patch)
tree11871e815251466cb2a6f68ecbd02ef92ec7f953 /fs/btrfs/inode-map.c
parent29d47d00e0ae61668ee0c5d90bef2893c8abbafa (diff)
Btrfs: fix inode cache waiters hanging on failure to start caching thread
If we fail to start the inode caching thread, we print an error message and disable the inode cache, however we never wake up any waiters, so they hang forever waiting for the caching to finish. Fix this by waking them up and have them fallback to a call to btrfs_find_free_objectid(). Fixes: e60efa84252c05 ("Btrfs: avoid triggering bug_on() when we fail to start inode caching task") Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode-map.c')
-rw-r--r--fs/btrfs/inode-map.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 45db4fb4b959..c242ae434355 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -13,6 +13,19 @@
13#include "transaction.h" 13#include "transaction.h"
14#include "delalloc-space.h" 14#include "delalloc-space.h"
15 15
16static void fail_caching_thread(struct btrfs_root *root)
17{
18 struct btrfs_fs_info *fs_info = root->fs_info;
19
20 btrfs_warn(fs_info, "failed to start inode caching task");
21 btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE,
22 "disabling inode map caching");
23 spin_lock(&root->ino_cache_lock);
24 root->ino_cache_state = BTRFS_CACHE_ERROR;
25 spin_unlock(&root->ino_cache_lock);
26 wake_up(&root->ino_cache_wait);
27}
28
16static int caching_kthread(void *data) 29static int caching_kthread(void *data)
17{ 30{
18 struct btrfs_root *root = data; 31 struct btrfs_root *root = data;
@@ -165,11 +178,8 @@ static void start_caching(struct btrfs_root *root)
165 178
166 tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu", 179 tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu",
167 root->root_key.objectid); 180 root->root_key.objectid);
168 if (IS_ERR(tsk)) { 181 if (IS_ERR(tsk))
169 btrfs_warn(fs_info, "failed to start inode caching task"); 182 fail_caching_thread(root);
170 btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE,
171 "disabling inode map caching");
172 }
173} 183}
174 184
175int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) 185int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
@@ -187,11 +197,14 @@ again:
187 197
188 wait_event(root->ino_cache_wait, 198 wait_event(root->ino_cache_wait,
189 root->ino_cache_state == BTRFS_CACHE_FINISHED || 199 root->ino_cache_state == BTRFS_CACHE_FINISHED ||
200 root->ino_cache_state == BTRFS_CACHE_ERROR ||
190 root->free_ino_ctl->free_space > 0); 201 root->free_ino_ctl->free_space > 0);
191 202
192 if (root->ino_cache_state == BTRFS_CACHE_FINISHED && 203 if (root->ino_cache_state == BTRFS_CACHE_FINISHED &&
193 root->free_ino_ctl->free_space == 0) 204 root->free_ino_ctl->free_space == 0)
194 return -ENOSPC; 205 return -ENOSPC;
206 else if (root->ino_cache_state == BTRFS_CACHE_ERROR)
207 return btrfs_find_free_objectid(root, objectid);
195 else 208 else
196 goto again; 209 goto again;
197} 210}