for-5.6-rc2-tag
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl5SdTAACgkQxWXV+ddt
WDtOPQ/+PGbN2bfZSf0DBUcOC+IOdiCYWHmaO6NQZzQb4CTjuumsDErSTzbg77OQ
gBqRBfcaWnyZZIabHe0JjctQ//buycP8yGb8VevgVdD4qBnb5sM/pvBqT4kO9Omy
6K3W7RhcP8gejOxGJb4nuiUBdYRW3KTji8QT3TMv/njuqn0p8n1NgzVlz0m6+xtO
IfJOqThvvG9LBytsQq/pvqaoXID/06lXRyM42XbsKFyygv10vp69xz5Skdl1XkGk
pyymzLlLDkLorRuDkjnzIvOqNFDAYiSFJafHupSE4SlfscRYfTwCV0uXE+NX4bdL
piTr5169ALoIRyTHU37YNNCPZXNGHnmn5Mtf4o8Q0ps0MKz1+sIjFRAxrdolLHjw
iYcocXU9L5wtHUBouTBzAsnuWJnizJNExHYb/3MHnHZYDu371l8wOGL1AHzRXEm/
qkxTPS3V2JpaFkFvTmwEQbl8PzDgpxpPDDBQUcEBZn3Vb9AFX38Fo/5OiGOnpnTd
9wVKXK2S6vHz/xpfcT/3SOtDUljSPJMUXUVkVcdz+OfUWvn6icXzR0t4keXVqZv+
INSOHzXb+iCuIb+NX7VZTN9oq0GH58aA+ApIo5beNbwJ6EzFotGE8dQmK3AfQ6pU
Pod0gzW5Hqj9Q2AfWYTZjWP+Og+dF2+bQFYSRK8NjcKjcrvUEVU=
=Asj0
-----END PGP SIGNATURE-----
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 28553fa992
('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
This commit is contained in:
commit
d2eee25858
|
@ -3200,6 +3200,7 @@ int __cold open_ctree(struct super_block *sb,
|
|||
if (IS_ERR(fs_info->fs_root)) {
|
||||
err = PTR_ERR(fs_info->fs_root);
|
||||
btrfs_warn(fs_info, "failed to read fs tree: %d", err);
|
||||
fs_info->fs_root = NULL;
|
||||
goto fail_qgroup;
|
||||
}
|
||||
|
||||
|
@ -4276,6 +4277,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
|
|||
cond_resched();
|
||||
spin_lock(&delayed_refs->lock);
|
||||
}
|
||||
btrfs_qgroup_destroy_extent_records(trans);
|
||||
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
|
||||
|
@ -4501,7 +4503,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
|
|||
wake_up(&fs_info->transaction_wait);
|
||||
|
||||
btrfs_destroy_delayed_inodes(fs_info);
|
||||
btrfs_assert_delayed_root_empty(fs_info);
|
||||
|
||||
btrfs_destroy_marked_extents(fs_info, &cur_trans->dirty_pages,
|
||||
EXTENT_DIRTY);
|
||||
|
|
|
@ -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,
|
||||
offset, ins, 1);
|
||||
if (ret)
|
||||
btrfs_pin_extent(fs_info, ins->objectid, ins->offset, 1);
|
||||
btrfs_put_block_group(block_group);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -4103,8 +4103,9 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||
return -ENOMEM;
|
||||
path->reada = READA_BACK;
|
||||
|
||||
lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1,
|
||||
&cached_state);
|
||||
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
|
||||
lock_extent_bits(&BTRFS_I(inode)->io_tree, lock_start, (u64)-1,
|
||||
&cached_state);
|
||||
|
||||
/*
|
||||
* We want to drop from the next block forward in case this new size is
|
||||
|
@ -4368,11 +4369,10 @@ out:
|
|||
if (!ret && last_size > new_size)
|
||||
last_size = new_size;
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
@ -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_key ins;
|
||||
u64 cur_offset = start;
|
||||
u64 clear_offset = start;
|
||||
u64 i_size;
|
||||
u64 cur_bytes;
|
||||
u64 last_alloc = (u64)-1;
|
||||
|
@ -9858,6 +9859,15 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
|
|||
btrfs_end_transaction(trans);
|
||||
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);
|
||||
|
||||
last_alloc = ins.offset;
|
||||
|
@ -9937,9 +9947,9 @@ next:
|
|||
if (own_trans)
|
||||
btrfs_end_transaction(trans);
|
||||
}
|
||||
if (cur_offset < end)
|
||||
btrfs_free_reserved_data_space(inode, NULL, cur_offset,
|
||||
end - cur_offset + 1);
|
||||
if (clear_offset < end)
|
||||
btrfs_free_reserved_data_space(inode, NULL, clear_offset,
|
||||
end - clear_offset + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -679,10 +679,15 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
|
|||
}
|
||||
btrfs_start_ordered_extent(inode, ordered, 1);
|
||||
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))
|
||||
ret = -EIO;
|
||||
btrfs_put_ordered_extent(ordered);
|
||||
if (ret || end == 0 || end == start)
|
||||
if (end == 0 || end == start)
|
||||
break;
|
||||
end--;
|
||||
}
|
||||
|
|
|
@ -4002,3 +4002,16 @@ out:
|
|||
}
|
||||
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,
|
|||
u64 last_snapshot);
|
||||
int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct extent_buffer *eb);
|
||||
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -121,6 +121,8 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
|
|||
BUG_ON(!list_empty(&transaction->list));
|
||||
WARN_ON(!RB_EMPTY_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)
|
||||
btrfs_err(transaction->fs_info,
|
||||
"pending csums is %llu",
|
||||
|
|
Loading…
Reference in New Issue