Commit d2eee258 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.6-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
 "These are fixes that were found during testing with help of error
  injection, plus some other stable material.

  There's a fixup to patch added to rc1 causing locking in wrong context
  warnings, tests found one more deadlock scenario. The patches are
  tagged for stable, two of them now in the queue but we'd like all
  three released at the same time.

  I'm not happy about fixes to fixes in such a fast succession during
  rcs, but I hope we found all the fallouts of commit 28553fa9
  ('Btrfs: fix race between shrinking truncate and fiemap')"

* tag 'for-5.6-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  Btrfs: fix deadlock during fast fsync when logging prealloc extents beyond eof
  Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered extents
  btrfs: fix bytes_may_use underflow in prealloc error condtition
  btrfs: handle logged extent failure properly
  btrfs: do not check delayed items are empty for single transaction cleanup
  btrfs: reset fs_root to NULL on error in open_ctree
  btrfs: destroy qgroup extent records on transaction abort
parents a3163ca0 a5ae50de
...@@ -3200,6 +3200,7 @@ int __cold open_ctree(struct super_block *sb, ...@@ -3200,6 +3200,7 @@ int __cold open_ctree(struct super_block *sb,
if (IS_ERR(fs_info->fs_root)) { if (IS_ERR(fs_info->fs_root)) {
err = PTR_ERR(fs_info->fs_root); err = PTR_ERR(fs_info->fs_root);
btrfs_warn(fs_info, "failed to read fs tree: %d", err); btrfs_warn(fs_info, "failed to read fs tree: %d", err);
fs_info->fs_root = NULL;
goto fail_qgroup; goto fail_qgroup;
} }
...@@ -4276,6 +4277,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, ...@@ -4276,6 +4277,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
cond_resched(); cond_resched();
spin_lock(&delayed_refs->lock); spin_lock(&delayed_refs->lock);
} }
btrfs_qgroup_destroy_extent_records(trans);
spin_unlock(&delayed_refs->lock); spin_unlock(&delayed_refs->lock);
...@@ -4501,7 +4503,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, ...@@ -4501,7 +4503,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
wake_up(&fs_info->transaction_wait); wake_up(&fs_info->transaction_wait);
btrfs_destroy_delayed_inodes(fs_info); btrfs_destroy_delayed_inodes(fs_info);
btrfs_assert_delayed_root_empty(fs_info);
btrfs_destroy_marked_extents(fs_info, &cur_trans->dirty_pages, btrfs_destroy_marked_extents(fs_info, &cur_trans->dirty_pages,
EXTENT_DIRTY); EXTENT_DIRTY);
......
...@@ -4430,6 +4430,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, ...@@ -4430,6 +4430,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
ret = alloc_reserved_file_extent(trans, 0, root_objectid, 0, owner, ret = alloc_reserved_file_extent(trans, 0, root_objectid, 0, owner,
offset, ins, 1); offset, ins, 1);
if (ret)
btrfs_pin_extent(fs_info, ins->objectid, ins->offset, 1);
btrfs_put_block_group(block_group); btrfs_put_block_group(block_group);
return ret; return ret;
} }
......
...@@ -4103,6 +4103,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, ...@@ -4103,6 +4103,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
return -ENOMEM; return -ENOMEM;
path->reada = READA_BACK; path->reada = READA_BACK;
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1, lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1,
&cached_state); &cached_state);
...@@ -4368,11 +4369,10 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, ...@@ -4368,11 +4369,10 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
if (!ret && last_size > new_size) if (!ret && last_size > new_size)
last_size = new_size; last_size = new_size;
btrfs_ordered_update_i_size(inode, last_size, NULL); btrfs_ordered_update_i_size(inode, last_size, NULL);
unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start,
(u64)-1, &cached_state);
} }
unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1,
&cached_state);
btrfs_free_path(path); btrfs_free_path(path);
return ret; return ret;
} }
...@@ -9824,6 +9824,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, ...@@ -9824,6 +9824,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_key ins; struct btrfs_key ins;
u64 cur_offset = start; u64 cur_offset = start;
u64 clear_offset = start;
u64 i_size; u64 i_size;
u64 cur_bytes; u64 cur_bytes;
u64 last_alloc = (u64)-1; u64 last_alloc = (u64)-1;
...@@ -9858,6 +9859,15 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, ...@@ -9858,6 +9859,15 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
btrfs_end_transaction(trans); btrfs_end_transaction(trans);
break; break;
} }
/*
* We've reserved this space, and thus converted it from
* ->bytes_may_use to ->bytes_reserved. Any error that happens
* from here on out we will only need to clear our reservation
* for the remaining unreserved area, so advance our
* clear_offset by our extent size.
*/
clear_offset += ins.offset;
btrfs_dec_block_group_reservations(fs_info, ins.objectid); btrfs_dec_block_group_reservations(fs_info, ins.objectid);
last_alloc = ins.offset; last_alloc = ins.offset;
...@@ -9937,9 +9947,9 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, ...@@ -9937,9 +9947,9 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
if (own_trans) if (own_trans)
btrfs_end_transaction(trans); btrfs_end_transaction(trans);
} }
if (cur_offset < end) if (clear_offset < end)
btrfs_free_reserved_data_space(inode, NULL, cur_offset, btrfs_free_reserved_data_space(inode, NULL, clear_offset,
end - cur_offset + 1); end - clear_offset + 1);
return ret; return ret;
} }
......
...@@ -679,10 +679,15 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) ...@@ -679,10 +679,15 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
} }
btrfs_start_ordered_extent(inode, ordered, 1); btrfs_start_ordered_extent(inode, ordered, 1);
end = ordered->file_offset; end = ordered->file_offset;
/*
* If the ordered extent had an error save the error but don't
* exit without waiting first for all other ordered extents in
* the range to complete.
*/
if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags))
ret = -EIO; ret = -EIO;
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
if (ret || end == 0 || end == start) if (end == 0 || end == start)
break; break;
end--; end--;
} }
......
...@@ -4002,3 +4002,16 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, ...@@ -4002,3 +4002,16 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
} }
return ret; return ret;
} }
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans)
{
struct btrfs_qgroup_extent_record *entry;
struct btrfs_qgroup_extent_record *next;
struct rb_root *root;
root = &trans->delayed_refs.dirty_extent_root;
rbtree_postorder_for_each_entry_safe(entry, next, root, node) {
ulist_free(entry->old_roots);
kfree(entry);
}
}
...@@ -414,5 +414,6 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans, ...@@ -414,5 +414,6 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans,
u64 last_snapshot); u64 last_snapshot);
int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *eb); struct btrfs_root *root, struct extent_buffer *eb);
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans);
#endif #endif
...@@ -121,6 +121,8 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction) ...@@ -121,6 +121,8 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
BUG_ON(!list_empty(&transaction->list)); BUG_ON(!list_empty(&transaction->list));
WARN_ON(!RB_EMPTY_ROOT( WARN_ON(!RB_EMPTY_ROOT(
&transaction->delayed_refs.href_root.rb_root)); &transaction->delayed_refs.href_root.rb_root));
WARN_ON(!RB_EMPTY_ROOT(
&transaction->delayed_refs.dirty_extent_root));
if (transaction->delayed_refs.pending_csums) if (transaction->delayed_refs.pending_csums)
btrfs_err(transaction->fs_info, btrfs_err(transaction->fs_info,
"pending csums is %llu", "pending csums is %llu",
......
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