for-6.4-rc1-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmRaYhYACgkQxWXV+ddt WDvCRQ/+MjRuInALh+N34mMneF8jjPOlUQBZbaC43XYJ0ss9drSzvE3STmPVrjdK IHyzRYipKI6vdTtzYbyGwxJ9oazsuXTQXC3w/qMW1hO1EAQ0a9tbnTSIQ+BDbU63 BW7rJ3JuM6hKxKK+e9Dserhks0lOgQc+xKT1CUELvAHp3UykD4OrNczguaIT2lGR YXL+9B3ex2SooCqrQStkqEtjD/kxbaYUkK7yWA2FssXWqU5SjZwUOsuY3ZPOWrm1 ULNI67gIxkMkSynV3aYka7nY3xc9oGIfk9WPeylWcOcH3+pWabeptjk617XbA0KI 4biz1zZ/qTRXWlCLDv3ukUa5EIVAWQ1kxVE/hAt3SzqJvoqB/ymML/2LeQNdyx2i adMTZQ95JkhQNU9Lp9QOtpgfZonhhjxnL9KE7eMVo28zJFdYjge3egINjimY+mLz qzrzUBI3bqCNYG0LRR1EvuN0feBd/9nNMFjLBi2mkDqsWtzvTxxzWvVlV5EEcoJe xrozGh00Y5ioP6ZanKuZRib+u2ligbD66dYhKSU74D6B5kuZPic3Kkn9qICjRByM uBGBze/7GT/3ouhPOwxVPtGZstiFhbAxE7mApROrIxAx8I9rZjBdHgFJQklolXNy HSKNf3u98XZBVVcku/O1hyoeTLnApPfApxD4lv3qlRmgdEnAp6I= =K25T -----END PGP SIGNATURE----- Merge tag 'for-6.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: - fix backward leaf iteration which could possibly return the same key - fix assertion when device add and balance race for exclusive operation - fix regression when freeing device, state tree would leak after device replace - fix attempt to clear space cache v1 when block-group-tree is enabled - fix potential i_size corruption when encoded write races with send v2 and enabled no-holes (the race is hard to hit though, the window is a few instructions wide) - fix wrong bitmap API use when checking empty zones, parameters were swapped but not causing a bug due to other code - prevent potential qgroup leak if subvolume create does not commit transaction (which is pending in the development queue) - error handling and reporting: - abort transaction when sibling keys check fails for leaves - print extent buffers when sibling keys check fails * tag 'for-6.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: don't free qgroup space unless specified btrfs: fix encoded write i_size corruption with no-holes btrfs: zoned: fix wrong use of bitops API in btrfs_ensure_empty_zones btrfs: properly reject clear_cache and v1 cache for block-group-tree btrfs: print extent buffers when sibling keys check fails btrfs: abort transaction when sibling keys check fails for leaves btrfs: fix leak of source device allocation state after device replace btrfs: fix assertion of exclop condition when starting balance btrfs: fix btrfs_prev_leaf() to not return the same key twice
This commit is contained in:
Коммит
1dc3731daf
|
@ -124,7 +124,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
|
|||
} else {
|
||||
num_bytes = 0;
|
||||
}
|
||||
if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
|
||||
if (qgroup_to_release_ret &&
|
||||
block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
|
||||
qgroup_to_release = block_rsv->qgroup_rsv_reserved -
|
||||
block_rsv->qgroup_rsv_size;
|
||||
block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
|
||||
|
|
|
@ -2627,6 +2627,10 @@ static bool check_sibling_keys(struct extent_buffer *left,
|
|||
}
|
||||
|
||||
if (btrfs_comp_cpu_keys(&left_last, &right_first) >= 0) {
|
||||
btrfs_crit(left->fs_info, "left extent buffer:");
|
||||
btrfs_print_tree(left, false);
|
||||
btrfs_crit(left->fs_info, "right extent buffer:");
|
||||
btrfs_print_tree(right, false);
|
||||
btrfs_crit(left->fs_info,
|
||||
"bad key order, sibling blocks, left last (%llu %u %llu) right first (%llu %u %llu)",
|
||||
left_last.objectid, left_last.type,
|
||||
|
@ -3215,6 +3219,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|||
|
||||
if (check_sibling_keys(left, right)) {
|
||||
ret = -EUCLEAN;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_tree_unlock(right);
|
||||
free_extent_buffer(right);
|
||||
return ret;
|
||||
|
@ -3433,6 +3438,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|||
|
||||
if (check_sibling_keys(left, right)) {
|
||||
ret = -EUCLEAN;
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
}
|
||||
return __push_leaf_left(trans, path, min_data_size, empty, left,
|
||||
|
@ -4478,10 +4484,12 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|||
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
|
||||
{
|
||||
struct btrfs_key key;
|
||||
struct btrfs_key orig_key;
|
||||
struct btrfs_disk_key found_key;
|
||||
int ret;
|
||||
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &key, 0);
|
||||
orig_key = key;
|
||||
|
||||
if (key.offset > 0) {
|
||||
key.offset--;
|
||||
|
@ -4498,8 +4506,36 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
|
|||
|
||||
btrfs_release_path(path);
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0)
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Previous key not found. Even if we were at slot 0 of the leaf we had
|
||||
* before releasing the path and calling btrfs_search_slot(), we now may
|
||||
* be in a slot pointing to the same original key - this can happen if
|
||||
* after we released the path, one of more items were moved from a
|
||||
* sibling leaf into the front of the leaf we had due to an insertion
|
||||
* (see push_leaf_right()).
|
||||
* If we hit this case and our slot is > 0 and just decrement the slot
|
||||
* so that the caller does not process the same key again, which may or
|
||||
* may not break the caller, depending on its logic.
|
||||
*/
|
||||
if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
|
||||
btrfs_item_key(path->nodes[0], &found_key, path->slots[0]);
|
||||
ret = comp_keys(&found_key, &orig_key);
|
||||
if (ret == 0) {
|
||||
if (path->slots[0] > 0) {
|
||||
path->slots[0]--;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* At slot 0, same key as before, it means orig_key is
|
||||
* the lowest, leftmost, key in the tree. We're done.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
btrfs_item_key(path->nodes[0], &found_key, 0);
|
||||
ret = comp_keys(&found_key, &key);
|
||||
/*
|
||||
|
|
|
@ -52,13 +52,13 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
|
|||
u64 start, end, i_size;
|
||||
int ret;
|
||||
|
||||
spin_lock(&inode->lock);
|
||||
i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
|
||||
if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
|
||||
inode->disk_i_size = i_size;
|
||||
return;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
spin_lock(&inode->lock);
|
||||
ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
|
||||
&end, EXTENT_DIRTY);
|
||||
if (!ret && start == 0)
|
||||
|
@ -66,6 +66,7 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
|
|||
else
|
||||
i_size = 0;
|
||||
inode->disk_i_size = i_size;
|
||||
out_unlock:
|
||||
spin_unlock(&inode->lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -454,7 +454,9 @@ void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
|
|||
case BTRFS_EXCLOP_BALANCE_PAUSED:
|
||||
spin_lock(&fs_info->super_lock);
|
||||
ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
|
||||
fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD);
|
||||
fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD ||
|
||||
fs_info->exclusive_operation == BTRFS_EXCLOP_NONE ||
|
||||
fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
|
||||
fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED;
|
||||
spin_unlock(&fs_info->super_lock);
|
||||
break;
|
||||
|
|
|
@ -826,7 +826,12 @@ out:
|
|||
!btrfs_test_opt(info, CLEAR_CACHE)) {
|
||||
btrfs_err(info, "cannot disable free space tree");
|
||||
ret = -EINVAL;
|
||||
|
||||
}
|
||||
if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) &&
|
||||
(btrfs_test_opt(info, CLEAR_CACHE) ||
|
||||
!btrfs_test_opt(info, FREE_SPACE_TREE))) {
|
||||
btrfs_err(info, "cannot disable free space tree with block-group-tree feature");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!ret)
|
||||
ret = btrfs_check_mountopts_zoned(info);
|
||||
|
|
|
@ -395,6 +395,7 @@ void btrfs_free_device(struct btrfs_device *device)
|
|||
{
|
||||
WARN_ON(!list_empty(&device->post_commit_list));
|
||||
rcu_string_free(device->name);
|
||||
extent_io_tree_release(&device->alloc_state);
|
||||
btrfs_destroy_dev_zone_info(device);
|
||||
kfree(device);
|
||||
}
|
||||
|
|
|
@ -1168,12 +1168,12 @@ int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size)
|
|||
return -ERANGE;
|
||||
|
||||
/* All the zones are conventional */
|
||||
if (find_next_bit(zinfo->seq_zones, begin, end) == end)
|
||||
if (find_next_bit(zinfo->seq_zones, end, begin) == end)
|
||||
return 0;
|
||||
|
||||
/* All the zones are sequential and empty */
|
||||
if (find_next_zero_bit(zinfo->seq_zones, begin, end) == end &&
|
||||
find_next_zero_bit(zinfo->empty_zones, begin, end) == end)
|
||||
if (find_next_zero_bit(zinfo->seq_zones, end, begin) == end &&
|
||||
find_next_zero_bit(zinfo->empty_zones, end, begin) == end)
|
||||
return 0;
|
||||
|
||||
for (pos = start; pos < start + size; pos += zinfo->zone_size) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче