Re: [PATCH 5/5] btrfs: ctree: Checking key orders before merged tree blocks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2019/7/10 下午7:19, Nikolay Borisov wrote:
>
>
[...]
>> +static int check_cross_tree_key_order(struct extent_buffer *left,
>> +				      struct extent_buffer *right)
>> +{
>> +	struct btrfs_key left_last;
>> +	struct btrfs_key right_first;
>> +	int level = btrfs_header_level(left);
>> +	int nr_left = btrfs_header_nritems(left);
>> +	int nr_right = btrfs_header_nritems(right);
>> +
>> +	/* No key to check in one of the tree blocks */
>> +	if (!nr_left || !nr_right)
>> +		return 0;
>> +	if (level) {
>> +		btrfs_node_key_to_cpu(left, &left_last, nr_left - 1);
>> +		btrfs_node_key_to_cpu(right, &right_first, 0);
>> +	} else {
>> +		btrfs_item_key_to_cpu(left, &left_last, nr_left - 1);
>> +		btrfs_item_key_to_cpu(right, &right_first, 0);
>> +	}
>> +	if (btrfs_comp_cpu_keys(&left_last, &right_first) >= 0) {
>> +		btrfs_crit(left->fs_info,
>> +"bad key order cross tree blocks, left last (%llu %u %llu) right first (%llu %u %llu",
>> +			   left_last.objectid, left_last.type,
>> +			   left_last.offset, right_first.objectid,
>> +			   right_first.type, right_first.offset);
>> +		return -EUCLEAN;
>> +	}
>> +	return 0;
>> +}
>> +
>
> nit: I wonder if it will make it a bit easier to reason about the code
> if that function is renamed to valid_cross_block_key_order and make it
> return true or false, then it's callers will do if
> (!valid_cross_block_key_ordered) {
> return -EUCLEAN
> }

I'm always uncertain what's the correct schema for check function.

Sometimes we have bool check_whatever() sometimes we have bool
is_whatever(), and sometimes we have int check_whatever().

If we have a good guidance for btrfs, it will be a no-brain choice.

>
> I guess it won't be much different than it is now.
>
>>  /*
>>   * try to push data from one node into the next node left in the
>>   * tree.
>> @@ -3263,6 +3309,10 @@ static int push_node_left(struct btrfs_trans_handle *trans,
>>  	} else
>>  		push_items = min(src_nritems - 8, push_items);
>>
>> +	/* dst is the left eb src is the middle eb */
> nit: missing ',' between 'eb' and 'src'. But this is very minor.

I'd prefer the rename the parameter of push_node_left() directly in
another patch so that we won't need this comment at all.

@dst @src?! That makes no sense compared to @left and @right.

Thanks,
Qu

>
>
>> +	ret = check_cross_tree_key_order(dst, src);
>> +	if (ret < 0)
>> +		return ret;
>>  	ret = tree_mod_log_eb_copy(dst, src, dst_nritems, 0, push_items);
>>  	if (ret) {
>>  		btrfs_abort_transaction(trans, ret);
>> @@ -3331,6 +3381,10 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
>>  	if (max_push < push_items)
>>  		push_items = max_push;
>>
>> +	/* dst is the right eb, src is the middle eb */
>> +	ret = check_cross_tree_key_order(src, dst);
>> +	if (ret < 0)
>> +		return ret;
>>  	ret = tree_mod_log_insert_move(dst, push_items, 0, dst_nritems);
>>  	BUG_ON(ret < 0);
>>  	memmove_extent_buffer(dst, btrfs_node_key_ptr_offset(push_items),
>> @@ -3810,6 +3864,12 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
>>  	if (left_nritems == 0)
>>  		goto out_unlock;
>>
>> +	ret = check_cross_tree_key_order(left, right);
>> +	if (ret < 0) {
>> +		btrfs_tree_unlock(right);
>> +		free_extent_buffer(right);
>> +		return ret;
>> +	}
>>  	if (path->slots[0] == left_nritems && !empty) {
>>  		/* Key greater than all keys in the leaf, right neighbor has
>>  		 * enough room for it and we're not emptying our leaf to delete
>> @@ -4048,6 +4108,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
>>  		goto out;
>>  	}
>>
>> +	ret = check_cross_tree_key_order(left, right);
>> +	if (ret < 0)
>> +		goto out;
>>  	return __push_leaf_left(path, min_data_size,
>>  			       empty, left, free_space, right_nritems,
>>  			       max_slot);
>>




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux