Commit a68ebe07 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

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: e60efa84 ("Btrfs: avoid triggering bug_on() when we fail to start inode caching task")
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 29d47d00
......@@ -13,6 +13,19 @@
#include "transaction.h"
#include "delalloc-space.h"
static void fail_caching_thread(struct btrfs_root *root)
{
struct btrfs_fs_info *fs_info = root->fs_info;
btrfs_warn(fs_info, "failed to start inode caching task");
btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE,
"disabling inode map caching");
spin_lock(&root->ino_cache_lock);
root->ino_cache_state = BTRFS_CACHE_ERROR;
spin_unlock(&root->ino_cache_lock);
wake_up(&root->ino_cache_wait);
}
static int caching_kthread(void *data)
{
struct btrfs_root *root = data;
......@@ -165,11 +178,8 @@ static void start_caching(struct btrfs_root *root)
tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu",
root->root_key.objectid);
if (IS_ERR(tsk)) {
btrfs_warn(fs_info, "failed to start inode caching task");
btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE,
"disabling inode map caching");
}
if (IS_ERR(tsk))
fail_caching_thread(root);
}
int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
......@@ -187,11 +197,14 @@ int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
wait_event(root->ino_cache_wait,
root->ino_cache_state == BTRFS_CACHE_FINISHED ||
root->ino_cache_state == BTRFS_CACHE_ERROR ||
root->free_ino_ctl->free_space > 0);
if (root->ino_cache_state == BTRFS_CACHE_FINISHED &&
root->free_ino_ctl->free_space == 0)
return -ENOSPC;
else if (root->ino_cache_state == BTRFS_CACHE_ERROR)
return btrfs_find_free_objectid(root, objectid);
else
goto again;
}
......
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