Re: [PATCH v5.1 12/12] btrfs: Do mandatory tree block check before submitting bio

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

 



[snip]
>>
>> Reported-by: Leonard Lausen <leonard@xxxxxxxxx>
>> Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
>> ---
>>  fs/btrfs/disk-io.c      | 10 ++++++++++
>>  fs/btrfs/tree-checker.c | 24 +++++++++++++++++++++---
>>  fs/btrfs/tree-checker.h |  8 ++++++++
>>  3 files changed, 39 insertions(+), 3 deletions(-)
>>
>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
>> index 6052ab508f84..fff789f8db63 100644
>> --- a/fs/btrfs/disk-io.c
>> +++ b/fs/btrfs/disk-io.c
>> @@ -313,6 +313,16 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info,
>>  			return -EUCLEAN;
>>  		}
>>  	} else {
>> +		if (btrfs_header_level(buf))
>> +			err = btrfs_check_node(fs_info, buf);
>> +		else
>> +			err = btrfs_check_leaf_write(fs_info, buf);
>> +		if (err < 0) {
>> +			btrfs_err(fs_info,
>> +			"block=%llu write time tree block corruption detected",
>> +				  buf->start);
>> +			return err;
>> +		}
> 
> This code should be moved in csum_dirty_buffer. Currently there is
> pending cleanups in csum_tree_block and the final if there will be
> removed and respective read/write code factored out in
> csum_dirty_buffer/btree_readpage_end_io_hook.

I have no preference here.
As long as the timing isn't changed, I'm fine either way.

But at least, from my last check on misc-next, there is no conflict at
all. So the pending cleanup isn't so pending right now?

Thanks,
Qu

> 
> Eventually csum_tree_block's sole purpose should be to calculate the
> checksum and nothing more.
> 
>>  		write_extent_buffer(buf, result, 0, csum_size);
>>  	}
>>  
>> diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
>> index a62e1e837a89..b8cdaf472031 100644
>> --- a/fs/btrfs/tree-checker.c
>> +++ b/fs/btrfs/tree-checker.c
>> @@ -477,7 +477,7 @@ static int check_leaf_item(struct btrfs_fs_info *fs_info,
>>  }
>>  
>>  static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf,
>> -		      bool check_item_data)
>> +		      bool check_item_data, bool check_empty_leaf)
>>  {
>>  	/* No valid key type is 0, so all key should be larger than this key */
>>  	struct btrfs_key prev_key = {0, 0, 0};
>> @@ -516,6 +516,18 @@ static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf,
>>  				    owner);
>>  			return -EUCLEAN;
>>  		}
>> +
>> +		/*
>> +		 * Skip empty leaf check, mostly for write time tree block
>> +		 *
>> +		 * Such skip mostly happens for tree block write time, as
>> +		 * we can't use @owner as accurate owner indicator.
>> +		 * Case like balance and new tree block created for commit root
>> +		 * can break owner check easily.
>> +		 */
>> +		if (!check_empty_leaf)
>> +			return 0;
>> +
>>  		key.objectid = owner;
>>  		key.type = BTRFS_ROOT_ITEM_KEY;
>>  		key.offset = (u64)-1;
>> @@ -636,13 +648,19 @@ static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf,
>>  int btrfs_check_leaf_full(struct btrfs_fs_info *fs_info,
>>  			  struct extent_buffer *leaf)
>>  {
>> -	return check_leaf(fs_info, leaf, true);
>> +	return check_leaf(fs_info, leaf, true, true);
>>  }
>>  
>>  int btrfs_check_leaf_relaxed(struct btrfs_fs_info *fs_info,
>>  			     struct extent_buffer *leaf)
>>  {
>> -	return check_leaf(fs_info, leaf, false);
>> +	return check_leaf(fs_info, leaf, false, true);
>> +}
>> +
>> +int btrfs_check_leaf_write(struct btrfs_fs_info *fs_info,
>> +			   struct extent_buffer *leaf)
>> +{
>> +	return check_leaf(fs_info, leaf, false, false);
>>  }
>>  
>>  int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node)
>> diff --git a/fs/btrfs/tree-checker.h b/fs/btrfs/tree-checker.h
>> index ff043275b784..6f8d1b627c53 100644
>> --- a/fs/btrfs/tree-checker.h
>> +++ b/fs/btrfs/tree-checker.h
>> @@ -23,6 +23,14 @@ int btrfs_check_leaf_full(struct btrfs_fs_info *fs_info,
>>   */
>>  int btrfs_check_leaf_relaxed(struct btrfs_fs_info *fs_info,
>>  			     struct extent_buffer *leaf);
>> +
>> +/*
>> + * Write time specific leaf checker.
>> + * Don't check if the empty leaf belongs to a tree root. Mostly for balance
>> + * and new tree created in current transaction.
>> + */
>> +int btrfs_check_leaf_write(struct btrfs_fs_info *fs_info,
>> +			   struct extent_buffer *leaf);
>>  int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node);
>>  
>>  #endif
>>



[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