Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 1dc3731

Browse files
committed
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
2 parents ba0ad6e + d246331 commit 1dc3731

File tree

7 files changed

+55
-9
lines changed

7 files changed

+55
-9
lines changed

fs/btrfs/block-rsv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
124124
} else {
125125
num_bytes = 0;
126126
}
127-
if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
127+
if (qgroup_to_release_ret &&
128+
block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
128129
qgroup_to_release = block_rsv->qgroup_rsv_reserved -
129130
block_rsv->qgroup_rsv_size;
130131
block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;

fs/btrfs/ctree.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2627,6 +2627,10 @@ static bool check_sibling_keys(struct extent_buffer *left,
26272627
}
26282628

26292629
if (btrfs_comp_cpu_keys(&left_last, &right_first) >= 0) {
2630+
btrfs_crit(left->fs_info, "left extent buffer:");
2631+
btrfs_print_tree(left, false);
2632+
btrfs_crit(left->fs_info, "right extent buffer:");
2633+
btrfs_print_tree(right, false);
26302634
btrfs_crit(left->fs_info,
26312635
"bad key order, sibling blocks, left last (%llu %u %llu) right first (%llu %u %llu)",
26322636
left_last.objectid, left_last.type,
@@ -3215,6 +3219,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
32153219

32163220
if (check_sibling_keys(left, right)) {
32173221
ret = -EUCLEAN;
3222+
btrfs_abort_transaction(trans, ret);
32183223
btrfs_tree_unlock(right);
32193224
free_extent_buffer(right);
32203225
return ret;
@@ -3433,6 +3438,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
34333438

34343439
if (check_sibling_keys(left, right)) {
34353440
ret = -EUCLEAN;
3441+
btrfs_abort_transaction(trans, ret);
34363442
goto out;
34373443
}
34383444
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,
44784484
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
44794485
{
44804486
struct btrfs_key key;
4487+
struct btrfs_key orig_key;
44814488
struct btrfs_disk_key found_key;
44824489
int ret;
44834490

44844491
btrfs_item_key_to_cpu(path->nodes[0], &key, 0);
4492+
orig_key = key;
44854493

44864494
if (key.offset > 0) {
44874495
key.offset--;
@@ -4498,8 +4506,36 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
44984506

44994507
btrfs_release_path(path);
45004508
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
4501-
if (ret < 0)
4509+
if (ret <= 0)
45024510
return ret;
4511+
4512+
/*
4513+
* Previous key not found. Even if we were at slot 0 of the leaf we had
4514+
* before releasing the path and calling btrfs_search_slot(), we now may
4515+
* be in a slot pointing to the same original key - this can happen if
4516+
* after we released the path, one of more items were moved from a
4517+
* sibling leaf into the front of the leaf we had due to an insertion
4518+
* (see push_leaf_right()).
4519+
* If we hit this case and our slot is > 0 and just decrement the slot
4520+
* so that the caller does not process the same key again, which may or
4521+
* may not break the caller, depending on its logic.
4522+
*/
4523+
if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
4524+
btrfs_item_key(path->nodes[0], &found_key, path->slots[0]);
4525+
ret = comp_keys(&found_key, &orig_key);
4526+
if (ret == 0) {
4527+
if (path->slots[0] > 0) {
4528+
path->slots[0]--;
4529+
return 0;
4530+
}
4531+
/*
4532+
* At slot 0, same key as before, it means orig_key is
4533+
* the lowest, leftmost, key in the tree. We're done.
4534+
*/
4535+
return 1;
4536+
}
4537+
}
4538+
45034539
btrfs_item_key(path->nodes[0], &found_key, 0);
45044540
ret = comp_keys(&found_key, &key);
45054541
/*

fs/btrfs/file-item.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,21 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
5252
u64 start, end, i_size;
5353
int ret;
5454

55+
spin_lock(&inode->lock);
5556
i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
5657
if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
5758
inode->disk_i_size = i_size;
58-
return;
59+
goto out_unlock;
5960
}
6061

61-
spin_lock(&inode->lock);
6262
ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
6363
&end, EXTENT_DIRTY);
6464
if (!ret && start == 0)
6565
i_size = min(i_size, end + 1);
6666
else
6767
i_size = 0;
6868
inode->disk_i_size = i_size;
69+
out_unlock:
6970
spin_unlock(&inode->lock);
7071
}
7172

fs/btrfs/ioctl.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,9 @@ void btrfs_exclop_balance(struct btrfs_fs_info *fs_info,
454454
case BTRFS_EXCLOP_BALANCE_PAUSED:
455455
spin_lock(&fs_info->super_lock);
456456
ASSERT(fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
457-
fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD);
457+
fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD ||
458+
fs_info->exclusive_operation == BTRFS_EXCLOP_NONE ||
459+
fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE_PAUSED);
458460
fs_info->exclusive_operation = BTRFS_EXCLOP_BALANCE_PAUSED;
459461
spin_unlock(&fs_info->super_lock);
460462
break;

fs/btrfs/super.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
826826
!btrfs_test_opt(info, CLEAR_CACHE)) {
827827
btrfs_err(info, "cannot disable free space tree");
828828
ret = -EINVAL;
829-
829+
}
830+
if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) &&
831+
(btrfs_test_opt(info, CLEAR_CACHE) ||
832+
!btrfs_test_opt(info, FREE_SPACE_TREE))) {
833+
btrfs_err(info, "cannot disable free space tree with block-group-tree feature");
834+
ret = -EINVAL;
830835
}
831836
if (!ret)
832837
ret = btrfs_check_mountopts_zoned(info);

fs/btrfs/volumes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ void btrfs_free_device(struct btrfs_device *device)
395395
{
396396
WARN_ON(!list_empty(&device->post_commit_list));
397397
rcu_string_free(device->name);
398+
extent_io_tree_release(&device->alloc_state);
398399
btrfs_destroy_dev_zone_info(device);
399400
kfree(device);
400401
}

fs/btrfs/zoned.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,12 +1168,12 @@ int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size)
11681168
return -ERANGE;
11691169

11701170
/* All the zones are conventional */
1171-
if (find_next_bit(zinfo->seq_zones, begin, end) == end)
1171+
if (find_next_bit(zinfo->seq_zones, end, begin) == end)
11721172
return 0;
11731173

11741174
/* All the zones are sequential and empty */
1175-
if (find_next_zero_bit(zinfo->seq_zones, begin, end) == end &&
1176-
find_next_zero_bit(zinfo->empty_zones, begin, end) == end)
1175+
if (find_next_zero_bit(zinfo->seq_zones, end, begin) == end &&
1176+
find_next_zero_bit(zinfo->empty_zones, end, begin) == end)
11771177
return 0;
11781178

11791179
for (pos = start; pos < start + size; pos += zinfo->zone_size) {

0 commit comments

Comments
 (0)