Commit 35c76642 authored by Filipe Manana's avatar Filipe Manana Committed by Chris Mason

Btrfs: fix mutex unlock without prior lock on space cache truncation

If the call to btrfs_truncate_inode_items() failed and we don't have a block
group, we were unlocking the cache_write_mutex without having locked it (we
do it only if we have a block group).

Fixes: 1bbc621e ("Btrfs: allow block group cache writeout
                      outside critical section in commit")
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.cz>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 816fcebe
...@@ -231,6 +231,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ...@@ -231,6 +231,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
{ {
int ret = 0; int ret = 0;
struct btrfs_path *path = btrfs_alloc_path(); struct btrfs_path *path = btrfs_alloc_path();
bool locked = false;
if (!path) { if (!path) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -238,6 +239,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ...@@ -238,6 +239,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
} }
if (block_group) { if (block_group) {
locked = true;
mutex_lock(&trans->transaction->cache_write_mutex); mutex_lock(&trans->transaction->cache_write_mutex);
if (!list_empty(&block_group->io_list)) { if (!list_empty(&block_group->io_list)) {
list_del_init(&block_group->io_list); list_del_init(&block_group->io_list);
...@@ -269,18 +271,14 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ...@@ -269,18 +271,14 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
*/ */
ret = btrfs_truncate_inode_items(trans, root, inode, ret = btrfs_truncate_inode_items(trans, root, inode,
0, BTRFS_EXTENT_DATA_KEY); 0, BTRFS_EXTENT_DATA_KEY);
if (ret) { if (ret)
mutex_unlock(&trans->transaction->cache_write_mutex); goto fail;
btrfs_abort_transaction(trans, root, ret);
return ret;
}
ret = btrfs_update_inode(trans, root, inode); ret = btrfs_update_inode(trans, root, inode);
if (block_group)
mutex_unlock(&trans->transaction->cache_write_mutex);
fail: fail:
if (locked)
mutex_unlock(&trans->transaction->cache_write_mutex);
if (ret) if (ret)
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
......
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